Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 58a9b78750bb7401bfdc9e167800f8f01d3ef078..637f1d03df17bc7fe59241c68e5b7eacd746d29c 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -7131,22 +7131,30 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| HValue* object, |
| SmallMapList* types, |
| Handle<String> name) { |
| - int count = 0; |
| - int previous_field_offset = 0; |
| - bool previous_field_is_in_object = false; |
| - bool is_monomorphic_field = true; |
| if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) |
| return; |
| - Handle<Map> map; |
| - LookupResult lookup(isolate()); |
| - for (int i = 0; i < types->length() && count < kMaxLoadPolymorphism; ++i) { |
| - map = types->at(i); |
| - if (ComputeLoadStoreField(map, name, &lookup, false)) { |
| + AddInstruction(new(zone()) HCheckNonSmi(object)); |
| + |
| + // 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. |
| + if (types->length() > 0 && types->length() <= kMaxLoadPolymorphism) { |
|
mvstanton
2013/05/07 10:17:17
I like this if check against kMaxLoadPolymorphism,
Toon Verwaest
2013/05/07 10:30:24
Done.
|
| + LookupResult lookup(isolate()); |
| + int previous_field_offset = 0; |
| + bool previous_field_is_in_object = false; |
| + Representation representation = Representation::None(); |
| + int count; |
| + for (count = 0; count < types->length(); ++count) { |
| + Handle<Map> map = types->at(count); |
| + if (!ComputeLoadStoreField(map, name, &lookup, false)) break; |
| + |
| int index = ComputeLoadStoreFieldIndex(map, &lookup); |
| + Representation new_representation = |
| + ComputeLoadStoreRepresentation(map, &lookup); |
| bool is_in_object = index < 0; |
| int offset = index * kPointerSize; |
| + |
| if (index < 0) { |
| // Negative property indices are in-object properties, indexed |
| // from the end of the fixed part of the object. |
| @@ -7154,33 +7162,34 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
| } else { |
| offset += FixedArray::kHeaderSize; |
| } |
| + |
| if (count == 0) { |
| previous_field_offset = offset; |
| previous_field_is_in_object = is_in_object; |
| - } else if (is_monomorphic_field) { |
| - is_monomorphic_field = (offset == previous_field_offset) && |
| - (is_in_object == previous_field_is_in_object); |
| + representation = new_representation; |
| + } else if (offset != previous_field_offset || |
| + is_in_object != previous_field_is_in_object || |
| + (FLAG_track_fields && |
| + !representation.IsCompatibleForLoad(new_representation))) { |
| + break; |
| } |
| - ++count; |
| + |
| + representation = representation.generalize(new_representation); |
| } |
| - } |
| - // 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. |
| - AddInstruction(new(zone()) HCheckNonSmi(object)); |
| - HInstruction* instr; |
| - if (count == types->length() && is_monomorphic_field) { |
| - AddInstruction(HCheckMaps::New(object, types, zone())); |
| - instr = BuildLoadNamedField(object, map, &lookup); |
| - } else { |
| - HValue* context = environment()->LookupContext(); |
| - instr = new(zone()) HLoadNamedFieldPolymorphic(context, |
| - object, |
| - types, |
| - name, |
| - zone()); |
| + if (count == types->length()) { |
| + AddInstruction(HCheckMaps::New(object, types, zone())); |
| + HInstruction* instr = DoBuildLoadNamedField( |
| + object, previous_field_is_in_object, |
| + representation, previous_field_offset); |
| + instr->set_position(expr->position()); |
|
mvstanton
2013/05/07 10:17:17
the instr->set_position() line and ast_context() l
Toon Verwaest
2013/05/07 10:30:24
Done.
|
| + return ast_context()->ReturnInstruction(instr, expr->id()); |
| + } |
| } |
| + HValue* context = environment()->LookupContext(); |
| + HInstruction* instr = new(zone()) HLoadNamedFieldPolymorphic( |
| + context, object, types, name, zone()); |
| instr->set_position(expr->position()); |
| return ast_context()->ReturnInstruction(instr, expr->id()); |
| } |
| @@ -7735,18 +7744,25 @@ HLoadNamedField* HOptimizedGraphBuilder::BuildLoadNamedField( |
| HValue* object, |
| Handle<Map> map, |
| LookupResult* lookup) { |
| - Representation representation = lookup->representation(); |
| int index = lookup->GetLocalFieldIndexFromMap(*map); |
| - if (index < 0) { |
| - // Negative property indices are in-object properties, indexed |
| - // from the end of the fixed part of the object. |
| - int offset = (index * kPointerSize) + map->instance_size(); |
| - return new(zone()) HLoadNamedField(object, true, representation, offset); |
| - } else { |
| - // Non-negative property indices are in the properties array. |
| - int offset = (index * kPointerSize) + FixedArray::kHeaderSize; |
| - return new(zone()) HLoadNamedField(object, false, representation, offset); |
| - } |
| + // Negative property indices are in-object properties, indexed from the end of |
| + // the fixed part of the object. Non-negative property indices are in the |
| + // properties array. |
| + int inobject = index < 0; |
| + Representation representation = lookup->representation(); |
| + int offset = inobject |
| + ? index * kPointerSize + map->instance_size() |
| + : index * kPointerSize + FixedArray::kHeaderSize; |
| + return DoBuildLoadNamedField(object, inobject, representation, offset); |
| +} |
| + |
| + |
| +HLoadNamedField* HGraphBuilder::DoBuildLoadNamedField( |
| + HValue* object, |
| + bool inobject, |
| + Representation representation, |
| + int offset) { |
| + return new(zone()) HLoadNamedField(object, inobject, representation, offset); |
| } |