Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index c42d03509fbb243edd6703d3fe8cf0329b1e7d22..afd4a74ec40419842c694bbba6d09ff4a9abae92 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -4554,7 +4554,6 @@ static bool CanLoadPropertyFromPrototype(Handle<Map> map, |
HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic( |
- Property* expr, |
HValue* object, |
SmallMapList* types, |
Handle<String> name) { |
@@ -4655,15 +4654,15 @@ static bool PrototypeChainCanNeverResolve( |
void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
- Property* expr, |
+ int position, |
+ BailoutId return_id, |
HValue* object, |
SmallMapList* types, |
Handle<String> name) { |
- HInstruction* instr = TryLoadPolymorphicAsMonomorphic( |
- expr, object, types, name); |
+ HInstruction* instr = TryLoadPolymorphicAsMonomorphic(object, types, name); |
if (instr != NULL) { |
- instr->set_position(expr->position()); |
- return ast_context()->ReturnInstruction(instr, expr->id()); |
+ instr->set_position(position); |
+ return ast_context()->ReturnInstruction(instr, return_id); |
} |
// Something did not match; must use a polymorphic load. |
@@ -4695,7 +4694,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
if (lookup.IsField()) { |
HObjectAccess access = HObjectAccess::ForField(map, &lookup, name); |
HLoadNamedField* load = BuildLoadNamedField(compare, access); |
- load->set_position(expr->position()); |
+ load->set_position(position); |
AddInstruction(load); |
if (!ast_context()->IsEffect()) Push(load); |
} else if (lookup.IsConstant()) { |
@@ -4726,22 +4725,23 @@ void HOptimizedGraphBuilder::HandlePolymorphicLoadNamedField( |
if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
FinishExitWithHardDeoptimization("Unknown map in polymorphic load", join); |
} else { |
- HInstruction* load = BuildLoadNamedGeneric(object, name, expr); |
- load->set_position(expr->position()); |
+ HValue* context = environment()->context(); |
+ HInstruction* load = new(zone()) HLoadNamedGeneric(context, object, name); |
+ load->set_position(position); |
AddInstruction(load); |
if (!ast_context()->IsEffect()) Push(load); |
if (join != NULL) { |
current_block()->Goto(join); |
} else { |
- Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
+ Add<HSimulate>(return_id, REMOVABLE_SIMULATE); |
if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
return; |
} |
} |
ASSERT(join != NULL); |
- join->SetJoinId(expr->id()); |
+ join->SetJoinId(return_id); |
set_current_block(join); |
if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
} |
@@ -5130,34 +5130,7 @@ void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
// Named property. |
CHECK_ALIVE(VisitForValue(prop->obj())); |
HValue* object = Top(); |
- |
- Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
- Handle<Map> map; |
- HInstruction* load = NULL; |
- SmallMapList* types = prop->GetReceiverTypes(); |
- bool monomorphic = prop->IsMonomorphic(); |
- if (monomorphic) { |
- map = types->first(); |
- // We can't generate code for a monomorphic dict mode load so |
- // just pretend it is not monomorphic. |
- monomorphic = CanInlinePropertyAccess(*map); |
- } |
- if (monomorphic) { |
- Handle<JSFunction> getter; |
- Handle<JSObject> holder; |
- if (LookupGetter(map, name, &getter, &holder)) { |
- load = BuildCallGetter(object, map, getter, holder); |
- } else { |
- load = BuildLoadNamedMonomorphic(object, name, prop, map); |
- } |
- } 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()) { |
- Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE); |
- } |
+ PushLoad(prop, object, expr->position(), expr->id(), prop->LoadId()); |
CHECK_ALIVE(VisitForValue(expr->value())); |
HValue* right = Pop(); |
@@ -5418,7 +5391,6 @@ HInstruction* HOptimizedGraphBuilder::BuildCallGetter( |
HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
HValue* object, |
Handle<String> name, |
- Property* expr, |
Handle<Map> map) { |
// Handle a load from a known field. |
ASSERT(!map->is_dictionary_map()); |
@@ -5471,7 +5443,8 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic( |
} |
// No luck, do a generic load. |
- return BuildLoadNamedGeneric(object, name, expr); |
+ HValue* context = environment()->context(); |
+ return new(zone()) HLoadNamedGeneric(context, object, name); |
} |
@@ -5858,15 +5831,21 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
} |
-void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
- ASSERT(!HasStackOverflow()); |
- ASSERT(current_block() != NULL); |
- ASSERT(current_block()->HasPredecessor()); |
- |
- if (TryArgumentsAccess(expr)) return; |
+void HOptimizedGraphBuilder::PushLoad(Property* expr, |
+ HValue* object, |
+ int position, |
+ BailoutId ast_id, |
+ BailoutId return_id) { |
+ ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); |
+ Push(object); |
+ BuildLoad(expr, position, ast_id, return_id); |
+} |
- CHECK_ALIVE(VisitForValue(expr->obj())); |
+void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
+ int position, |
+ BailoutId ast_id, |
+ BailoutId return_id) { |
HInstruction* instr = NULL; |
if (expr->IsStringLength()) { |
HValue* string = Pop(); |
@@ -5908,14 +5887,15 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
Handle<JSObject> holder; |
if (LookupGetter(map, name, &getter, &holder)) { |
AddCheckConstantFunction(holder, Top(), map); |
- if (FLAG_inline_accessors && TryInlineGetter(getter, expr)) return; |
+ if (FLAG_inline_accessors && TryInlineGetter(getter, return_id)) return; |
Add<HPushArgument>(Pop()); |
instr = new(zone()) HCallConstantFunction(getter, 1); |
} else { |
- instr = BuildLoadNamedMonomorphic(Pop(), name, expr, map); |
+ instr = BuildLoadNamedMonomorphic(Pop(), name, map); |
} |
} else if (types != NULL && types->length() > 1) { |
- return HandlePolymorphicLoadNamedField(expr, Pop(), types, name); |
+ return HandlePolymorphicLoadNamedField( |
+ position, return_id, Pop(), types, name); |
} else { |
instr = BuildLoadNamedGeneric(Pop(), name, expr); |
} |
@@ -5928,22 +5908,34 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
bool has_side_effects = false; |
HValue* load = HandleKeyedElementAccess( |
- obj, key, NULL, expr, expr->id(), expr->position(), |
+ obj, key, NULL, expr, return_id, position, |
false, // is_store |
&has_side_effects); |
if (has_side_effects) { |
if (ast_context()->IsEffect()) { |
- Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
+ Add<HSimulate>(return_id, REMOVABLE_SIMULATE); |
} else { |
Push(load); |
- Add<HSimulate>(expr->id(), REMOVABLE_SIMULATE); |
+ Add<HSimulate>(return_id, REMOVABLE_SIMULATE); |
Drop(1); |
} |
} |
return ast_context()->ReturnValue(load); |
} |
- instr->set_position(expr->position()); |
- return ast_context()->ReturnInstruction(instr, expr->id()); |
+ instr->set_position(position); |
+ return ast_context()->ReturnInstruction(instr, return_id); |
+} |
+ |
+ |
+void HOptimizedGraphBuilder::VisitProperty(Property* expr) { |
+ ASSERT(!HasStackOverflow()); |
+ ASSERT(current_block() != NULL); |
+ ASSERT(current_block()->HasPredecessor()); |
+ |
+ if (TryArgumentsAccess(expr)) return; |
+ |
+ CHECK_ALIVE(VisitForValue(expr->obj())); |
+ BuildLoad(expr, expr->position(), expr->id(), expr->id()); |
} |
@@ -6620,13 +6612,13 @@ bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
- Property* prop) { |
+ BailoutId return_id) { |
return TryInline(CALL_AS_METHOD, |
getter, |
0, |
NULL, |
- prop->id(), |
- prop->LoadId(), |
+ return_id, |
+ return_id, |
GETTER_CALL_RETURN); |
} |
@@ -7576,32 +7568,7 @@ void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
CHECK_ALIVE(VisitForValue(prop->obj())); |
HValue* object = Top(); |
- |
- Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
- Handle<Map> map; |
- HInstruction* load = NULL; |
- bool monomorphic = prop->IsMonomorphic(); |
- SmallMapList* types = prop->GetReceiverTypes(); |
- if (monomorphic) { |
- map = types->first(); |
- monomorphic = CanInlinePropertyAccess(*map); |
- } |
- if (monomorphic) { |
- Handle<JSFunction> getter; |
- Handle<JSObject> holder; |
- if (LookupGetter(map, name, &getter, &holder)) { |
- load = BuildCallGetter(object, map, getter, holder); |
- } else { |
- load = BuildLoadNamedMonomorphic(object, name, prop, map); |
- } |
- } 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()) { |
- Add<HSimulate>(prop->LoadId(), REMOVABLE_SIMULATE); |
- } |
+ PushLoad(prop, object, expr->position(), expr->id(), prop->LoadId()); |
after = BuildIncrement(returns_original_input, expr); |
HValue* result = returns_original_input ? Pop() : after; |