| Index: src/ia32/virtual-frame-ia32.cc
|
| ===================================================================
|
| --- src/ia32/virtual-frame-ia32.cc (revision 2006)
|
| +++ src/ia32/virtual-frame-ia32.cc (working copy)
|
| @@ -33,24 +33,17 @@
|
|
|
| namespace v8 { namespace internal {
|
|
|
| -#define __ ACCESS_MASM(masm_)
|
| +#define __ ACCESS_MASM(masm())
|
|
|
| // -------------------------------------------------------------------------
|
| // VirtualFrame implementation.
|
|
|
| // On entry to a function, the virtual frame already contains the receiver,
|
| // the parameters, and a return address. All frame elements are in memory.
|
| -VirtualFrame::VirtualFrame(CodeGenerator* cgen)
|
| - : cgen_(cgen),
|
| - masm_(cgen->masm()),
|
| - elements_(cgen->scope()->num_parameters()
|
| - + cgen->scope()->num_stack_slots()
|
| - + kPreallocatedElements),
|
| - parameter_count_(cgen->scope()->num_parameters()),
|
| - local_count_(0),
|
| - stack_pointer_(parameter_count_ + 1), // 0-based index of TOS.
|
| - frame_pointer_(kIllegalIndex) {
|
| - for (int i = 0; i < parameter_count_ + 2; i++) {
|
| +VirtualFrame::VirtualFrame()
|
| + : elements_(parameter_count() + local_count() + kPreallocatedElements),
|
| + stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
|
| + for (int i = 0; i <= stack_pointer_; i++) {
|
| elements_.Add(FrameElement::MemoryElement());
|
| }
|
| for (int i = 0; i < kNumRegisters; i++) {
|
| @@ -80,10 +73,10 @@
|
| break;
|
|
|
| case FrameElement::CONSTANT:
|
| - if (cgen_->IsUnsafeSmi(element.handle())) {
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + if (cgen()->IsUnsafeSmi(element.handle())) {
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| - cgen_->LoadUnsafeSmi(temp.reg(), element.handle());
|
| + cgen()->LoadUnsafeSmi(temp.reg(), element.handle());
|
| __ mov(Operand(ebp, fp_relative(index)), temp.reg());
|
| } else {
|
| __ Set(Operand(ebp, fp_relative(index)),
|
| @@ -95,7 +88,7 @@
|
| int backing_index = element.index();
|
| FrameElement backing_element = elements_[backing_index];
|
| if (backing_element.is_memory()) {
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| __ mov(temp.reg(), Operand(ebp, fp_relative(backing_index)));
|
| __ mov(Operand(ebp, fp_relative(index)), temp.reg());
|
| @@ -132,10 +125,10 @@
|
| break;
|
|
|
| case FrameElement::CONSTANT:
|
| - if (cgen_->IsUnsafeSmi(element.handle())) {
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + if (cgen()->IsUnsafeSmi(element.handle())) {
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| - cgen_->LoadUnsafeSmi(temp.reg(), element.handle());
|
| + cgen()->LoadUnsafeSmi(temp.reg(), element.handle());
|
| __ push(temp.reg());
|
| } else {
|
| __ push(Immediate(element.handle()));
|
| @@ -200,7 +193,7 @@
|
| if (element.is_copy()) {
|
| backing_element = elements_[element.index()];
|
| }
|
| - Result fresh = cgen_->allocator()->Allocate();
|
| + Result fresh = cgen()->allocator()->Allocate();
|
| ASSERT(fresh.is_valid());
|
| elements_[i] =
|
| FrameElement::RegisterElement(fresh.reg(),
|
| @@ -209,8 +202,8 @@
|
|
|
| // Emit a move.
|
| if (element.is_constant()) {
|
| - if (cgen_->IsUnsafeSmi(element.handle())) {
|
| - cgen_->LoadUnsafeSmi(fresh.reg(), element.handle());
|
| + if (cgen()->IsUnsafeSmi(element.handle())) {
|
| + cgen()->LoadUnsafeSmi(fresh.reg(), element.handle());
|
| } else {
|
| __ Set(fresh.reg(), Immediate(element.handle()));
|
| }
|
| @@ -245,10 +238,10 @@
|
|
|
|
|
| void VirtualFrame::MergeTo(VirtualFrame* expected) {
|
| - Comment cmnt(masm_, "[ Merge frame");
|
| + Comment cmnt(masm(), "[ Merge frame");
|
| // We should always be merging the code generator's current frame to an
|
| // expected frame.
|
| - ASSERT(cgen_->frame() == this);
|
| + ASSERT(cgen()->frame() == this);
|
|
|
| // Adjust the stack pointer upward (toward the top of the virtual
|
| // frame) if necessary.
|
| @@ -311,9 +304,9 @@
|
|
|
| case FrameElement::CONSTANT:
|
| if (!source.is_synced()) {
|
| - if (cgen_->IsUnsafeSmi(source.handle())) {
|
| + if (cgen()->IsUnsafeSmi(source.handle())) {
|
| esi_caches = i;
|
| - cgen_->LoadUnsafeSmi(esi, source.handle());
|
| + cgen()->LoadUnsafeSmi(esi, source.handle());
|
| __ mov(Operand(ebp, fp_relative(i)), esi);
|
| } else {
|
| __ Set(Operand(ebp, fp_relative(i)), Immediate(source.handle()));
|
| @@ -417,8 +410,8 @@
|
| break;
|
|
|
| case FrameElement::CONSTANT:
|
| - if (cgen_->IsUnsafeSmi(source.handle())) {
|
| - cgen_->LoadUnsafeSmi(target_reg, source.handle());
|
| + if (cgen()->IsUnsafeSmi(source.handle())) {
|
| + cgen()->LoadUnsafeSmi(target_reg, source.handle());
|
| } else {
|
| __ Set(target_reg, Immediate(source.handle()));
|
| }
|
| @@ -463,7 +456,7 @@
|
|
|
| void VirtualFrame::Enter() {
|
| // Registers live on entry: esp, ebp, esi, edi.
|
| - Comment cmnt(masm_, "[ Enter JS frame");
|
| + Comment cmnt(masm(), "[ Enter JS frame");
|
|
|
| #ifdef DEBUG
|
| // Verify that edi contains a JS function. The following code
|
| @@ -478,7 +471,6 @@
|
|
|
| EmitPush(ebp);
|
|
|
| - frame_pointer_ = stack_pointer_;
|
| __ mov(ebp, Operand(esp));
|
|
|
| // Store the context in the frame. The context is kept in esi and a
|
| @@ -490,12 +482,12 @@
|
| // reference now (ie, it can keep it in edi or spill it later).
|
| Push(edi);
|
| SyncElementAt(elements_.length() - 1);
|
| - cgen_->allocator()->Unuse(edi);
|
| + cgen()->allocator()->Unuse(edi);
|
| }
|
|
|
|
|
| void VirtualFrame::Exit() {
|
| - Comment cmnt(masm_, "[ Exit JS frame");
|
| + Comment cmnt(masm(), "[ Exit JS frame");
|
| // Record the location of the JS exit code for patching when setting
|
| // break point.
|
| __ RecordJSReturn();
|
| @@ -505,7 +497,7 @@
|
| // call instruction to support patching the exit code in the
|
| // debugger. See VisitReturnStatement for the full return sequence.
|
| __ mov(esp, Operand(ebp));
|
| - stack_pointer_ = frame_pointer_;
|
| + stack_pointer_ = frame_pointer();
|
| for (int i = elements_.length() - 1; i > stack_pointer_; i--) {
|
| FrameElement last = elements_.RemoveLast();
|
| if (last.is_register()) {
|
| @@ -513,17 +505,16 @@
|
| }
|
| }
|
|
|
| - frame_pointer_ = kIllegalIndex;
|
| EmitPop(ebp);
|
| }
|
|
|
|
|
| -void VirtualFrame::AllocateStackSlots(int count) {
|
| +void VirtualFrame::AllocateStackSlots() {
|
| ASSERT(height() == 0);
|
| - local_count_ = count;
|
|
|
| + int count = local_count();
|
| if (count > 0) {
|
| - Comment cmnt(masm_, "[ Allocate space for locals");
|
| + Comment cmnt(masm(), "[ Allocate space for locals");
|
| // The locals are initialized to a constant (the undefined value), but
|
| // we sync them with the actual frame to allocate space for spilling
|
| // them later. First sync everything above the stack pointer so we can
|
| @@ -532,7 +523,7 @@
|
| Handle<Object> undefined = Factory::undefined_value();
|
| FrameElement initial_value =
|
| FrameElement::ConstantElement(undefined, FrameElement::SYNCED);
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| __ Set(temp.reg(), Immediate(undefined));
|
| for (int i = 0; i < count; i++) {
|
| @@ -557,7 +548,7 @@
|
|
|
|
|
| void VirtualFrame::PushReceiverSlotAddress() {
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| __ lea(temp.reg(), ParameterAt(-1));
|
| Push(&temp);
|
| @@ -591,7 +582,7 @@
|
| // This is the backing store of copies.
|
| Register backing_reg;
|
| if (original.is_memory()) {
|
| - Result fresh = cgen_->allocator()->Allocate();
|
| + Result fresh = cgen()->allocator()->Allocate();
|
| ASSERT(fresh.is_valid());
|
| Use(fresh.reg(), new_backing_index);
|
| backing_reg = fresh.reg();
|
| @@ -636,7 +627,7 @@
|
| case FrameElement::MEMORY: {
|
| // Emit code to load the original element's data into a register.
|
| // Push that register as a FrameElement on top of the frame.
|
| - Result fresh = cgen_->allocator()->Allocate();
|
| + Result fresh = cgen()->allocator()->Allocate();
|
| ASSERT(fresh.is_valid());
|
| FrameElement new_element =
|
| FrameElement::RegisterElement(fresh.reg(),
|
| @@ -710,7 +701,7 @@
|
| // temp register. Alternatively, allow copies to appear in
|
| // any order in the frame and lazily move the value down to
|
| // the slot.
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| __ mov(temp.reg(), Operand(ebp, fp_relative(backing_index)));
|
| __ mov(Operand(ebp, fp_relative(index)), temp.reg());
|
| @@ -757,7 +748,7 @@
|
|
|
| // The sync state of the former top element is correct (synced).
|
| // Emit code to move the value down in the frame.
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| __ mov(temp.reg(), Operand(esp, 0));
|
| __ mov(Operand(ebp, fp_relative(index)), temp.reg());
|
| @@ -782,7 +773,7 @@
|
|
|
|
|
| void VirtualFrame::PushTryHandler(HandlerType type) {
|
| - ASSERT(cgen_->HasValidEntryRegisters());
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| // Grow the expression stack by handler size less two (the return address
|
| // is already pushed by a call instruction, and PushTryHandler from the
|
| // macro assembler will leave the top of stack in the eax register to be
|
| @@ -795,9 +786,9 @@
|
|
|
|
|
| Result VirtualFrame::RawCallStub(CodeStub* stub) {
|
| - ASSERT(cgen_->HasValidEntryRegisters());
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| __ CallStub(stub);
|
| - Result result = cgen_->allocator()->Allocate(eax);
|
| + Result result = cgen()->allocator()->Allocate(eax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| }
|
| @@ -838,9 +829,9 @@
|
|
|
| Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
|
| PrepareForCall(arg_count, arg_count);
|
| - ASSERT(cgen_->HasValidEntryRegisters());
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| __ CallRuntime(f, arg_count);
|
| - Result result = cgen_->allocator()->Allocate(eax);
|
| + Result result = cgen()->allocator()->Allocate(eax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| }
|
| @@ -848,9 +839,9 @@
|
|
|
| Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
|
| PrepareForCall(arg_count, arg_count);
|
| - ASSERT(cgen_->HasValidEntryRegisters());
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| __ CallRuntime(id, arg_count);
|
| - Result result = cgen_->allocator()->Allocate(eax);
|
| + Result result = cgen()->allocator()->Allocate(eax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| }
|
| @@ -860,9 +851,9 @@
|
| InvokeFlag flag,
|
| int arg_count) {
|
| PrepareForCall(arg_count, arg_count);
|
| - ASSERT(cgen_->HasValidEntryRegisters());
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| __ InvokeBuiltin(id, flag);
|
| - Result result = cgen_->allocator()->Allocate(eax);
|
| + Result result = cgen()->allocator()->Allocate(eax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| }
|
| @@ -870,9 +861,9 @@
|
|
|
| Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
|
| RelocInfo::Mode rmode) {
|
| - ASSERT(cgen_->HasValidEntryRegisters());
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| __ call(code, rmode);
|
| - Result result = cgen_->allocator()->Allocate(eax);
|
| + Result result = cgen()->allocator()->Allocate(eax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| }
|
| @@ -952,8 +943,8 @@
|
| // The IC expects them on the stack. It does not drop the function
|
| // name slot (but it does drop the rest).
|
| Handle<Code> ic = (loop_nesting > 0)
|
| - ? cgen_->ComputeCallInitializeInLoop(arg_count)
|
| - : cgen_->ComputeCallInitialize(arg_count);
|
| + ? cgen()->ComputeCallInitializeInLoop(arg_count)
|
| + : cgen()->ComputeCallInitialize(arg_count);
|
| // Spill args, receiver, and function. The call will drop args and
|
| // receiver.
|
| PrepareForCall(arg_count + 2, arg_count + 1);
|
| @@ -975,7 +966,7 @@
|
| // Constructors are called with the number of arguments in register
|
| // eax for now. Another option would be to have separate construct
|
| // call trampolines per different arguments counts encountered.
|
| - Result num_args = cgen_->allocator()->Allocate(eax);
|
| + Result num_args = cgen()->allocator()->Allocate(eax);
|
| ASSERT(num_args.is_valid());
|
| __ Set(num_args.reg(), Immediate(arg_count));
|
|
|
| @@ -1015,7 +1006,7 @@
|
| if (pop_needed) {
|
| stack_pointer_--;
|
| if (element.is_memory()) {
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| temp.set_static_type(element.static_type());
|
| __ pop(temp.reg());
|
| @@ -1042,7 +1033,7 @@
|
| // Memory elements could only be the backing store of a copy.
|
| // Allocate the original to a register.
|
| ASSERT(index <= stack_pointer_);
|
| - Result temp = cgen_->allocator()->Allocate();
|
| + Result temp = cgen()->allocator()->Allocate();
|
| ASSERT(temp.is_valid());
|
| Use(temp.reg(), index);
|
| FrameElement new_element =
|
|
|