Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index e49bbb4fa6391104b4b0b49848f647c9e3d2d497..312e30d0261d69c1448e31063f7fd575984103bf 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -4764,12 +4764,18 @@ void HGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { |
property->RecordTypeFeedback(oracle()); |
CHECK_ALIVE(VisitForValue(value)); |
HValue* value = Pop(); |
+ Handle<Map> map = property->GetReceiverType(); |
Handle<String> name = property->key()->AsPropertyName(); |
HInstruction* store; |
- CHECK_ALIVE(store = BuildStoreNamed(literal, |
- name, |
- value, |
- property->GetReceiverType())); |
+ if (map.is_null()) { |
+ // If we don't know the monomorphic type, do a generic store. |
+ CHECK_ALIVE(store = BuildStoreNamedGeneric(literal, name, value)); |
+ } else { |
+ CHECK_ALIVE(store = BuildStoreNamedMonomorphic(literal, |
+ name, |
+ value, |
+ map)); |
+ } |
AddInstruction(store); |
if (store->HasObservableSideEffects()) AddSimulate(key->id()); |
} else { |
@@ -5039,13 +5045,10 @@ HInstruction* HGraphBuilder::BuildCallSetter(HValue* object, |
} |
-HInstruction* HGraphBuilder::BuildStoreNamed(HValue* object, |
- Handle<String> name, |
- HValue* value, |
- Handle<Map> map) { |
- // If we don't know the monomorphic type, do a generic store. |
- if (map.is_null()) return BuildStoreNamedGeneric(object, name, value); |
- |
+HInstruction* HGraphBuilder::BuildStoreNamedMonomorphic(HValue* object, |
+ Handle<String> name, |
+ HValue* value, |
+ Handle<Map> map) { |
// Handle a store to a known field. |
LookupResult lookup(isolate()); |
if (ComputeLoadStoreField(map, name, &lookup, true)) { |
@@ -5233,11 +5236,8 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
SmallMapList* types = expr->GetReceiverTypes(); |
if (expr->IsMonomorphic()) { |
- CHECK_ALIVE(instr = BuildStoreNamed(object, |
- name, |
- value, |
- types->first())); |
- |
+ Handle<Map> map = types->first(); |
+ CHECK_ALIVE(instr = BuildStoreNamedMonomorphic(object, name, value, map)); |
} else if (types != NULL && types->length() > 1) { |
HandlePolymorphicStoreNamedField(expr, object, value, types, name); |
return; |
@@ -5401,7 +5401,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
HInstruction* load; |
if (prop->IsMonomorphic()) { |
map = prop->GetReceiverTypes()->first(); |
- load = BuildLoadNamed(object, name, prop, map); |
+ load = BuildLoadNamedMonomorphic(object, name, prop, map); |
} else { |
load = BuildLoadNamedGeneric(object, name, prop); |
} |
@@ -5417,7 +5417,15 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
if (instr->HasObservableSideEffects()) AddSimulate(operation->id()); |
HInstruction* store; |
- CHECK_ALIVE(store = BuildStoreNamed(object, name, instr, map)); |
+ if (map.is_null()) { |
+ // If we don't know the monomorphic type, do a generic store. |
+ CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, instr)); |
+ } else { |
+ CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, |
+ name, |
+ instr, |
+ map)); |
+ } |
AddInstruction(store); |
// Drop the simulated receiver and value. Return the value. |
Drop(2); |
@@ -5640,7 +5648,7 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
} |
-HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, |
+HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* object, |
Handle<String> name, |
Property* expr) { |
if (expr->IsUninitialized() && !FLAG_always_opt) { |
@@ -5648,7 +5656,7 @@ HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj, |
current_block()->MarkAsDeoptimizing(); |
} |
HValue* context = environment()->LookupContext(); |
- return new(zone()) HLoadNamedGeneric(context, obj, name); |
+ return new(zone()) HLoadNamedGeneric(context, object, name); |
} |
@@ -5663,20 +5671,27 @@ HInstruction* HGraphBuilder::BuildCallGetter(HValue* object, |
} |
-HInstruction* HGraphBuilder::BuildLoadNamed(HValue* object, |
- Handle<String> name, |
- Property* expr, |
- Handle<Map> map) { |
+HInstruction* HGraphBuilder::BuildLoadNamedMonomorphic(HValue* object, |
+ Handle<String> name, |
+ Property* expr, |
+ Handle<Map> map) { |
+ // Handle a load from a known field. |
LookupResult lookup(isolate()); |
map->LookupDescriptor(NULL, *name, &lookup); |
if (lookup.IsField()) { |
return BuildLoadNamedField(object, map, &lookup, true); |
- } else if (lookup.IsConstantFunction()) { |
+ } |
+ |
+ // Handle a load of a constant known function. |
+ if (lookup.IsConstantFunction()) { |
AddInstruction(new(zone()) HCheckNonSmi(object)); |
AddInstruction(HCheckMaps::NewWithTransitions(object, map, zone())); |
Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*map)); |
return new(zone()) HConstant(function, Representation::Tagged()); |
- } else if (lookup.IsPropertyCallbacks()) { |
+ } |
+ |
+ // Handle a known getter directly in the receiver. |
+ if (lookup.IsPropertyCallbacks()) { |
Handle<Object> callback(lookup.GetValueFromMap(*map)); |
Handle<JSObject> holder; |
if (!callback->IsAccessorPair()) { |
@@ -5684,19 +5699,22 @@ HInstruction* HGraphBuilder::BuildLoadNamed(HValue* object, |
} |
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback); |
return BuildCallGetter(object, map, accessors, holder); |
- } else { |
- LookupInPrototypes(map, name, &lookup); |
- if (lookup.IsPropertyCallbacks()) { |
- Handle<Object> callback(lookup.GetValue()); |
+ } |
+ |
+ // Handle a known getter somewhere in the prototype chain. |
+ LookupInPrototypes(map, name, &lookup); |
+ if (lookup.IsPropertyCallbacks()) { |
+ Handle<Object> callback(lookup.GetValue()); |
Handle<JSObject> holder(lookup.holder()); |
if (!callback->IsAccessorPair()) { |
return BuildLoadNamedGeneric(object, name, expr); |
} |
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(callback); |
return BuildCallGetter(object, map, accessors, holder); |
- } |
- return BuildLoadNamedGeneric(object, name, expr); |
} |
+ |
+ // No luck, do a generic load. |
+ return BuildLoadNamedGeneric(object, name, expr); |
} |
@@ -6315,7 +6333,7 @@ void HGraphBuilder::VisitProperty(Property* expr) { |
HValue* obj = Pop(); |
if (expr->IsMonomorphic()) { |
- instr = BuildLoadNamed(obj, name, expr, types->first()); |
+ instr = BuildLoadNamedMonomorphic(obj, name, expr, types->first()); |
} else if (types != NULL && types->length() > 1) { |
AddInstruction(new(zone()) HCheckNonSmi(obj)); |
HandlePolymorphicLoadNamedField(expr, obj, types, name); |
@@ -7798,16 +7816,16 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
if (returns_original_input) Push(graph_->GetConstantUndefined()); |
CHECK_ALIVE(VisitForValue(prop->obj())); |
- HValue* obj = Top(); |
+ HValue* object = Top(); |
Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
Handle<Map> map; |
HInstruction* load; |
if (prop->IsMonomorphic()) { |
map = prop->GetReceiverTypes()->first(); |
- load = BuildLoadNamed(obj, name, prop, map); |
+ load = BuildLoadNamedMonomorphic(object, name, prop, map); |
} else { |
- load = BuildLoadNamedGeneric(obj, name, prop); |
+ load = BuildLoadNamedGeneric(object, name, prop); |
} |
PushAndAdd(load); |
if (load->HasObservableSideEffects()) AddSimulate(expr->CountId()); |
@@ -7816,7 +7834,15 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
input = Pop(); |
HInstruction* store; |
- CHECK_ALIVE(store = BuildStoreNamed(obj, name, after, map)); |
+ if (map.is_null()) { |
+ // If we don't know the monomorphic type, do a generic store. |
+ CHECK_ALIVE(store = BuildStoreNamedGeneric(object, name, after)); |
+ } else { |
+ CHECK_ALIVE(store = BuildStoreNamedMonomorphic(object, |
+ name, |
+ after, |
+ map)); |
+ } |
AddInstruction(store); |
// Overwrite the receiver in the bailout environment with the result |