Size reduction of VirtualFrame objects. Remove the code generator and

macro assembler pointers and all derived state.

Review URL: http://codereview.chromium.org/115564

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2011 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f04016b1
This diff is collapsed.
...@@ -36,23 +36,16 @@ namespace v8 { namespace internal { ...@@ -36,23 +36,16 @@ namespace v8 { namespace internal {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// VirtualFrame implementation. // VirtualFrame implementation.
#define __ ACCESS_MASM(masm_) #define __ ACCESS_MASM(masm())
// On entry to a function, the virtual frame already contains the // On entry to a function, the virtual frame already contains the
// receiver and the parameters. All initial frame elements are in // receiver and the parameters. All initial frame elements are in
// memory. // memory.
VirtualFrame::VirtualFrame(CodeGenerator* cgen) VirtualFrame::VirtualFrame()
: cgen_(cgen), : elements_(parameter_count() + local_count() + kPreallocatedElements),
masm_(cgen->masm()), stack_pointer_(parameter_count()) { // 0-based index of TOS.
elements_(cgen->scope()->num_parameters() for (int i = 0; i <= stack_pointer_; i++) {
+ cgen->scope()->num_stack_slots()
+ kPreallocatedElements),
parameter_count_(cgen->scope()->num_parameters()),
local_count_(0),
stack_pointer_(parameter_count_), // 0-based index of TOS.
frame_pointer_(kIllegalIndex) {
for (int i = 0; i < parameter_count_ + 1; i++) {
elements_.Add(FrameElement::MemoryElement()); elements_.Add(FrameElement::MemoryElement());
} }
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
...@@ -82,10 +75,10 @@ void VirtualFrame::SyncRange(int begin, int end) { ...@@ -82,10 +75,10 @@ void VirtualFrame::SyncRange(int begin, int end) {
void VirtualFrame::MergeTo(VirtualFrame* expected) { 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 // We should always be merging the code generator's current frame to an
// expected frame. // expected frame.
ASSERT(cgen_->frame() == this); ASSERT(cgen()->frame() == this);
// Adjust the stack pointer upward (toward the top of the virtual // Adjust the stack pointer upward (toward the top of the virtual
// frame) if necessary. // frame) if necessary.
...@@ -152,7 +145,7 @@ void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame* expected) { ...@@ -152,7 +145,7 @@ void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame* expected) {
void VirtualFrame::Enter() { void VirtualFrame::Enter() {
Comment cmnt(masm_, "[ Enter JS frame"); Comment cmnt(masm(), "[ Enter JS frame");
#ifdef DEBUG #ifdef DEBUG
// Verify that r1 contains a JS function. The following code relies // Verify that r1 contains a JS function. The following code relies
...@@ -175,15 +168,14 @@ void VirtualFrame::Enter() { ...@@ -175,15 +168,14 @@ void VirtualFrame::Enter() {
Adjust(4); Adjust(4);
__ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
// Adjust FP to point to saved FP. // Adjust FP to point to saved FP.
frame_pointer_ = elements_.length() - 2;
__ add(fp, sp, Operand(2 * kPointerSize)); __ add(fp, sp, Operand(2 * kPointerSize));
cgen_->allocator()->Unuse(r1); cgen()->allocator()->Unuse(r1);
cgen_->allocator()->Unuse(lr); cgen()->allocator()->Unuse(lr);
} }
void VirtualFrame::Exit() { void VirtualFrame::Exit() {
Comment cmnt(masm_, "[ Exit JS frame"); Comment cmnt(masm(), "[ Exit JS frame");
// Drop the execution stack down to the frame pointer and restore the caller // Drop the execution stack down to the frame pointer and restore the caller
// frame pointer and return address. // frame pointer and return address.
__ mov(sp, fp); __ mov(sp, fp);
...@@ -191,12 +183,11 @@ void VirtualFrame::Exit() { ...@@ -191,12 +183,11 @@ void VirtualFrame::Exit() {
} }
void VirtualFrame::AllocateStackSlots(int count) { void VirtualFrame::AllocateStackSlots() {
ASSERT(height() == 0); int count = local_count();
local_count_ = count;
Adjust(count);
if (count > 0) { if (count > 0) {
Comment cmnt(masm_, "[ Allocate space for locals"); Comment cmnt(masm(), "[ Allocate space for locals");
Adjust(count);
// Initialize stack slots with 'undefined' value. // Initialize stack slots with 'undefined' value.
__ mov(ip, Operand(Factory::undefined_value())); __ mov(ip, Operand(Factory::undefined_value()));
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
...@@ -246,9 +237,9 @@ void VirtualFrame::PushTryHandler(HandlerType type) { ...@@ -246,9 +237,9 @@ void VirtualFrame::PushTryHandler(HandlerType type) {
Result VirtualFrame::RawCallStub(CodeStub* stub) { Result VirtualFrame::RawCallStub(CodeStub* stub) {
ASSERT(cgen_->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ CallStub(stub); __ CallStub(stub);
Result result = cgen_->allocator()->Allocate(r0); Result result = cgen()->allocator()->Allocate(r0);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
...@@ -271,9 +262,9 @@ Result VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) { ...@@ -271,9 +262,9 @@ Result VirtualFrame::CallStub(CodeStub* stub, Result* arg0, Result* arg1) {
Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
PrepareForCall(arg_count, arg_count); PrepareForCall(arg_count, arg_count);
ASSERT(cgen_->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ CallRuntime(f, arg_count); __ CallRuntime(f, arg_count);
Result result = cgen_->allocator()->Allocate(r0); Result result = cgen()->allocator()->Allocate(r0);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
...@@ -281,9 +272,9 @@ Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { ...@@ -281,9 +272,9 @@ Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
PrepareForCall(arg_count, arg_count); PrepareForCall(arg_count, arg_count);
ASSERT(cgen_->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ CallRuntime(id, arg_count); __ CallRuntime(id, arg_count);
Result result = cgen_->allocator()->Allocate(r0); Result result = cgen()->allocator()->Allocate(r0);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
...@@ -297,16 +288,16 @@ Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id, ...@@ -297,16 +288,16 @@ Result VirtualFrame::InvokeBuiltin(Builtins::JavaScript id,
PrepareForCall(arg_count, arg_count); PrepareForCall(arg_count, arg_count);
arg_count_register->Unuse(); arg_count_register->Unuse();
__ InvokeBuiltin(id, flags); __ InvokeBuiltin(id, flags);
Result result = cgen_->allocator()->Allocate(r0); Result result = cgen()->allocator()->Allocate(r0);
return result; return result;
} }
Result VirtualFrame::RawCallCodeObject(Handle<Code> code, Result VirtualFrame::RawCallCodeObject(Handle<Code> code,
RelocInfo::Mode rmode) { RelocInfo::Mode rmode) {
ASSERT(cgen_->HasValidEntryRegisters()); ASSERT(cgen()->HasValidEntryRegisters());
__ Call(code, rmode); __ Call(code, rmode);
Result result = cgen_->allocator()->Allocate(r0); Result result = cgen()->allocator()->Allocate(r0);
ASSERT(result.is_valid()); ASSERT(result.is_valid());
return result; return result;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define V8_ARM_VIRTUAL_FRAME_ARM_H_ #define V8_ARM_VIRTUAL_FRAME_ARM_H_
#include "register-allocator.h" #include "register-allocator.h"
#include "scopes.h"
namespace v8 { namespace internal { namespace v8 { namespace internal {
...@@ -50,37 +51,39 @@ class VirtualFrame : public ZoneObject { ...@@ -50,37 +51,39 @@ class VirtualFrame : public ZoneObject {
// generator is being transformed. // generator is being transformed.
class SpilledScope BASE_EMBEDDED { class SpilledScope BASE_EMBEDDED {
public: public:
explicit SpilledScope(CodeGenerator* cgen) SpilledScope() : previous_state_(cgen()->in_spilled_code()) {
: cgen_(cgen), ASSERT(cgen()->has_valid_frame());
previous_state_(cgen->in_spilled_code()) { cgen()->frame()->SpillAll();
ASSERT(cgen->has_valid_frame()); cgen()->set_in_spilled_code(true);
cgen->frame()->SpillAll();
cgen->set_in_spilled_code(true);
} }
~SpilledScope() { ~SpilledScope() {
cgen_->set_in_spilled_code(previous_state_); cgen()->set_in_spilled_code(previous_state_);
} }
private: private:
CodeGenerator* cgen_;
bool previous_state_; bool previous_state_;
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
}; };
// An illegal index into the virtual frame. // An illegal index into the virtual frame.
static const int kIllegalIndex = -1; static const int kIllegalIndex = -1;
// Construct an initial virtual frame on entry to a JS function. // Construct an initial virtual frame on entry to a JS function.
explicit VirtualFrame(CodeGenerator* cgen); VirtualFrame();
// Construct a virtual frame as a clone of an existing one. // Construct a virtual frame as a clone of an existing one.
explicit VirtualFrame(VirtualFrame* original); explicit VirtualFrame(VirtualFrame* original);
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
MacroAssembler* masm() { return cgen()->masm(); }
// Create a duplicate of an existing valid frame element. // Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index); FrameElement CopyElementAt(int index);
// The height of the virtual expression stack. // The height of the virtual expression stack.
int height() const { int height() {
return elements_.length() - expression_base_index(); return elements_.length() - expression_base_index();
} }
...@@ -143,7 +146,7 @@ class VirtualFrame : public ZoneObject { ...@@ -143,7 +146,7 @@ class VirtualFrame : public ZoneObject {
// registers. Used when the code generator's frame is switched from this // registers. Used when the code generator's frame is switched from this
// one to NULL by an unconditional jump. // one to NULL by an unconditional jump.
void DetachFromCodeGenerator() { void DetachFromCodeGenerator() {
RegisterAllocator* cgen_allocator = cgen_->allocator(); RegisterAllocator* cgen_allocator = cgen()->allocator();
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i)) { if (is_used(i)) {
Register temp = { i }; Register temp = { i };
...@@ -157,7 +160,7 @@ class VirtualFrame : public ZoneObject { ...@@ -157,7 +160,7 @@ class VirtualFrame : public ZoneObject {
// Used when a code generator's frame is switched from NULL to this one by // Used when a code generator's frame is switched from NULL to this one by
// binding a label. // binding a label.
void AttachToCodeGenerator() { void AttachToCodeGenerator() {
RegisterAllocator* cgen_allocator = cgen_->allocator(); RegisterAllocator* cgen_allocator = cgen()->allocator();
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i)) { if (is_used(i)) {
Register temp = { i }; Register temp = { i };
...@@ -180,13 +183,13 @@ class VirtualFrame : public ZoneObject { ...@@ -180,13 +183,13 @@ class VirtualFrame : public ZoneObject {
void PrepareForReturn(); void PrepareForReturn();
// Allocate and initialize the frame-allocated locals. // Allocate and initialize the frame-allocated locals.
void AllocateStackSlots(int count); void AllocateStackSlots();
// The current top of the expression stack as an assembly operand. // The current top of the expression stack as an assembly operand.
MemOperand Top() const { return MemOperand(sp, 0); } MemOperand Top() { return MemOperand(sp, 0); }
// An element of the expression stack as an assembly operand. // An element of the expression stack as an assembly operand.
MemOperand ElementAt(int index) const { MemOperand ElementAt(int index) {
return MemOperand(sp, index * kPointerSize); return MemOperand(sp, index * kPointerSize);
} }
...@@ -205,9 +208,9 @@ class VirtualFrame : public ZoneObject { ...@@ -205,9 +208,9 @@ class VirtualFrame : public ZoneObject {
} }
// A frame-allocated local as an assembly operand. // A frame-allocated local as an assembly operand.
MemOperand LocalAt(int index) const { MemOperand LocalAt(int index) {
ASSERT(0 <= index); ASSERT(0 <= index);
ASSERT(index < local_count_); ASSERT(index < local_count());
return MemOperand(fp, kLocal0Offset - index * kPointerSize); return MemOperand(fp, kLocal0Offset - index * kPointerSize);
} }
...@@ -233,13 +236,13 @@ class VirtualFrame : public ZoneObject { ...@@ -233,13 +236,13 @@ class VirtualFrame : public ZoneObject {
void PushReceiverSlotAddress(); void PushReceiverSlotAddress();
// The function frame slot. // The function frame slot.
MemOperand Function() const { return MemOperand(fp, kFunctionOffset); } MemOperand Function() { return MemOperand(fp, kFunctionOffset); }
// Push the function on top of the frame. // Push the function on top of the frame.
void PushFunction() { PushFrameSlotAt(function_index()); } void PushFunction() { PushFrameSlotAt(function_index()); }
// The context frame slot. // The context frame slot.
MemOperand Context() const { return MemOperand(fp, kContextOffset); } MemOperand Context() { return MemOperand(fp, kContextOffset); }
// Save the value of the esi register to the context frame slot. // Save the value of the esi register to the context frame slot.
void SaveContextRegister(); void SaveContextRegister();
...@@ -249,10 +252,11 @@ class VirtualFrame : public ZoneObject { ...@@ -249,10 +252,11 @@ class VirtualFrame : public ZoneObject {
void RestoreContextRegister(); void RestoreContextRegister();
// A parameter as an assembly operand. // A parameter as an assembly operand.
MemOperand ParameterAt(int index) const { MemOperand ParameterAt(int index) {
// Index -1 corresponds to the receiver. // Index -1 corresponds to the receiver.
ASSERT(-1 <= index && index <= parameter_count_); ASSERT(-1 <= index); // -1 is the receiver.
return MemOperand(fp, (1 + parameter_count_ - index) * kPointerSize); ASSERT(index <= parameter_count());
return MemOperand(fp, (1 + parameter_count() - index) * kPointerSize);
} }
// Push a copy of the value of a parameter frame slot on top of the frame. // Push a copy of the value of a parameter frame slot on top of the frame.
...@@ -274,7 +278,7 @@ class VirtualFrame : public ZoneObject { ...@@ -274,7 +278,7 @@ class VirtualFrame : public ZoneObject {
} }
// The receiver frame slot. // The receiver frame slot.
MemOperand Receiver() const { return ParameterAt(-1); } MemOperand Receiver() { return ParameterAt(-1); }
// Push a try-catch or try-finally handler on top of the virtual frame. // Push a try-catch or try-finally handler on top of the virtual frame.
void PushTryHandler(HandlerType type); void PushTryHandler(HandlerType type);
...@@ -374,59 +378,50 @@ class VirtualFrame : public ZoneObject { ...@@ -374,59 +378,50 @@ class VirtualFrame : public ZoneObject {
static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
CodeGenerator* cgen_;
MacroAssembler* masm_;
ZoneList<FrameElement> elements_; ZoneList<FrameElement> elements_;
// The number of frame-allocated locals and parameters respectively.
int parameter_count_;
int local_count_;
// The index of the element that is at the processor's stack pointer // The index of the element that is at the processor's stack pointer
// (the sp register). // (the sp register).
int stack_pointer_; int stack_pointer_;
// The index of the element that is at the processor's frame pointer
// (the fp register).
int frame_pointer_;
// The index of the register frame element using each register, or // The index of the register frame element using each register, or
// kIllegalIndex if a register is not on the frame. // kIllegalIndex if a register is not on the frame.
int register_locations_[kNumRegisters]; int register_locations_[kNumRegisters];
// The number of frame-allocated locals and parameters respectively.
int parameter_count() { return cgen()->scope()->num_parameters(); }
int local_count() { return cgen()->scope()->num_stack_slots(); }
// The index of the element that is at the processor's frame pointer
// (the fp register). The parameters, receiver, function, and context
// are below the frame pointer.
int frame_pointer() { return parameter_count() + 3; }
// The index of the first parameter. The receiver lies below the first // The index of the first parameter. The receiver lies below the first
// parameter. // parameter.
int param0_index() const { return 1; } int param0_index() { return 1; }
// The index of the context slot in the frame. // The index of the context slot in the frame. It is immediately
int context_index() const { // below the frame pointer.
ASSERT(frame_pointer_ != kIllegalIndex); int context_index() { return frame_pointer() - 1; }
return frame_pointer_ - 1;
}
// The index of the function slot in the frame. It lies above the context // The index of the function slot in the frame. It is below the frame
// slot. // pointer and context slot.
int function_index() const { int function_index() { return frame_pointer() - 2; }
ASSERT(frame_pointer_ != kIllegalIndex);
return frame_pointer_ - 2;
}
// The index of the first local. Between the parameters and the locals // The index of the first local. Between the frame pointer and the
// lie the return address, the saved frame pointer, the context, and the // locals lies the return address.
// function. int local0_index() { return frame_pointer() + 2; }
int local0_index() const {
ASSERT(frame_pointer_ != kIllegalIndex);
return frame_pointer_ + 2;
}
// The index of the base of the expression stack. // The index of the base of the expression stack.
int expression_base_index() const { return local0_index() + local_count_; } int expression_base_index() { return local0_index() + local_count(); }
// Convert a frame index into a frame pointer relative offset into the // Convert a frame index into a frame pointer relative offset into the
// actual stack. // actual stack.
int fp_relative(int index) const { int fp_relative(int index) {
return (frame_pointer_ - index) * kPointerSize; ASSERT(index < elements_.length());
ASSERT(frame_pointer() < elements_.length()); // FP is on the frame.
return (frame_pointer() - index) * kPointerSize;
} }
// Record an occurrence of a register in the virtual frame. This has the // Record an occurrence of a register in the virtual frame. This has the
...@@ -435,7 +430,7 @@ class VirtualFrame : public ZoneObject { ...@@ -435,7 +430,7 @@ class VirtualFrame : public ZoneObject {
void Use(Register reg, int index) { void Use(Register reg, int index) {
ASSERT(!is_used(reg)); ASSERT(!is_used(reg));
register_locations_[reg.code()] = index; register_locations_[reg.code()] = index;
cgen_->allocator()->Use(reg); cgen()->allocator()->Use(reg);
} }
// Record that a register reference has been dropped from the frame. This // Record that a register reference has been dropped from the frame. This
...@@ -444,7 +439,7 @@ class VirtualFrame : public ZoneObject { ...@@ -444,7 +439,7 @@ class VirtualFrame : public ZoneObject {
void Unuse(Register reg) { void Unuse(Register reg) {
ASSERT(register_locations_[reg.code()] != kIllegalIndex); ASSERT(register_locations_[reg.code()] != kIllegalIndex);
register_locations_[reg.code()] = kIllegalIndex; register_locations_[reg.code()] = kIllegalIndex;
cgen_->allocator()->Unuse(reg); cgen()->allocator()->Unuse(reg);
} }
// Spill the element at a particular index---write it to memory if // Spill the element at a particular index---write it to memory if
......
...@@ -107,7 +107,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { ...@@ -107,7 +107,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) {
RegisterAllocator register_allocator(this); RegisterAllocator register_allocator(this);
allocator_ = &register_allocator; allocator_ = &register_allocator;
ASSERT(frame_ == NULL); ASSERT(frame_ == NULL);
frame_ = new VirtualFrame(this); frame_ = new VirtualFrame();
set_in_spilled_code(false); set_in_spilled_code(false);
// Adjust for function-level loop nesting. // Adjust for function-level loop nesting.
...@@ -138,7 +138,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) { ...@@ -138,7 +138,7 @@ void CodeGenerator::GenCode(FunctionLiteral* fun) {
frame_->Enter(); frame_->Enter();
// Allocate space for locals and initialize them. // Allocate space for locals and initialize them.
frame_->AllocateStackSlots(scope_->num_stack_slots()); frame_->AllocateStackSlots();
// Initialize the function return target after the locals are set // Initialize the function return target after the locals are set
// up, because it needs the expected frame height from the frame. // up, because it needs the expected frame height from the frame.
function_return_.set_direction(JumpTarget::BIDIRECTIONAL); function_return_.set_direction(JumpTarget::BIDIRECTIONAL);
...@@ -2651,7 +2651,7 @@ void CodeGenerator::VisitLoopStatement(LoopStatement* node) { ...@@ -2651,7 +2651,7 @@ void CodeGenerator::VisitLoopStatement(LoopStatement* node) {
void CodeGenerator::VisitForInStatement(ForInStatement* node) { void CodeGenerator::VisitForInStatement(ForInStatement* node) {
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
VirtualFrame::SpilledScope spilled_scope(this); VirtualFrame::SpilledScope spilled_scope;
Comment cmnt(masm_, "[ ForInStatement"); Comment cmnt(masm_, "[ ForInStatement");
CodeForStatementPosition(node); CodeForStatementPosition(node);
...@@ -2841,7 +2841,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { ...@@ -2841,7 +2841,7 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) {
void CodeGenerator::VisitTryCatch(TryCatch* node) { void CodeGenerator::VisitTryCatch(TryCatch* node) {
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
VirtualFrame::SpilledScope spilled_scope(this); VirtualFrame::SpilledScope spilled_scope;
Comment cmnt(masm_, "[ TryCatch"); Comment cmnt(masm_, "[ TryCatch");
CodeForStatementPosition(node); CodeForStatementPosition(node);
...@@ -2980,7 +2980,7 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) { ...@@ -2980,7 +2980,7 @@ void CodeGenerator::VisitTryCatch(TryCatch* node) {
void CodeGenerator::VisitTryFinally(TryFinally* node) { void CodeGenerator::VisitTryFinally(TryFinally* node) {
ASSERT(!in_spilled_code()); ASSERT(!in_spilled_code());
VirtualFrame::SpilledScope spilled_scope(this); VirtualFrame::SpilledScope spilled_scope;
Comment cmnt(masm_, "[ TryFinally"); Comment cmnt(masm_, "[ TryFinally");
CodeForStatementPosition(node); CodeForStatementPosition(node);
...@@ -3315,7 +3315,7 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { ...@@ -3315,7 +3315,7 @@ void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) {
// //
// We currently spill the virtual frame because constants use the // We currently spill the virtual frame because constants use the
// potentially unsafe direct-frame access of SlotOperand. // potentially unsafe direct-frame access of SlotOperand.
VirtualFrame::SpilledScope spilled_scope(this); VirtualFrame::SpilledScope spilled_scope;
Comment cmnt(masm_, "[ Load const"); Comment cmnt(masm_, "[ Load const");
JumpTarget exit; JumpTarget exit;
__ mov(ecx, SlotOperand(slot, ecx)); __ mov(ecx, SlotOperand(slot, ecx));
...@@ -3465,7 +3465,7 @@ void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { ...@@ -3465,7 +3465,7 @@ void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) {
// We spill the frame in the code below because the direct-frame // We spill the frame in the code below because the direct-frame
// access of SlotOperand is potentially unsafe with an unspilled // access of SlotOperand is potentially unsafe with an unspilled
// frame. // frame.
VirtualFrame::SpilledScope spilled_scope(this); VirtualFrame::SpilledScope spilled_scope;
Comment cmnt(masm_, "[ Init const"); Comment cmnt(masm_, "[ Init const");
__ mov(ecx, SlotOperand(slot, ecx)); __ mov(ecx, SlotOperand(slot, ecx));
__ cmp(ecx, Factory::the_hole_value()); __ cmp(ecx, Factory::the_hole_value());
......
This diff is collapsed.
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define V8_IA32_VIRTUAL_FRAME_IA32_H_ #define V8_IA32_VIRTUAL_FRAME_IA32_H_
#include "register-allocator.h" #include "register-allocator.h"
#include "scopes.h"
namespace v8 { namespace internal { namespace v8 { namespace internal {
...@@ -50,37 +51,39 @@ class VirtualFrame : public ZoneObject { ...@@ -50,37 +51,39 @@ class VirtualFrame : public ZoneObject {
// generator is being transformed. // generator is being transformed.
class SpilledScope BASE_EMBEDDED { class SpilledScope BASE_EMBEDDED {
public: public:
explicit SpilledScope(CodeGenerator* cgen) SpilledScope() : previous_state_(cgen()->in_spilled_code()) {
: cgen_(cgen), ASSERT(cgen()->has_valid_frame());
previous_state_(cgen->in_spilled_code()) { cgen()->frame()->SpillAll();
ASSERT(cgen->has_valid_frame()); cgen()->set_in_spilled_code(true);
cgen->frame()->SpillAll();
cgen->set_in_spilled_code(true);
} }
~SpilledScope() { ~SpilledScope() {
cgen_->set_in_spilled_code(previous_state_); cgen()->set_in_spilled_code(previous_state_);
} }
private: private:
CodeGenerator* cgen_;
bool previous_state_; bool previous_state_;
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
}; };
// An illegal index into the virtual frame. // An illegal index into the virtual frame.
static const int kIllegalIndex = -1; static const int kIllegalIndex = -1;
// Construct an initial virtual frame on entry to a JS function. // Construct an initial virtual frame on entry to a JS function.
explicit VirtualFrame(CodeGenerator* cgen); VirtualFrame();
// Construct a virtual frame as a clone of an existing one. // Construct a virtual frame as a clone of an existing one.
explicit VirtualFrame(VirtualFrame* original); explicit VirtualFrame(VirtualFrame* original);
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
MacroAssembler* masm() { return cgen()->masm(); }
// Create a duplicate of an existing valid frame element. // Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index); FrameElement CopyElementAt(int index);
// The height of the virtual expression stack. // The height of the virtual expression stack.
int height() const { int height() {
return elements_.length() - expression_base_index(); return elements_.length() - expression_base_index();
} }
...@@ -153,7 +156,7 @@ class VirtualFrame : public ZoneObject { ...@@ -153,7 +156,7 @@ class VirtualFrame : public ZoneObject {
// registers. Used when the code generator's frame is switched from this // registers. Used when the code generator's frame is switched from this
// one to NULL by an unconditional jump. // one to NULL by an unconditional jump.
void DetachFromCodeGenerator() { void DetachFromCodeGenerator() {
RegisterAllocator* cgen_allocator = cgen_->allocator(); RegisterAllocator* cgen_allocator = cgen()->allocator();
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i)) { if (is_used(i)) {
Register temp = { i }; Register temp = { i };
...@@ -167,7 +170,7 @@ class VirtualFrame : public ZoneObject { ...@@ -167,7 +170,7 @@ class VirtualFrame : public ZoneObject {
// Used when a code generator's frame is switched from NULL to this one by // Used when a code generator's frame is switched from NULL to this one by
// binding a label. // binding a label.
void AttachToCodeGenerator() { void AttachToCodeGenerator() {
RegisterAllocator* cgen_allocator = cgen_->allocator(); RegisterAllocator* cgen_allocator = cgen()->allocator();
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i)) { if (is_used(i)) {
Register temp = { i }; Register temp = { i };
...@@ -189,7 +192,7 @@ class VirtualFrame : public ZoneObject { ...@@ -189,7 +192,7 @@ class VirtualFrame : public ZoneObject {
void PrepareForReturn(); void PrepareForReturn();
// Allocate and initialize the frame-allocated locals. // Allocate and initialize the frame-allocated locals.
void AllocateStackSlots(int count); void AllocateStackSlots();
// An element of the expression stack as an assembly operand. // An element of the expression stack as an assembly operand.
Operand ElementAt(int index) const { Operand ElementAt(int index) const {
...@@ -215,9 +218,9 @@ class VirtualFrame : public ZoneObject { ...@@ -215,9 +218,9 @@ class VirtualFrame : public ZoneObject {
} }
// A frame-allocated local as an assembly operand. // A frame-allocated local as an assembly operand.
Operand LocalAt(int index) const { Operand LocalAt(int index) {
ASSERT(0 <= index); ASSERT(0 <= index);
ASSERT(index < local_count_); ASSERT(index < local_count());
return Operand(ebp, kLocal0Offset - index * kPointerSize); return Operand(ebp, kLocal0Offset - index * kPointerSize);
} }
...@@ -253,10 +256,10 @@ class VirtualFrame : public ZoneObject { ...@@ -253,10 +256,10 @@ class VirtualFrame : public ZoneObject {
void RestoreContextRegister(); void RestoreContextRegister();
// A parameter as an assembly operand. // A parameter as an assembly operand.
Operand ParameterAt(int index) const { Operand ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver. ASSERT(-1 <= index); // -1 is the receiver.
ASSERT(index < parameter_count_); ASSERT(index <= parameter_count());
return Operand(ebp, (1 + parameter_count_ - index) * kPointerSize); return Operand(ebp, (1 + parameter_count() - index) * kPointerSize);
} }
// Push a copy of the value of a parameter frame slot on top of the frame. // Push a copy of the value of a parameter frame slot on top of the frame.
...@@ -278,7 +281,7 @@ class VirtualFrame : public ZoneObject { ...@@ -278,7 +281,7 @@ class VirtualFrame : public ZoneObject {
} }
// The receiver frame slot. // The receiver frame slot.
Operand Receiver() const { return ParameterAt(-1); } Operand Receiver() { return ParameterAt(-1); }
// Push a try-catch or try-finally handler on top of the virtual frame. // Push a try-catch or try-finally handler on top of the virtual frame.
void PushTryHandler(HandlerType type); void PushTryHandler(HandlerType type);
...@@ -395,59 +398,50 @@ class VirtualFrame : public ZoneObject { ...@@ -395,59 +398,50 @@ class VirtualFrame : public ZoneObject {
static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
CodeGenerator* cgen_;
MacroAssembler* masm_;
ZoneList<FrameElement> elements_; ZoneList<FrameElement> elements_;
// The number of frame-allocated locals and parameters respectively.
int parameter_count_;
int local_count_;
// The index of the element that is at the processor's stack pointer // The index of the element that is at the processor's stack pointer
// (the esp register). // (the esp register).
int stack_pointer_; int stack_pointer_;
// The index of the element that is at the processor's frame pointer
// (the ebp register).
int frame_pointer_;
// The index of the register frame element using each register, or // The index of the register frame element using each register, or
// kIllegalIndex if a register is not on the frame. // kIllegalIndex if a register is not on the frame.
int register_locations_[kNumRegisters]; int register_locations_[kNumRegisters];
// The number of frame-allocated locals and parameters respectively.
int parameter_count() { return cgen()->scope()->num_parameters(); }
int local_count() { return cgen()->scope()->num_stack_slots(); }
// The index of the element that is at the processor's frame pointer
// (the ebp register). The parameters, receiver, and return address
// are below the frame pointer.
int frame_pointer() { return parameter_count() + 2; }
// The index of the first parameter. The receiver lies below the first // The index of the first parameter. The receiver lies below the first
// parameter. // parameter.
int param0_index() const { return 1; } int param0_index() { return 1; }
// The index of the context slot in the frame. // The index of the context slot in the frame. It is immediately
int context_index() const { // above the frame pointer.
ASSERT(frame_pointer_ != kIllegalIndex); int context_index() { return frame_pointer() + 1; }
return frame_pointer_ + 1;
}
// The index of the function slot in the frame. It lies above the context // The index of the function slot in the frame. It is above the frame
// slot. // pointer and the context slot.
int function_index() const { int function_index() { return frame_pointer() + 2; }
ASSERT(frame_pointer_ != kIllegalIndex);
return frame_pointer_ + 2;
}
// The index of the first local. Between the parameters and the locals // The index of the first local. Between the frame pointer and the
// lie the return address, the saved frame pointer, the context, and the // locals lie the context and the function.
// function. int local0_index() { return frame_pointer() + 3; }
int local0_index() const {
ASSERT(frame_pointer_ != kIllegalIndex);
return frame_pointer_ + 3;
}
// The index of the base of the expression stack. // The index of the base of the expression stack.
int expression_base_index() const { return local0_index() + local_count_; } int expression_base_index() { return local0_index() + local_count(); }
// Convert a frame index into a frame pointer relative offset into the // Convert a frame index into a frame pointer relative offset into the
// actual stack. // actual stack.
int fp_relative(int index) const { int fp_relative(int index) {
return (frame_pointer_ - index) * kPointerSize; ASSERT(index < elements_.length());
ASSERT(frame_pointer() < elements_.length()); // FP is on the frame.
return (frame_pointer() - index) * kPointerSize;
} }
// Record an occurrence of a register in the virtual frame. This has the // Record an occurrence of a register in the virtual frame. This has the
...@@ -456,7 +450,7 @@ class VirtualFrame : public ZoneObject { ...@@ -456,7 +450,7 @@ class VirtualFrame : public ZoneObject {
void Use(Register reg, int index) { void Use(Register reg, int index) {
ASSERT(!is_used(reg)); ASSERT(!is_used(reg));
register_locations_[reg.code()] = index; register_locations_[reg.code()] = index;
cgen_->allocator()->Use(reg); cgen()->allocator()->Use(reg);
} }
// Record that a register reference has been dropped from the frame. This // Record that a register reference has been dropped from the frame. This
...@@ -465,7 +459,7 @@ class VirtualFrame : public ZoneObject { ...@@ -465,7 +459,7 @@ class VirtualFrame : public ZoneObject {
void Unuse(Register reg) { void Unuse(Register reg) {
ASSERT(register_locations_[reg.code()] != kIllegalIndex); ASSERT(register_locations_[reg.code()] != kIllegalIndex);
register_locations_[reg.code()] = kIllegalIndex; register_locations_[reg.code()] = kIllegalIndex;
cgen_->allocator()->Unuse(reg); cgen()->allocator()->Unuse(reg);
} }
// Spill the element at a particular index---write it to memory if // Spill the element at a particular index---write it to memory if
...@@ -545,6 +539,7 @@ class VirtualFrame : public ZoneObject { ...@@ -545,6 +539,7 @@ class VirtualFrame : public ZoneObject {
friend class JumpTarget; friend class JumpTarget;
}; };
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_IA32_VIRTUAL_FRAME_IA32_H_ #endif // V8_IA32_VIRTUAL_FRAME_IA32_H_
...@@ -121,7 +121,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -121,7 +121,7 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// Build the new frame. A freshly allocated frame has memory elements // Build the new frame. A freshly allocated frame has memory elements
// for the parameters and some platform-dependent elements (e.g., // for the parameters and some platform-dependent elements (e.g.,
// return address). Replace those first. // return address). Replace those first.
entry_frame_ = new VirtualFrame(cgen()); entry_frame_ = new VirtualFrame();
int index = 0; int index = 0;
for (; index < entry_frame_->elements_.length(); index++) { for (; index < entry_frame_->elements_.length(); index++) {
FrameElement* target = elements[index]; FrameElement* target = elements[index];
...@@ -215,10 +215,6 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) { ...@@ -215,10 +215,6 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
} }
} }
// Fill in the other fields of the entry frame.
entry_frame_->local_count_ = initial_frame->local_count_;
entry_frame_->frame_pointer_ = initial_frame->frame_pointer_;
// The stack pointer is at the highest synced element or the base of // The stack pointer is at the highest synced element or the base of
// the expression stack. // the expression stack.
int stack_pointer = length - 1; int stack_pointer = length - 1;
......
...@@ -37,13 +37,8 @@ namespace v8 { namespace internal { ...@@ -37,13 +37,8 @@ namespace v8 { namespace internal {
// When cloned, a frame is a deep copy of the original. // When cloned, a frame is a deep copy of the original.
VirtualFrame::VirtualFrame(VirtualFrame* original) VirtualFrame::VirtualFrame(VirtualFrame* original)
: cgen_(original->cgen_), : elements_(original->elements_),
masm_(original->masm_), stack_pointer_(original->stack_pointer_) {
elements_(original->elements_),
parameter_count_(original->parameter_count_),
local_count_(original->local_count_),
stack_pointer_(original->stack_pointer_),
frame_pointer_(original->frame_pointer_) {
// Copy register locations from original. // Copy register locations from original.
memcpy(&register_locations_, memcpy(&register_locations_,
original->register_locations_, original->register_locations_,
...@@ -118,7 +113,7 @@ void VirtualFrame::ForgetElements(int count) { ...@@ -118,7 +113,7 @@ void VirtualFrame::ForgetElements(int count) {
// A hack to properly count register references for the code // A hack to properly count register references for the code
// generator's current frame and also for other frames. The // generator's current frame and also for other frames. The
// same code appears in PrepareMergeTo. // same code appears in PrepareMergeTo.
if (cgen_->frame() == this) { if (cgen()->frame() == this) {
Unuse(last.reg()); Unuse(last.reg());
} else { } else {
register_locations_[last.reg().code()] = kIllegalIndex; register_locations_[last.reg().code()] = kIllegalIndex;
...@@ -133,10 +128,10 @@ Register VirtualFrame::SpillAnyRegister() { ...@@ -133,10 +128,10 @@ Register VirtualFrame::SpillAnyRegister() {
// Find the leftmost (ordered by register code) register whose only // Find the leftmost (ordered by register code) register whose only
// reference is in the frame. // reference is in the frame.
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i) && cgen_->allocator()->count(i) == 1) { if (is_used(i) && cgen()->allocator()->count(i) == 1) {
Register result = { i }; Register result = { i };
Spill(result); Spill(result);
ASSERT(!cgen_->allocator()->is_used(result)); ASSERT(!cgen()->allocator()->is_used(result));
return result; return result;
} }
} }
...@@ -200,7 +195,7 @@ void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) { ...@@ -200,7 +195,7 @@ void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) {
// If the frame is the code generator's current frame, we have // If the frame is the code generator's current frame, we have
// to decrement both the frame-internal and global register // to decrement both the frame-internal and global register
// counts. // counts.
if (cgen_->frame() == this) { if (cgen()->frame() == this) {
Unuse(source.reg()); Unuse(source.reg());
} else { } else {
register_locations_[source.reg().code()] = kIllegalIndex; register_locations_[source.reg().code()] = kIllegalIndex;
...@@ -369,14 +364,6 @@ void VirtualFrame::Nip(int num_dropped) { ...@@ -369,14 +364,6 @@ void VirtualFrame::Nip(int num_dropped) {
bool VirtualFrame::Equals(VirtualFrame* other) { bool VirtualFrame::Equals(VirtualFrame* other) {
#ifdef DEBUG #ifdef DEBUG
// These are sanity checks in debug builds, but we do not need to
// use them to distinguish frames at merge points.
if (cgen_ != other->cgen_) return false;
if (masm_ != other->masm_) return false;
if (parameter_count_ != other->parameter_count_) return false;
if (local_count_ != other->local_count_) return false;
if (frame_pointer_ != other->frame_pointer_) return false;
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (register_locations_[i] != other->register_locations_[i]) { if (register_locations_[i] != other->register_locations_[i]) {
return false; return false;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#define V8_X64_VIRTUAL_FRAME_X64_H_ #define V8_X64_VIRTUAL_FRAME_X64_H_
#include "register-allocator.h" #include "register-allocator.h"
#include "scopes.h"
namespace v8 { namespace internal { namespace v8 { namespace internal {
...@@ -50,37 +51,39 @@ class VirtualFrame : public ZoneObject { ...@@ -50,37 +51,39 @@ class VirtualFrame : public ZoneObject {
// generator is being transformed. // generator is being transformed.
class SpilledScope BASE_EMBEDDED { class SpilledScope BASE_EMBEDDED {
public: public:
explicit SpilledScope(CodeGenerator* cgen) SpilledScope() : previous_state_(cgen()->in_spilled_code()) {
: cgen_(cgen), ASSERT(cgen()->has_valid_frame());
previous_state_(cgen->in_spilled_code()) { cgen()->frame()->SpillAll();
ASSERT(cgen->has_valid_frame()); cgen()->set_in_spilled_code(true);
cgen->frame()->SpillAll();
cgen->set_in_spilled_code(true);
} }
~SpilledScope() { ~SpilledScope() {
cgen_->set_in_spilled_code(previous_state_); cgen()->set_in_spilled_code(previous_state_);
} }
private: private:
CodeGenerator* cgen_;
bool previous_state_; bool previous_state_;
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
}; };
// An illegal index into the virtual frame. // An illegal index into the virtual frame.
static const int kIllegalIndex = -1; static const int kIllegalIndex = -1;
// Construct an initial virtual frame on entry to a JS function. // Construct an initial virtual frame on entry to a JS function.
explicit VirtualFrame(CodeGenerator* cgen); VirtualFrame();
// Construct a virtual frame as a clone of an existing one. // Construct a virtual frame as a clone of an existing one.
explicit VirtualFrame(VirtualFrame* original); explicit VirtualFrame(VirtualFrame* original);
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
MacroAssembler* masm() { return cgen()->masm(); }
// Create a duplicate of an existing valid frame element. // Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index); FrameElement CopyElementAt(int index);
// The height of the virtual expression stack. // The height of the virtual expression stack.
int height() const { int height() {
return elements_.length() - expression_base_index(); return elements_.length() - expression_base_index();
} }
...@@ -153,7 +156,7 @@ class VirtualFrame : public ZoneObject { ...@@ -153,7 +156,7 @@ class VirtualFrame : public ZoneObject {
// registers. Used when the code generator's frame is switched from this // registers. Used when the code generator's frame is switched from this
// one to NULL by an unconditional jump. // one to NULL by an unconditional jump.
void DetachFromCodeGenerator() { void DetachFromCodeGenerator() {
RegisterAllocator* cgen_allocator = cgen_->allocator(); RegisterAllocator* cgen_allocator = cgen()->allocator();
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i)) { if (is_used(i)) {
Register temp = { i }; Register temp = { i };
...@@ -167,7 +170,7 @@ class VirtualFrame : public ZoneObject { ...@@ -167,7 +170,7 @@ class VirtualFrame : public ZoneObject {
// Used when a code generator's frame is switched from NULL to this one by // Used when a code generator's frame is switched from NULL to this one by
// binding a label. // binding a label.
void AttachToCodeGenerator() { void AttachToCodeGenerator() {
RegisterAllocator* cgen_allocator = cgen_->allocator(); RegisterAllocator* cgen_allocator = cgen()->allocator();
for (int i = 0; i < kNumRegisters; i++) { for (int i = 0; i < kNumRegisters; i++) {
if (is_used(i)) { if (is_used(i)) {
Register temp = { i }; Register temp = { i };
...@@ -189,7 +192,7 @@ class VirtualFrame : public ZoneObject { ...@@ -189,7 +192,7 @@ class VirtualFrame : public ZoneObject {
void PrepareForReturn(); void PrepareForReturn();
// Allocate and initialize the frame-allocated locals. // Allocate and initialize the frame-allocated locals.
void AllocateStackSlots(int count); void AllocateStackSlots();
// An element of the expression stack as an assembly operand. // An element of the expression stack as an assembly operand.
Operand ElementAt(int index) const { Operand ElementAt(int index) const {
...@@ -215,9 +218,9 @@ class VirtualFrame : public ZoneObject { ...@@ -215,9 +218,9 @@ class VirtualFrame : public ZoneObject {
} }
// A frame-allocated local as an assembly operand. // A frame-allocated local as an assembly operand.
Operand LocalAt(int index) const { Operand LocalAt(int index) {
ASSERT(0 <= index); ASSERT(0 <= index);
ASSERT(index < local_count_); ASSERT(index < local_count());
return Operand(rbp, kLocal0Offset - index * kPointerSize); return Operand(rbp, kLocal0Offset - index * kPointerSize);
} }
...@@ -253,10 +256,10 @@ class VirtualFrame : public ZoneObject { ...@@ -253,10 +256,10 @@ class VirtualFrame : public ZoneObject {
void RestoreContextRegister(); void RestoreContextRegister();
// A parameter as an assembly operand. // A parameter as an assembly operand.
Operand ParameterAt(int index) const { Operand ParameterAt(int index) {
ASSERT(-1 <= index); // -1 is the receiver. ASSERT(-1 <= index); // -1 is the receiver.
ASSERT(index < parameter_count_); ASSERT(index < parameter_count());
return Operand(rbp, (1 + parameter_count_ - index) * kPointerSize); return Operand(rbp, (1 + parameter_count() - index) * kPointerSize);
} }
// Push a copy of the value of a parameter frame slot on top of the frame. // Push a copy of the value of a parameter frame slot on top of the frame.
...@@ -278,7 +281,7 @@ class VirtualFrame : public ZoneObject { ...@@ -278,7 +281,7 @@ class VirtualFrame : public ZoneObject {
} }
// The receiver frame slot. // The receiver frame slot.
Operand Receiver() const { return ParameterAt(-1); } Operand Receiver() { return ParameterAt(-1); }
// Push a try-catch or try-finally handler on top of the virtual frame. // Push a try-catch or try-finally handler on top of the virtual frame.
void PushTryHandler(HandlerType type); void PushTryHandler(HandlerType type);
...@@ -395,59 +398,50 @@ class VirtualFrame : public ZoneObject { ...@@ -395,59 +398,50 @@ class VirtualFrame : public ZoneObject {
static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
CodeGenerator* cgen_;
MacroAssembler* masm_;
ZoneList<FrameElement> elements_; ZoneList<FrameElement> elements_;
// The number of frame-allocated locals and parameters respectively.
int parameter_count_;
int local_count_;
// The index of the element that is at the processor's stack pointer // The index of the element that is at the processor's stack pointer
// (the esp register). // (the esp register).
int stack_pointer_; int stack_pointer_;
// The index of the element that is at the processor's frame pointer
// (the ebp register).
int frame_pointer_;
// The index of the register frame element using each register, or // The index of the register frame element using each register, or
// kIllegalIndex if a register is not on the frame. // kIllegalIndex if a register is not on the frame.
int register_locations_[kNumRegisters]; int register_locations_[kNumRegisters];
// The number of frame-allocated locals and parameters respectively.
int parameter_count() { return cgen()->scope()->num_parameters(); }
int local_count() { return cgen()->scope()->num_stack_slots(); }
// The index of the element that is at the processor's frame pointer
// (the ebp register). The parameters, receiver, and return address
// are below the frame pointer.
int frame_pointer() { return parameter_count() + 2; }
// The index of the first parameter. The receiver lies below the first // The index of the first parameter. The receiver lies below the first
// parameter. // parameter.
int param0_index() const { return 1; } int param0_index() const { return 1; }
// The index of the context slot in the frame. // The index of the context slot in the frame. It is immediately
int context_index() const { // above the frame pointer.
ASSERT(frame_pointer_ != kIllegalIndex); int context_index() { return frame_pointer() + 1; }
return frame_pointer_ + 1;
}
// The index of the function slot in the frame. It lies above the context // The index of the function slot in the frame. It is above the frame
// slot. // pointer and the context slot.
int function_index() const { int function_index() { return frame_pointer() + 2; }
ASSERT(frame_pointer_ != kIllegalIndex);
return frame_pointer_ + 2;
}
// The index of the first local. Between the parameters and the locals // The index of the first local. Between the frame pointer and the
// lie the return address, the saved frame pointer, the context, and the // locals lie the context and the function.
// function. int local0_index() { return frame_pointer() + 3; }
int local0_index() const {
ASSERT(frame_pointer_ != kIllegalIndex);
return frame_pointer_ + 3;
}
// The index of the base of the expression stack. // The index of the base of the expression stack.
int expression_base_index() const { return local0_index() + local_count_; } int expression_base_index() { return local0_index() + local_count(); }
// Convert a frame index into a frame pointer relative offset into the // Convert a frame index into a frame pointer relative offset into the
// actual stack. // actual stack.
int fp_relative(int index) const { int fp_relative(int index) {
return (frame_pointer_ - index) * kPointerSize; ASSERT(index < elements_.length());
ASSERT(frame_pointer() < elements_.length()); // FP is on the frame.
return (frame_pointer() - index) * kPointerSize;
} }
// Record an occurrence of a register in the virtual frame. This has the // Record an occurrence of a register in the virtual frame. This has the
...@@ -456,7 +450,7 @@ class VirtualFrame : public ZoneObject { ...@@ -456,7 +450,7 @@ class VirtualFrame : public ZoneObject {
void Use(Register reg, int index) { void Use(Register reg, int index) {
ASSERT(!is_used(reg)); ASSERT(!is_used(reg));
register_locations_[reg.code()] = index; register_locations_[reg.code()] = index;
cgen_->allocator()->Use(reg); cgen()->allocator()->Use(reg);
} }
// Record that a register reference has been dropped from the frame. This // Record that a register reference has been dropped from the frame. This
...@@ -465,7 +459,7 @@ class VirtualFrame : public ZoneObject { ...@@ -465,7 +459,7 @@ class VirtualFrame : public ZoneObject {
void Unuse(Register reg) { void Unuse(Register reg) {
ASSERT(register_locations_[reg.code()] != kIllegalIndex); ASSERT(register_locations_[reg.code()] != kIllegalIndex);
register_locations_[reg.code()] = kIllegalIndex; register_locations_[reg.code()] = kIllegalIndex;
cgen_->allocator()->Unuse(reg); cgen()->allocator()->Unuse(reg);
} }
// Spill the element at a particular index---write it to memory if // Spill the element at a particular index---write it to memory if
...@@ -545,6 +539,7 @@ class VirtualFrame : public ZoneObject { ...@@ -545,6 +539,7 @@ class VirtualFrame : public ZoneObject {
friend class JumpTarget; friend class JumpTarget;
}; };
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_X64_VIRTUAL_FRAME_X64_H_ #endif // V8_X64_VIRTUAL_FRAME_X64_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment