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 |