Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 3d0d5505aea05800177fdce62d85f9cafe7dcaef..b252fc70d829e3d2fabdb51f5b9cabf7eb197b44 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -6316,43 +6316,13 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedMonomorphic( |
} |
-bool HOptimizedGraphBuilder::HandlePolymorphicArrayLengthLoad( |
+HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( |
Property* expr, |
HValue* object, |
SmallMapList* types, |
Handle<String> name) { |
- if (!name->Equals(isolate()->heap()->length_string())) return false; |
- |
- for (int i = 0; i < types->length(); i++) { |
- if (types->at(i)->instance_type() != JS_ARRAY_TYPE) return false; |
- } |
- |
- BuildCheckNonSmi(object); |
- |
- HInstruction* typecheck = |
- AddInstruction(HCheckMaps::New(object, types, zone())); |
- HInstruction* instr = new(zone()) |
- HLoadNamedField(object, HObjectAccess::ForArrayLength(), typecheck); |
- |
- instr->set_position(expr->position()); |
- ast_context()->ReturnInstruction(instr, expr->id()); |
- return true; |
-} |
- |
- |
-void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
- HValue* object, |
- SmallMapList* types, |
- Handle<String> name) { |
- |
- if (HandlePolymorphicArrayLengthLoad(expr, object, types, name)) |
- return; |
- |
- BuildCheckNonSmi(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. |
- HInstruction* instr = NULL; |
LookupResult lookup(isolate()); |
int count; |
Representation representation = Representation::None(); |
@@ -6383,12 +6353,25 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, |
} |
} |
- if (count == types->length()) { |
- // Everything matched; can use monomorphic load. |
- AddInstruction(HCheckMaps::New(object, types, zone())); |
- instr = BuildLoadNamedField(object, access, representation); |
- } else { |
+ if (count != types->length()) return NULL; |
+ |
+ // Everything matched; can use monomorphic load. |
+ BuildCheckNonSmi(object); |
+ AddInstruction(HCheckMaps::New(object, types, zone())); |
+ return BuildLoadNamedField(object, access, representation); |
+} |
+ |
+ |
+void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
+ Property* expr, |
+ HValue* object, |
+ SmallMapList* types, |
+ Handle<String> name) { |
+ HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
+ expr, object, types, name); |
+ if (instr == NULL) { |
// Something did not match; must use a polymorphic load. |
+ BuildCheckNonSmi(object); |
HValue* context = environment()->LookupContext(); |
instr = new(zone()) HLoadNamedFieldPolymorphic( |
context, object, types, name, zone()); |
@@ -6683,10 +6666,11 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
Handle<Map> map; |
- HInstruction* load; |
+ HInstruction* load = NULL; |
+ SmallMapList* types = prop->GetReceiverTypes(); |
bool monomorphic = prop->IsMonomorphic(); |
if (monomorphic) { |
- map = prop->GetReceiverTypes()->first(); |
+ map = types->first(); |
// We can't generate code for a monomorphic dict mode load so |
// just pretend it is not monomorphic. |
if (map->is_dictionary_map()) monomorphic = false; |
@@ -6699,9 +6683,10 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
} else { |
load = BuildLoadNamedMonomorphic(object, name, prop, map); |
} |
- } else { |
- load = BuildLoadNamedGeneric(object, name, prop); |
+ } else if (types != NULL && types->length() > 1) { |
+ load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
} |
+ if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
PushAndAdd(load); |
if (load->HasObservableSideEffects()) { |
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
@@ -6967,6 +6952,8 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
Property* expr) { |
if (expr->IsUninitialized()) { |
AddSoftDeoptimize(); |
+ } else { |
+ // OS::DebugBreak(); |
} |
HValue* context = environment()->LookupContext(); |
return new(zone()) HLoadNamedGeneric(context, object, name); |
@@ -9265,10 +9252,11 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
Handle<Map> map; |
- HInstruction* load; |
+ HInstruction* load = NULL; |
bool monomorphic = prop->IsMonomorphic(); |
+ SmallMapList* types = prop->GetReceiverTypes(); |
if (monomorphic) { |
- map = prop->GetReceiverTypes()->first(); |
+ map = types->first(); |
if (map->is_dictionary_map()) monomorphic = false; |
} |
if (monomorphic) { |
@@ -9279,9 +9267,10 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
} else { |
load = BuildLoadNamedMonomorphic(object, name, prop, map); |
} |
- } else { |
- load = BuildLoadNamedGeneric(object, name, prop); |
+ } else if (types != NULL && types->length() > 1) { |
+ load = TryLoadPolymorphicAsMonomorphic(prop, object, types, name); |
} |
+ if (load == NULL) load = BuildLoadNamedGeneric(object, name, prop); |
PushAndAdd(load); |
if (load->HasObservableSideEffects()) { |
AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |