Index: src/ia32/codegen-ia32.cc |
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc |
index 9fe67587abd1ba3688a5490f2c75560af5c0a2e2..48c93c9b6e5b756f82be75b71e3a72d5f98cc87a 100644 |
--- a/src/ia32/codegen-ia32.cc |
+++ b/src/ia32/codegen-ia32.cc |
@@ -574,7 +574,9 @@ void CodeGenerator::LoadTypeofExpression(Expression* expr) { |
} else if (variable != NULL && variable->slot() != NULL) { |
// For a variable that rewrites to a slot, we signal it is the immediate |
// subexpression of a typeof. |
- LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); |
+ Result result = |
+ LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); |
+ frame()->Push(&result); |
} else { |
// Anything else can be handled normally. |
Load(expr); |
@@ -623,8 +625,7 @@ Result CodeGenerator::StoreArgumentsObject(bool initial) { |
// We have to skip storing into the arguments slot if it has already |
// been written to. This can happen if the a function has a local |
// variable named 'arguments'. |
- LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); |
- Result probe = frame_->Pop(); |
+ Result probe = LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); |
if (probe.is_constant()) { |
// We have to skip updating the arguments object if it has |
// been assigned a proper value. |
@@ -2337,7 +2338,9 @@ void CodeGenerator::CallApplyLazy(Expression* applicand, |
// Load the receiver and the existing arguments object onto the |
// expression stack. Avoid allocating the arguments object here. |
Load(receiver); |
- LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
+ Result existing_args = |
+ LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); |
+ frame()->Push(&existing_args); |
// Emit the source position information after having loaded the |
// receiver and the arguments. |
@@ -3990,13 +3993,12 @@ void CodeGenerator::VisitConditional(Conditional* node) { |
} |
-void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
+Result CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
+ Result result; |
fschneider
2010/02/12 12:23:06
I'd move the declaration into the innermost necess
Kevin Millikin (Chromium)
2010/02/12 12:39:21
Ultimately it will be a field in the codegen state
|
if (slot->type() == Slot::LOOKUP) { |
ASSERT(slot->var()->is_dynamic()); |
fschneider
2010/02/12 12:23:06
Declare result here instead.
|
- |
JumpTarget slow; |
JumpTarget done; |
- Result value; |
// Generate fast-case code for variables that might be shadowed by |
// eval-introduced variables. Eval is used a lot without |
@@ -4004,14 +4006,10 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
// perform a runtime call for all variables in the scope |
// containing the eval. |
if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { |
- value = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow); |
+ result = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow); |
// If there was no control flow to slow, we can exit early. |
- if (!slow.is_linked()) { |
- frame_->Push(&value); |
- return; |
- } |
- |
- done.Jump(&value); |
+ if (!slow.is_linked()) return result; |
+ done.Jump(&result); |
} else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { |
Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); |
fschneider
2010/02/12 12:23:06
Declare result here.
|
@@ -4021,21 +4019,21 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
// Allocate a fresh register to use as a temp in |
// ContextSlotOperandCheckExtensions and to hold the result |
// value. |
- value = allocator_->Allocate(); |
- ASSERT(value.is_valid()); |
- __ mov(value.reg(), |
+ result = allocator()->Allocate(); |
+ ASSERT(result.is_valid()); |
+ __ mov(result.reg(), |
ContextSlotOperandCheckExtensions(potential_slot, |
- value, |
+ result, |
&slow)); |
if (potential_slot->var()->mode() == Variable::CONST) { |
- __ cmp(value.reg(), Factory::the_hole_value()); |
- done.Branch(not_equal, &value); |
- __ mov(value.reg(), Factory::undefined_value()); |
+ __ cmp(result.reg(), Factory::the_hole_value()); |
+ done.Branch(not_equal, &result); |
+ __ mov(result.reg(), Factory::undefined_value()); |
} |
// There is always control flow to slow from |
// ContextSlotOperandCheckExtensions so we have to jump around |
// it. |
- done.Jump(&value); |
+ done.Jump(&result); |
} |
} |
@@ -4043,18 +4041,18 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
// A runtime call is inevitable. We eagerly sync frame elements |
// to memory so that we can push the arguments directly into place |
// on top of the frame. |
- frame_->SyncRange(0, frame_->element_count() - 1); |
- frame_->EmitPush(esi); |
- frame_->EmitPush(Immediate(slot->var()->name())); |
+ frame()->SyncRange(0, frame()->element_count() - 1); |
+ frame()->EmitPush(esi); |
+ frame()->EmitPush(Immediate(slot->var()->name())); |
if (typeof_state == INSIDE_TYPEOF) { |
- value = |
- frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
+ result = |
+ frame()->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
} else { |
- value = frame_->CallRuntime(Runtime::kLoadContextSlot, 2); |
+ result = frame()->CallRuntime(Runtime::kLoadContextSlot, 2); |
} |
- done.Bind(&value); |
- frame_->Push(&value); |
+ done.Bind(&result); |
+ return result; |
} else if (slot->var()->mode() == Variable::CONST) { |
// Const slots may contain 'the hole' value (the constant hasn't been |
@@ -4065,19 +4063,21 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
// potentially unsafe direct-frame access of SlotOperand. |
VirtualFrame::SpilledScope spilled_scope; |
Comment cmnt(masm_, "[ Load const"); |
- JumpTarget exit; |
+ Label exit; |
__ mov(ecx, SlotOperand(slot, ecx)); |
__ cmp(ecx, Factory::the_hole_value()); |
- exit.Branch(not_equal); |
+ __ j(not_equal, &exit); |
__ mov(ecx, Factory::undefined_value()); |
- exit.Bind(); |
- frame_->EmitPush(ecx); |
+ __ bind(&exit); |
+ return Result(ecx); |
} else if (slot->type() == Slot::PARAMETER) { |
- frame_->PushParameterAt(slot->index()); |
+ frame()->PushParameterAt(slot->index()); |
+ return frame()->Pop(); |
fschneider
2010/02/12 12:23:06
Would it make sense to have a virtual frame functi
Kevin Millikin (Chromium)
2010/02/12 12:39:21
Yes, and PushParameterAt should go away. That's a
|
} else if (slot->type() == Slot::LOCAL) { |
- frame_->PushLocalAt(slot->index()); |
+ frame()->PushLocalAt(slot->index()); |
+ return frame()->Pop(); |
} else { |
// The other remaining slot types (LOOKUP and GLOBAL) cannot reach |
fschneider
2010/02/12 12:23:06
Declare result here.
|
@@ -4086,49 +4086,46 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
// The use of SlotOperand below is safe for an unspilled frame |
// because it will always be a context slot. |
ASSERT(slot->type() == Slot::CONTEXT); |
- Result temp = allocator_->Allocate(); |
- ASSERT(temp.is_valid()); |
- __ mov(temp.reg(), SlotOperand(slot, temp.reg())); |
- frame_->Push(&temp); |
+ result = allocator()->Allocate(); |
+ ASSERT(result.is_valid()); |
+ __ mov(result.reg(), SlotOperand(slot, result.reg())); |
+ return result; |
} |
} |
-void CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot, |
- TypeofState state) { |
- LoadFromSlot(slot, state); |
+Result CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot, |
+ TypeofState state) { |
+ Result result = LoadFromSlot(slot, state); |
// Bail out quickly if we're not using lazy arguments allocation. |
- if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return; |
+ if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return result; |
// ... or if the slot isn't a non-parameter arguments slot. |
- if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return; |
- |
- // Pop the loaded value from the stack. |
- Result value = frame_->Pop(); |
+ if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return result; |
// If the loaded value is a constant, we know if the arguments |
// object has been lazily loaded yet. |
- if (value.is_constant()) { |
- if (value.handle()->IsTheHole()) { |
- Result arguments = StoreArgumentsObject(false); |
- frame_->Push(&arguments); |
+ if (result.is_constant()) { |
+ if (result.handle()->IsTheHole()) { |
+ result.Unuse(); |
+ return StoreArgumentsObject(false); |
} else { |
- frame_->Push(&value); |
+ return result; |
} |
- return; |
} |
// The loaded value is in a register. If it is the sentinel that |
// indicates that we haven't loaded the arguments object yet, we |
// need to do it now. |
JumpTarget exit; |
- __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value())); |
- frame_->Push(&value); |
- exit.Branch(not_equal); |
- Result arguments = StoreArgumentsObject(false); |
- frame_->SetElementAt(0, &arguments); |
- exit.Bind(); |
+ __ cmp(Operand(result.reg()), Immediate(Factory::the_hole_value())); |
+ exit.Branch(not_equal, &result); |
+ |
+ result.Unuse(); |
+ result = StoreArgumentsObject(false); |
+ exit.Bind(&result); |
+ return result; |
} |
@@ -4302,7 +4299,8 @@ void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { |
void CodeGenerator::VisitSlot(Slot* node) { |
Comment cmnt(masm_, "[ Slot"); |
- LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF); |
+ Result result = LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF); |
+ frame()->Push(&result); |
} |
@@ -6569,10 +6567,10 @@ void Reference::GetValue() { |
Comment cmnt(masm, "[ Load from Slot"); |
Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
ASSERT(slot != NULL); |
- cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); |
- if (!persist_after_get_) { |
- cgen_->UnloadReference(this); |
- } |
+ Result result = |
+ cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); |
+ if (!persist_after_get_) set_unloaded(); |
+ cgen_->frame()->Push(&result); |
break; |
} |