Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 153bd9aae9cb02a5121a45ce991363a50f109f94..bc49f06a20baf0980a6c5b1a62d90dda1742448d 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -3299,7 +3299,7 @@ void HGraphBuilder::HandlePropertyAssignment(Assignment* expr) { |
Push(value); |
instr->set_position(expr->position()); |
AddInstruction(instr); |
- if (instr->HasSideEffects()) AddSimulate(expr->id()); |
+ if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
ast_context()->ReturnValue(Pop()); |
} |
@@ -3344,7 +3344,10 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
VISIT_FOR_VALUE(operation); |
if (var->is_global()) { |
- HandleGlobalVariableAssignment(var, Top(), expr->position(), expr->id()); |
+ HandleGlobalVariableAssignment(var, |
+ Top(), |
+ expr->position(), |
+ expr->AssignmentId()); |
} else { |
Bind(var, Top()); |
} |
@@ -3367,7 +3370,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
load = BuildLoadNamedGeneric(obj, prop); |
} |
PushAndAdd(load); |
- if (load->HasSideEffects()) AddSimulate(expr->compound_bailout_id()); |
+ if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
VISIT_FOR_VALUE(expr->value()); |
HValue* right = Pop(); |
@@ -3379,11 +3382,11 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
HInstruction* store = BuildStoreNamed(obj, instr, prop); |
AddInstruction(store); |
- if (store->HasSideEffects()) AddSimulate(expr->id()); |
- |
// Drop the simulated receiver and value. Return the value. |
Drop(2); |
- ast_context()->ReturnValue(instr); |
+ Push(instr); |
+ if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
+ ast_context()->ReturnValue(Pop()); |
} else { |
// Keyed property. |
@@ -3399,7 +3402,7 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
? BuildLoadKeyedFastElement(obj, key, prop) |
: BuildLoadKeyedGeneric(obj, key); |
PushAndAdd(load); |
- if (load->HasSideEffects()) AddSimulate(expr->compound_bailout_id()); |
+ if (load->HasSideEffects()) AddSimulate(expr->CompoundLoadId()); |
VISIT_FOR_VALUE(expr->value()); |
HValue* right = Pop(); |
@@ -3413,11 +3416,11 @@ void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { |
? BuildStoreKeyedFastElement(obj, key, instr, prop) |
: BuildStoreKeyedGeneric(obj, key, instr); |
AddInstruction(store); |
- if (store->HasSideEffects()) AddSimulate(expr->id()); |
- |
// Drop the simulated receiver, key, and value. Return the value. |
Drop(3); |
- ast_context()->ReturnValue(instr); |
+ Push(instr); |
+ if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
+ ast_context()->ReturnValue(Pop()); |
} |
} else { |
@@ -3443,7 +3446,10 @@ void HGraphBuilder::VisitAssignment(Assignment* expr) { |
// Handle the assignment. |
if (var->is_global()) { |
VISIT_FOR_VALUE(expr->value()); |
- HandleGlobalVariableAssignment(var, Top(), expr->position(), expr->id()); |
+ HandleGlobalVariableAssignment(var, |
+ Top(), |
+ expr->position(), |
+ expr->AssignmentId()); |
} else { |
// We allow reference to the arguments object only in assignemtns |
// to local variables to make sure that the arguments object does |
@@ -4536,7 +4542,10 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
} |
if (var->is_global()) { |
- HandleGlobalVariableAssignment(var, instr, expr->position(), expr->id()); |
+ HandleGlobalVariableAssignment(var, |
+ instr, |
+ expr->position(), |
+ expr->AssignmentId()); |
} else { |
ASSERT(var->IsStackAllocated()); |
Bind(var, instr); |
@@ -4551,9 +4560,8 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
// Match the full code generator stack by simulating an extra stack |
// element for postfix operations in a value context. |
- if (expr->is_postfix() && !ast_context()->IsEffect()) { |
- Push(graph_->GetConstantUndefined()); |
- } |
+ bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
+ if (has_extra) Push(graph_->GetConstantUndefined()); |
VISIT_FOR_VALUE(prop->obj()); |
HValue* obj = Top(); |
@@ -4569,40 +4577,35 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
PushAndAdd(load); |
if (load->HasSideEffects()) AddSimulate(increment->id()); |
- HValue* value = Pop(); |
- |
+ HValue* before = Pop(); |
// There is no deoptimization to after the increment, so we don't need |
// to simulate the expression stack after this instruction. |
- HInstruction* instr = BuildIncrement(value, inc); |
- AddInstruction(instr); |
+ HInstruction* after = BuildIncrement(before, inc); |
+ AddInstruction(after); |
- HInstruction* store = BuildStoreNamed(obj, instr, prop); |
+ HInstruction* store = BuildStoreNamed(obj, after, prop); |
AddInstruction(store); |
- // Drop simulated receiver and push the result. |
- Drop(1); |
- if (expr->is_prefix()) { |
- Push(instr); |
- } else { |
- if (!ast_context()->IsEffect()) Drop(1); // Drop simulated zero. |
- Push(value); |
- } |
+ // Overwrite the receiver in the bailout environment with the result |
+ // of the operation, and the placeholder with the original value if |
+ // necessary. |
+ environment()->SetExpressionStackAt(0, after); |
+ if (has_extra) environment()->SetExpressionStackAt(1, before); |
+ if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
+ Drop(has_extra ? 2 : 1); |
- if (store->HasSideEffects()) AddSimulate(expr->id()); |
- ast_context()->ReturnValue(Pop()); |
+ ast_context()->ReturnValue(expr->is_postfix() ? before : after); |
} else { |
// Keyed property. |
// Match the full code generator stack by simulate an extra stack element |
// for postfix operations in a value context. |
- if (expr->is_postfix() && !ast_context()->IsEffect()) { |
- Push(graph_->GetConstantUndefined()); |
- } |
+ bool has_extra = expr->is_postfix() && !ast_context()->IsEffect(); |
+ if (has_extra) Push(graph_->GetConstantUndefined()); |
VISIT_FOR_VALUE(prop->obj()); |
VISIT_FOR_VALUE(prop->key()); |
- |
HValue* obj = environment()->ExpressionStackAt(1); |
HValue* key = environment()->ExpressionStackAt(0); |
@@ -4615,29 +4618,27 @@ void HGraphBuilder::VisitCountOperation(CountOperation* expr) { |
PushAndAdd(load); |
if (load->HasSideEffects()) AddSimulate(increment->id()); |
- HValue* value = Pop(); |
- |
+ HValue* before = Pop(); |
// There is no deoptimization to after the increment, so we don't need |
// to simulate the expression stack after this instruction. |
- HInstruction* instr = BuildIncrement(value, inc); |
- AddInstruction(instr); |
+ HInstruction* after = BuildIncrement(before, inc); |
+ AddInstruction(after); |
HInstruction* store = is_fast_elements |
- ? BuildStoreKeyedFastElement(obj, key, instr, prop) |
- : new HStoreKeyedGeneric(obj, key, instr); |
+ ? BuildStoreKeyedFastElement(obj, key, after, prop) |
+ : new HStoreKeyedGeneric(obj, key, after); |
AddInstruction(store); |
- // Drop simulated receiver and key and push the result. |
- Drop(2); |
- if (expr->is_prefix()) { |
- Push(instr); |
- } else { |
- if (!ast_context()->IsEffect()) Drop(1); // Drop simulated zero. |
- Push(value); |
- } |
+ // Drop the key from the bailout environment. Overwrite the receiver |
+ // with the result of the operation, and the placeholder with the |
+ // original value if necessary. |
+ Drop(1); |
+ environment()->SetExpressionStackAt(0, after); |
+ if (has_extra) environment()->SetExpressionStackAt(1, before); |
+ if (store->HasSideEffects()) AddSimulate(expr->AssignmentId()); |
+ Drop(has_extra ? 2 : 1); |
- if (store->HasSideEffects()) AddSimulate(expr->id()); |
- ast_context()->ReturnValue(Pop()); |
+ ast_context()->ReturnValue(expr->is_postfix() ? before : after); |
} |
} else { |