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