Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 9c83380492f6158b14d3c181c345980ddb44936d..c8ce91c784f86e526141477a6f37201bc75b334b 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -3871,14 +3871,15 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
| } |
| -// Sets the lookup result and returns true if the store can be inlined. |
| +// Sets the lookup result and returns true if the load/store can be inlined. |
| static bool ComputeStoredField(Handle<Map> type, |
|
danno
2012/03/09 11:52:58
Rename to something like ComputeLoadStoreField
Michael Starzinger
2012/03/12 11:37:11
Done.
|
| Handle<String> name, |
| - LookupResult* lookup) { |
| + LookupResult* lookup, |
| + bool is_store) { |
| type->LookupInDescriptors(NULL, *name, lookup); |
| if (!lookup->IsFound()) return false; |
| if (lookup->type() == FIELD) return true; |
| - return (lookup->type() == MAP_TRANSITION) && |
| + return is_store && (lookup->type() == MAP_TRANSITION) && |
| (type->unused_property_fields() > 0); |
| } |
| @@ -3957,7 +3958,7 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
| LookupResult lookup(isolate()); |
| SmallMapList* types = expr->GetReceiverTypes(); |
| bool is_monomorphic = expr->IsMonomorphic() && |
| - ComputeStoredField(types->first(), name, &lookup); |
| + ComputeStoredField(types->first(), name, &lookup, true); |
| return is_monomorphic |
| ? BuildStoreNamedField(object, name, value, types->first(), &lookup, |
| @@ -3966,6 +3967,47 @@ HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
| } |
| +void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| + HValue* object, |
| + SmallMapList* types, |
| + Handle<String> name) { |
| + int count = 0; |
| + int previous_field_index = 0; |
| + bool is_monomorphic_field = true; |
| + Handle<Map> map; |
| + LookupResult lookup(isolate()); |
| + for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
|
danno
2012/03/09 11:52:58
kMaxStorePolymorphism seems to be inappropriately
Michael Starzinger
2012/03/12 11:37:11
Done. That actually should have been kMaxLoadPolym
|
| + map = types->at(i); |
| + if (ComputeStoredField(map, name, &lookup, false)) { |
| + int index = ComputeStoredFieldIndex(map, name, &lookup); |
| + if (count == 0) { |
| + previous_field_index = index; |
| + } else if (is_monomorphic_field) { |
| + is_monomorphic_field = (index == previous_field_index); |
| + } |
| + ++count; |
| + } |
| + } |
| + |
| + // Use monomorphic load if property lookup results in the same field index |
| + // for all maps. Requires special map check on the set of all handled maps. |
| + HInstruction* instr; |
| + if (count == types->length() && is_monomorphic_field) { |
| + AddInstruction(new(zone()) HCheckMapSet(object, types)); |
| + instr = BuildLoadNamedField(object, expr, map, &lookup, false); |
| + } else { |
| + HValue* context = environment()->LookupContext(); |
| + instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
| + object, |
| + types, |
| + name); |
| + } |
| + |
| + instr->set_position(expr->position()); |
| + return ast_context()->ReturnInstruction(instr, expr->id()); |
| +} |
| + |
| + |
| void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
| HValue* object, |
| HValue* value, |
| @@ -3979,7 +4021,7 @@ void HGraphBuilder::HandlePolymorphicStoreNamedField(Assignment* expr, |
| for (int i = 0; i < types->length() && count < kMaxStorePolymorphism; ++i) { |
| Handle<Map> map = types->at(i); |
| LookupResult lookup(isolate()); |
| - if (ComputeStoredField(map, name, &lookup)) { |
| + if (ComputeStoredField(map, name, &lookup, true)) { |
| if (count == 0) { |
| AddInstruction(new(zone()) HCheckNonSmi(object)); // Only needed once. |
| join = graph()->CreateBasicBlock(); |
| @@ -4953,8 +4995,8 @@ void HGraphBuilder::VisitProperty(Property* expr) { |
| instr = BuildLoadNamed(obj, expr, types->first(), name); |
| } else if (types != NULL && types->length() > 1) { |
| AddInstruction(new(zone()) HCheckNonSmi(obj)); |
| - HValue* context = environment()->LookupContext(); |
| - instr = new(zone()) HLoadNamedFieldPolymorphic(context, obj, types, name); |
| + HandlePolymorphicLoadNamedField(expr, obj, types, name); |
| + return; |
| } else { |
| instr = BuildLoadNamedGeneric(obj, expr); |
| } |