| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 7200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7211 return ast_context()->ReturnInstruction(instr, expr->id()); | 7211 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 7212 } | 7212 } |
| 7213 | 7213 |
| 7214 | 7214 |
| 7215 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( | 7215 void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField( |
| 7216 Assignment* expr, | 7216 Assignment* expr, |
| 7217 HValue* object, | 7217 HValue* object, |
| 7218 HValue* value, | 7218 HValue* value, |
| 7219 SmallMapList* types, | 7219 SmallMapList* types, |
| 7220 Handle<String> name) { | 7220 Handle<String> name) { |
| 7221 // Use monomorphic store if property lookup results in the same field index | |
| 7222 // and compatible representation for all maps. Requires special map check on | |
| 7223 // the set of all handled maps. | |
| 7224 if (types->length() <= kMaxStorePolymorphism) { | |
| 7225 int previous_field_offset = 0; | |
| 7226 bool previous_field_is_in_object = false; | |
| 7227 Representation previous_representation = Representation::None(); | |
| 7228 | |
| 7229 Handle<Map> map; | |
| 7230 LookupResult lookup(isolate()); | |
| 7231 int count; | |
| 7232 for (count = 0; count < types->length(); ++count) { | |
| 7233 map = types->at(count); | |
| 7234 if (!ComputeLoadStoreField(map, name, &lookup, false) || | |
| 7235 lookup.IsTransition()) { | |
| 7236 break; | |
| 7237 } | |
| 7238 Representation representation = lookup.representation(); | |
| 7239 int index = ComputeLoadStoreFieldIndex(map, &lookup); | |
| 7240 bool is_in_object = index < 0; | |
| 7241 int offset = index * kPointerSize; | |
| 7242 if (index < 0) { | |
| 7243 offset += map->instance_size(); | |
| 7244 } else { | |
| 7245 offset += FixedArray::kHeaderSize; | |
| 7246 } | |
| 7247 if (count == 0) { | |
| 7248 previous_field_offset = offset; | |
| 7249 previous_field_is_in_object = is_in_object; | |
| 7250 previous_representation = representation; | |
| 7251 } else if (offset != previous_field_offset || | |
| 7252 is_in_object != previous_field_is_in_object || | |
| 7253 !representation.IsCompatibleForStore( | |
| 7254 previous_representation)) { | |
| 7255 break; | |
| 7256 } | |
| 7257 } | |
| 7258 | |
| 7259 if (types->length() == count) { | |
| 7260 AddInstruction(new(zone()) HCheckNonSmi(object)); | |
| 7261 AddInstruction(HCheckMaps::New(object, types, zone())); | |
| 7262 HInstruction* instr = BuildStoreNamedField( | |
| 7263 object, name, value, map, &lookup); | |
| 7264 AddInstruction(instr); | |
| 7265 instr->set_position(expr->position()); | |
| 7266 // The HSimulate for the store should not see the stored value in | |
| 7267 // effect contexts (it is not materialized at expr->id() in the | |
| 7268 // unoptimized code). | |
| 7269 if (instr->HasObservableSideEffects()) { | |
| 7270 if (ast_context()->IsEffect()) { | |
| 7271 AddSimulate(expr->id(), REMOVABLE_SIMULATE); | |
| 7272 } else { | |
| 7273 Push(value); | |
| 7274 AddSimulate(expr->id(), REMOVABLE_SIMULATE); | |
| 7275 Drop(1); | |
| 7276 } | |
| 7277 } | |
| 7278 return ast_context()->ReturnValue(value); | |
| 7279 } | |
| 7280 } | |
| 7281 | |
| 7282 // TODO(ager): We should recognize when the prototype chains for different | 7221 // TODO(ager): We should recognize when the prototype chains for different |
| 7283 // maps are identical. In that case we can avoid repeatedly generating the | 7222 // maps are identical. In that case we can avoid repeatedly generating the |
| 7284 // same prototype map checks. | 7223 // same prototype map checks. |
| 7285 int count = 0; | 7224 int count = 0; |
| 7286 HBasicBlock* join = NULL; | 7225 HBasicBlock* join = NULL; |
| 7287 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { | 7226 for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
| 7288 Handle<Map> map = types->at(i); | 7227 Handle<Map> map = types->at(i); |
| 7289 LookupResult lookup(isolate()); | 7228 LookupResult lookup(isolate()); |
| 7290 if (ComputeLoadStoreField(map, name, &lookup, true)) { | 7229 if (ComputeLoadStoreField(map, name, &lookup, true)) { |
| 7291 if (count == 0) { | 7230 if (count == 0) { |
| (...skipping 5073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12365 } | 12304 } |
| 12366 } | 12305 } |
| 12367 | 12306 |
| 12368 #ifdef DEBUG | 12307 #ifdef DEBUG |
| 12369 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 12308 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 12370 if (allocator_ != NULL) allocator_->Verify(); | 12309 if (allocator_ != NULL) allocator_->Verify(); |
| 12371 #endif | 12310 #endif |
| 12372 } | 12311 } |
| 12373 | 12312 |
| 12374 } } // namespace v8::internal | 12313 } } // namespace v8::internal |
| OLD | NEW |