diff options
Diffstat (limited to 'deps/v8/src/arm/virtual-frame-arm.h')
-rw-r--r-- | deps/v8/src/arm/virtual-frame-arm.h | 198 |
1 files changed, 127 insertions, 71 deletions
diff --git a/deps/v8/src/arm/virtual-frame-arm.h b/deps/v8/src/arm/virtual-frame-arm.h index 371a23e93..ebebd534a 100644 --- a/deps/v8/src/arm/virtual-frame-arm.h +++ b/deps/v8/src/arm/virtual-frame-arm.h @@ -29,8 +29,10 @@ #define V8_ARM_VIRTUAL_FRAME_ARM_H_ #include "register-allocator.h" +#include "scopes.h" -namespace v8 { namespace internal { +namespace v8 { +namespace internal { // ------------------------------------------------------------------------- // Virtual frames @@ -41,7 +43,7 @@ namespace v8 { namespace internal { // as random access to the expression stack elements, locals, and // parameters. -class VirtualFrame : public Malloced { +class VirtualFrame : public ZoneObject { public: // A utility class to introduce a scope where the virtual frame is // expected to remain spilled. The constructor spills the code @@ -50,42 +52,66 @@ class VirtualFrame : public Malloced { // generator is being transformed. class SpilledScope BASE_EMBEDDED { public: - explicit SpilledScope(CodeGenerator* cgen); + SpilledScope() : previous_state_(cgen()->in_spilled_code()) { + ASSERT(cgen()->has_valid_frame()); + cgen()->frame()->SpillAll(); + cgen()->set_in_spilled_code(true); + } - ~SpilledScope(); + ~SpilledScope() { + 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 number of elements on the virtual frame. + int element_count() { return elements_.length(); } + // The height of the virtual expression stack. - int height() const { - return elements_.length() - expression_base_index(); + int height() { + return element_count() - expression_base_index(); + } + + int register_location(int num) { + ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters); + return register_locations_[num]; + } + + int register_location(Register reg) { + return register_locations_[RegisterAllocator::ToNumber(reg)]; } - int register_index(Register reg) { - return register_locations_[reg.code()]; + void set_register_location(Register reg, int index) { + register_locations_[RegisterAllocator::ToNumber(reg)] = index; } - bool is_used(int reg_code) { - return register_locations_[reg_code] != kIllegalIndex; + bool is_used(int num) { + ASSERT(num >= 0 && num < RegisterAllocator::kNumRegisters); + return register_locations_[num] != kIllegalIndex; } bool is_used(Register reg) { - return is_used(reg.code()); + return register_locations_[RegisterAllocator::ToNumber(reg)] + != kIllegalIndex; } // Add extra in-memory elements to the top of the frame to match an actual @@ -95,7 +121,12 @@ class VirtualFrame : public Malloced { // Forget elements from the top of the frame to match an actual frame (eg, // the frame after a runtime call). No code is emitted. - void Forget(int count); + void Forget(int count) { + ASSERT(count >= 0); + ASSERT(stack_pointer_ == element_count() - 1); + stack_pointer_ -= count; + ForgetElements(count); + } // Forget count elements from the top of the frame without adjusting // the stack pointer downward. This is used, for example, before @@ -106,7 +137,9 @@ class VirtualFrame : public Malloced { void SpillAll(); // Spill all occurrences of a specific register from the frame. - void Spill(Register reg); + void Spill(Register reg) { + if (is_used(reg)) SpillElementAt(register_location(reg)); + } // Spill all occurrences of an arbitrary register if possible. Return the // register spilled or no_reg if it was not possible to free any register @@ -127,13 +160,23 @@ class VirtualFrame : public Malloced { // tells the register allocator that it is free to use frame-internal // registers. Used when the code generator's frame is switched from this // one to NULL by an unconditional jump. - void DetachFromCodeGenerator(); + void DetachFromCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen()->allocator(); + for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { + if (is_used(i)) cgen_allocator->Unuse(i); + } + } // (Re)attach a frame to its code generator. This informs the register // allocator that the frame-internal register references are active again. // Used when a code generator's frame is switched from NULL to this one by // binding a label. - void AttachToCodeGenerator(); + void AttachToCodeGenerator() { + RegisterAllocator* cgen_allocator = cgen()->allocator(); + for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { + if (is_used(i)) cgen_allocator->Unuse(i); + } + } // Emit code for the physical JS entry and exit frame sequences. After // calling Enter, the virtual frame is ready for use; and after calling @@ -149,13 +192,13 @@ class VirtualFrame : public Malloced { 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); } @@ -165,18 +208,18 @@ class VirtualFrame : public Malloced { // Set a frame element to a constant. The index is frame-top relative. void SetElementAt(int index, Handle<Object> value) { - Result temp(value, cgen_); + Result temp(value); SetElementAt(index, &temp); } void PushElementAt(int index) { - PushFrameSlotAt(elements_.length() - index - 1); + PushFrameSlotAt(element_count() - index - 1); } // 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); } @@ -202,13 +245,13 @@ class VirtualFrame : public Malloced { 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(); @@ -218,10 +261,11 @@ class VirtualFrame : public Malloced { 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. @@ -243,14 +287,17 @@ class VirtualFrame : public Malloced { } // 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); // Call stub given the number of arguments it expects on (and // removes from) the stack. - Result CallStub(CodeStub* stub, int arg_count); + Result CallStub(CodeStub* stub, int arg_count) { + PrepareForCall(arg_count, arg_count); + return RawCallStub(stub); + } // Call stub that expects its argument in r0. The argument is given // as a result which must be the register r0. @@ -297,7 +344,7 @@ class VirtualFrame : public Malloced { void Drop() { Drop(1); } // Duplicate the top element of the frame. - void Dup() { PushFrameSlotAt(elements_.length() - 1); } + void Dup() { PushFrameSlotAt(element_count() - 1); } // Pop an element from the top of the expression stack. Returns a // Result, which may be a constant or a register. @@ -317,7 +364,15 @@ class VirtualFrame : public Malloced { void Push(Smi* value) { Push(Handle<Object>(value)); } // Pushing a result invalidates it (its contents become owned by the frame). - void Push(Result* result); + void Push(Result* result) { + if (result->is_register()) { + Push(result->reg(), result->static_type()); + } else { + ASSERT(result->is_constant()); + Push(result->handle()); + } + result->Unuse(); + } // Nip removes zero or more elements from immediately below the top // of the frame, leaving the previous top-of-frame value on top of @@ -332,70 +387,69 @@ class VirtualFrame : public Malloced { static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize; static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots. - CodeGenerator* cgen_; - MacroAssembler* masm_; - - List<FrameElement> elements_; - - // The number of frame-allocated locals and parameters respectively. - int parameter_count_; - int local_count_; + ZoneList<FrameElement> elements_; // 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]; + int register_locations_[RegisterAllocator::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 < element_count()); + ASSERT(frame_pointer() < element_count()); // FP is on the frame. + return (frame_pointer() - index) * kPointerSize; } // Record an occurrence of a register in the virtual frame. This has the // effect of incrementing the register's external reference count and // of updating the index of the register's location in the frame. - void Use(Register reg, int index); + void Use(Register reg, int index) { + ASSERT(!is_used(reg)); + set_register_location(reg, index); + cgen()->allocator()->Use(reg); + } // Record that a register reference has been dropped from the frame. This // decrements the register's external reference count and invalidates the // index of the register's location in the frame. - void Unuse(Register reg); + void Unuse(Register reg) { + ASSERT(is_used(reg)); + set_register_location(reg, kIllegalIndex); + cgen()->allocator()->Unuse(reg); + } // Spill the element at a particular index---write it to memory if // necessary, free any associated register, and forget its value if @@ -407,7 +461,7 @@ class VirtualFrame : public Malloced { // Keep the element type as register or constant, and clear the dirty bit. void SyncElementAt(int index); - // Sync the range of elements in [begin, end). + // Sync the range of elements in [begin, end] with memory. void SyncRange(int begin, int end); // Sync a single unsynced element that lies beneath or at the stack pointer. @@ -471,6 +525,8 @@ class VirtualFrame : public Malloced { bool Equals(VirtualFrame* other); + // Classes that need raw access to the elements_ array. + friend class DeferredCode; friend class JumpTarget; }; |