Commit f5523ecc authored by erik.corry@gmail.com's avatar erik.corry@gmail.com

Split the virtual frame into heavy and light versions.

The heavy version is for x86 and x64.  The light version
is for ARM and MIPS.  Remove the elements_ array from the
virtual frame in the light version.  More simplifications
to come, followed by light register allocation.
Review URL: http://codereview.chromium.org/1164002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4272 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5b50fd70
......@@ -113,6 +113,8 @@ SOURCES = {
"""),
'arch:arm': Split("""
fast-codegen.cc
jump-target-light.cc
virtual-frame-light.cc
arm/builtins-arm.cc
arm/codegen-arm.cc
arm/constants-arm.cc
......@@ -156,6 +158,8 @@ SOURCES = {
mips/virtual-frame-mips.cc
"""),
'arch:ia32': Split("""
jump-target-heavy.cc
virtual-frame-heavy.cc
ia32/assembler-ia32.cc
ia32/builtins-ia32.cc
ia32/codegen-ia32.cc
......@@ -175,6 +179,8 @@ SOURCES = {
"""),
'arch:x64': Split("""
fast-codegen.cc
jump-target-heavy.cc
virtual-frame-heavy.cc
x64/assembler-x64.cc
x64/builtins-x64.cc
x64/codegen-x64.cc
......
......@@ -173,14 +173,7 @@ void BreakTarget::Jump() {
void BreakTarget::Jump(Result* arg) {
// On ARM we do not currently emit merge code for jumps, so we need to do
// it explicitly here. The only merging necessary is to drop extra
// statement state from the stack.
ASSERT(cgen()->has_valid_frame());
int count = cgen()->frame()->height() - expected_height_;
cgen()->frame()->Drop(count);
cgen()->frame()->Push(arg);
DoJump();
UNIMPLEMENTED();
}
......@@ -209,27 +202,7 @@ void BreakTarget::Bind() {
void BreakTarget::Bind(Result* arg) {
#ifdef DEBUG
// All the forward-reaching frames should have been adjusted at the
// jumps to this target.
for (int i = 0; i < reaching_frames_.length(); i++) {
ASSERT(reaching_frames_[i] == NULL ||
reaching_frames_[i]->height() == expected_height_ + 1);
}
#endif
// Drop leftover statement state from the frame before merging, even
// on the fall through. This is so we can bind the return target
// with state on the frame.
if (cgen()->has_valid_frame()) {
int count = cgen()->frame()->height() - expected_height_;
// On ARM we do not currently emit merge code at binding sites, so we need
// to do it explicitly here. The only merging necessary is to drop extra
// statement state from the stack.
cgen()->frame()->ForgetElements(count);
cgen()->frame()->Push(arg);
}
DoBind();
*arg = cgen()->frame()->Pop();
UNIMPLEMENTED();
}
......
......@@ -47,16 +47,6 @@ void VirtualFrame::SyncElementByPushing(int index) {
}
void VirtualFrame::SyncRange(int begin, int end) {
// All elements are in memory on ARM (ie, synced).
#ifdef DEBUG
for (int i = begin; i <= end; i++) {
ASSERT(elements_[i].is_synced());
}
#endif
}
void VirtualFrame::MergeTo(VirtualFrame* expected) {
// ARM frames are currently always in memory.
ASSERT(Equals(expected));
......@@ -270,12 +260,7 @@ void VirtualFrame::Drop(int count) {
}
// Discard elements from the virtual frame and free any registers.
for (int i = 0; i < count; i++) {
FrameElement dropped = elements_.RemoveLast();
if (dropped.is_register()) {
Unuse(dropped.reg());
}
}
element_count_ -= count;
}
......@@ -288,14 +273,14 @@ Result VirtualFrame::Pop() {
void VirtualFrame::EmitPop(Register reg) {
ASSERT(stack_pointer_ == element_count() - 1);
stack_pointer_--;
elements_.RemoveLast();
element_count_--;
__ pop(reg);
}
void VirtualFrame::EmitPush(Register reg) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement(TypeInfo::Unknown()));
element_count_++;
stack_pointer_++;
__ push(reg);
}
......
......@@ -67,12 +67,8 @@ class VirtualFrame : public ZoneObject {
CodeGenerator* cgen() { return CodeGeneratorScope::Current(); }
MacroAssembler* masm() { return cgen()->masm(); }
// Create a duplicate of an existing valid frame element.
FrameElement CopyElementAt(int index,
TypeInfo info = TypeInfo::Unknown());
// The number of elements on the virtual frame.
int element_count() { return elements_.length(); }
int element_count() { return element_count_; }
// The height of the virtual expression stack.
int height() {
......@@ -115,7 +111,7 @@ class VirtualFrame : public ZoneObject {
stack_pointer_ -= count;
// On ARM, all elements are in memory, so there is no extra bookkeeping
// (registers, copies, etc.) beyond dropping the elements.
elements_.Rewind(stack_pointer_ + 1);
element_count_ -= count;
}
// Forget count elements from the top of the frame and adjust the stack
......@@ -124,7 +120,7 @@ class VirtualFrame : public ZoneObject {
void ForgetElements(int count);
// Spill all values from the frame to memory.
void SpillAll();
inline void SpillAll();
// Spill all occurrences of a specific register from the frame.
void Spill(Register reg) {
......@@ -179,7 +175,7 @@ class VirtualFrame : public ZoneObject {
// dropping all non-locals elements in the virtual frame. This
// avoids generating unnecessary merge code when jumping to the
// shared return site. Emits code for spills.
void PrepareForReturn();
inline void PrepareForReturn();
// Number of local variables after when we use a loop for allocating.
static const int kLocalVarBound = 5;
......@@ -205,10 +201,6 @@ class VirtualFrame : public ZoneObject {
SetElementAt(index, &temp);
}
void PushElementAt(int index) {
PushFrameSlotAt(element_count() - index - 1);
}
// A frame-allocated local as an assembly operand.
MemOperand LocalAt(int index) {
ASSERT(0 <= index);
......@@ -216,11 +208,6 @@ class VirtualFrame : public ZoneObject {
return MemOperand(fp, kLocal0Offset - index * kPointerSize);
}
// Push a copy of the value of a local frame slot on top of the frame.
void PushLocalAt(int index) {
PushFrameSlotAt(local0_index() + index);
}
// Push the value of a local frame slot on top of the frame and invalidate
// the local slot. The slot should be written to before trying to read
// from it again.
......@@ -228,21 +215,12 @@ class VirtualFrame : public ZoneObject {
TakeFrameSlotAt(local0_index() + index);
}
// Store the top value on the virtual frame into a local frame slot. The
// value is left in place on top of the frame.
void StoreToLocalAt(int index) {
StoreToFrameSlotAt(local0_index() + index);
}
// Push the address of the receiver slot on the frame.
void PushReceiverSlotAddress();
// The function frame slot.
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() { return MemOperand(fp, kContextOffset); }
......@@ -261,11 +239,6 @@ class VirtualFrame : public ZoneObject {
return MemOperand(fp, (1 + parameter_count() - index) * kPointerSize);
}
// Push a copy of the value of a parameter frame slot on top of the frame.
void PushParameterAt(int index) {
PushFrameSlotAt(param0_index() + index);
}
// Push the value of a paramter frame slot on top of the frame and
// invalidate the parameter slot. The slot should be written to before
// trying to read from it again.
......@@ -323,9 +296,6 @@ class VirtualFrame : public ZoneObject {
// Drop one element.
void Drop() { Drop(1); }
// Duplicate the top element of the frame.
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.
Result Pop();
......@@ -344,21 +314,9 @@ class VirtualFrame : public ZoneObject {
void EmitPushMultiple(int count, int src_regs);
// Push an element on the virtual frame.
inline void Push(Register reg, TypeInfo info = TypeInfo::Unknown());
inline void Push(Handle<Object> value);
inline void Push(Smi* value);
// Pushing a result invalidates it (its contents become owned by the frame).
void Push(Result* result) {
if (result->is_register()) {
Push(result->reg());
} 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
// the frame. Nip(k) is equivalent to x = Pop(), Drop(k), Push(x).
......@@ -375,7 +333,8 @@ class VirtualFrame : public ZoneObject {
static const int kHandlerSize = StackHandlerConstants::kSize / kPointerSize;
static const int kPreallocatedElements = 5 + 8; // 8 expression stack slots.
ZoneList<FrameElement> elements_;
// The number of elements on the stack frame.
int element_count_;
// The index of the element that is at the processor's stack pointer
// (the sp register).
......@@ -449,19 +408,12 @@ class VirtualFrame : public ZoneObject {
// 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] with memory.
void SyncRange(int begin, int end);
// Sync a single unsynced element that lies beneath or at the stack pointer.
void SyncElementBelowStackPointer(int index);
// Sync a single unsynced element that lies just above the stack pointer.
void SyncElementByPushing(int index);
// Push a copy of a frame slot (typically a local or parameter) on top of
// the frame.
inline void PushFrameSlotAt(int index);
// Push a the value of a frame slot (typically a local or parameter) on
// top of the frame and invalidate the slot.
void TakeFrameSlotAt(int index);
......@@ -505,9 +457,8 @@ class VirtualFrame : public ZoneObject {
inline bool Equals(VirtualFrame* other);
// Classes that need raw access to the elements_ array.
friend class DeferredCode;
friend class JumpTarget;
friend class DeferredCode;
};
......
......@@ -66,38 +66,6 @@ Comment::~Comment() {
CodeGenerator* CodeGeneratorScope::top_ = NULL;
DeferredCode::DeferredCode()
: masm_(CodeGeneratorScope::Current()->masm()),
statement_position_(masm_->current_statement_position()),
position_(masm_->current_position()) {
ASSERT(statement_position_ != RelocInfo::kNoPosition);
ASSERT(position_ != RelocInfo::kNoPosition);
CodeGeneratorScope::Current()->AddDeferred(this);
#ifdef DEBUG
comment_ = "";
#endif
// Copy the register locations from the code generator's frame.
// These are the registers that will be spilled on entry to the
// deferred code and restored on exit.
VirtualFrame* frame = CodeGeneratorScope::Current()->frame();
int sp_offset = frame->fp_relative(frame->stack_pointer_);
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
int loc = frame->register_location(i);
if (loc == VirtualFrame::kIllegalIndex) {
registers_[i] = kIgnore;
} else if (frame->elements_[loc].is_synced()) {
// Needs to be restored on exit but not saved on entry.
registers_[i] = frame->fp_relative(loc) | kSyncedFlag;
} else {
int offset = frame->fp_relative(loc);
registers_[i] = (offset < sp_offset) ? kPush : offset;
}
}
}
void CodeGenerator::ProcessDeferred() {
while (!deferred_.is_empty()) {
DeferredCode* code = deferred_.RemoveLast();
......
......@@ -138,7 +138,7 @@ class VirtualFrame: public ZoneObject {
void ForgetElements(int count);
// Spill all values from the frame to memory.
void SpillAll();
inline void SpillAll();
// Spill all occurrences of a specific register from the frame.
void Spill(Register reg) {
......@@ -199,7 +199,7 @@ class VirtualFrame: public ZoneObject {
// Prepare for returning from the frame by spilling locals. This
// avoids generating unnecessary merge code when jumping to the
// shared return site. Emits code for spills.
void PrepareForReturn();
inline void PrepareForReturn();
// Number of local variables after when we use a loop for allocating.
static const int kLocalVarBound = 10;
......
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_JUMP_TARGET_HEAVY_INL_H_
#define V8_JUMP_TARGET_HEAVY_INL_H_
#include "virtual-frame-inl.h"
namespace v8 {
namespace internal {
void JumpTarget::InitializeEntryElement(int index, FrameElement* target) {
FrameElement* element = &entry_frame_->elements_[index];
element->clear_copied();
if (target->is_register()) {
entry_frame_->set_register_location(target->reg(), index);
} else if (target->is_copy()) {
entry_frame_->elements_[target->index()].set_copied();
}
if (direction_ == BIDIRECTIONAL && !target->is_copy()) {
element->set_type_info(TypeInfo::Unknown());
}
}
} } // namespace v8::internal
#endif // V8_JUMP_TARGET_HEAVY_INL_H_
This diff is collapsed.
......@@ -30,6 +30,12 @@
#include "virtual-frame-inl.h"
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
#include "jump-target-heavy-inl.h"
#else
#include "jump-target-light-inl.h"
#endif
namespace v8 {
namespace internal {
......@@ -37,19 +43,6 @@ CodeGenerator* JumpTarget::cgen() {
return CodeGeneratorScope::Current();
}
void JumpTarget::InitializeEntryElement(int index, FrameElement* target) {
FrameElement* element = &entry_frame_->elements_[index];
element->clear_copied();
if (target->is_register()) {
entry_frame_->set_register_location(target->reg(), index);
} else if (target->is_copy()) {
entry_frame_->elements_[target->index()].set_copied();
}
if (direction_ == BIDIRECTIONAL && !target->is_copy()) {
element->set_type_info(TypeInfo::Unknown());
}
}
} } // namespace v8::internal
#endif // V8_JUMP_TARGET_INL_H_
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_JUMP_TARGET_LIGHT_INL_H_
#define V8_JUMP_TARGET_LIGHT_INL_H_
#include "virtual-frame-inl.h"
namespace v8 {
namespace internal {
void JumpTarget::InitializeEntryElement(int index, FrameElement* target) {
UNIMPLEMENTED();
}
} } // namespace v8::internal
#endif // V8_JUMP_TARGET_LIGHT_INL_H_
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "v8.h"
#include "codegen-inl.h"
#include "jump-target-inl.h"
namespace v8 {
namespace internal {
void JumpTarget::Jump(Result* arg) {
UNIMPLEMENTED();
}
void JumpTarget::Branch(Condition cc, Result* arg, Hint hint) {
UNIMPLEMENTED();
}
void JumpTarget::Branch(Condition cc, Result* arg0, Result* arg1, Hint hint) {
UNIMPLEMENTED();
}
void BreakTarget::Branch(Condition cc, Result* arg, Hint hint) {
UNIMPLEMENTED();
}
void JumpTarget::Bind(Result* arg) {
UNIMPLEMENTED();
}
void JumpTarget::Bind(Result* arg0, Result* arg1) {
UNIMPLEMENTED();
}
void JumpTarget::ComputeEntryFrame() {
UNIMPLEMENTED();
}
DeferredCode::DeferredCode()
: masm_(CodeGeneratorScope::Current()->masm()),
statement_position_(masm_->current_statement_position()),
position_(masm_->current_position()) {
ASSERT(statement_position_ != RelocInfo::kNoPosition);
ASSERT(position_ != RelocInfo::kNoPosition);
CodeGeneratorScope::Current()->AddDeferred(this);
#ifdef DEBUG
comment_ = "";
#endif
// Copy the register locations from the code generator's frame.
// These are the registers that will be spilled on entry to the
// deferred code and restored on exit.
VirtualFrame* frame = CodeGeneratorScope::Current()->frame();
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
int loc = frame->register_location(i);
if (loc == VirtualFrame::kIllegalIndex) {
registers_[i] = kIgnore;
} else {
// Needs to be restored on exit but not saved on entry.
registers_[i] = frame->fp_relative(loc) | kSyncedFlag;
}
}
}
} } // namespace v8::internal
This diff is collapsed.
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_VIRTUAL_FRAME_HEAVY_INL_H_
#define V8_VIRTUAL_FRAME_HEAVY_INL_H_
#include "type-info.h"
#include "register-allocator.h"
#include "scopes.h"
namespace v8 {
namespace internal {
// On entry to a function, the virtual frame already contains the receiver,
// the parameters, and a return address. All frame elements are in memory.
VirtualFrame::VirtualFrame()
: elements_(parameter_count() + local_count() + kPreallocatedElements),
stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
for (int i = 0; i <= stack_pointer_; i++) {
elements_.Add(FrameElement::MemoryElement(TypeInfo::Unknown()));
}
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
register_locations_[i] = kIllegalIndex;
}
}
// When cloned, a frame is a deep copy of the original.
VirtualFrame::VirtualFrame(VirtualFrame* original)
: elements_(original->element_count()),
stack_pointer_(original->stack_pointer_) {
elements_.AddAll(original->elements_);
// Copy register locations from original.
memcpy(&register_locations_,
original->register_locations_,
sizeof(register_locations_));
}
void VirtualFrame::PushFrameSlotAt(int index) {
elements_.Add(CopyElementAt(index));
}
void VirtualFrame::Push(Register reg, TypeInfo info) {
if (is_used(reg)) {
int index = register_location(reg);
FrameElement element = CopyElementAt(index, info);
elements_.Add(element);
} else {
Use(reg, element_count());
FrameElement element =
FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, info);
elements_.Add(element);
}
}
void VirtualFrame::Push(Handle<Object> value) {
FrameElement element =
FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED);
elements_.Add(element);
}
bool VirtualFrame::Equals(VirtualFrame* other) {
#ifdef DEBUG
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
if (register_location(i) != other->register_location(i)) {
return false;
}
}
if (element_count() != other->element_count()) return false;
#endif
if (stack_pointer_ != other->stack_pointer_) return false;
for (int i = 0; i < element_count(); i++) {
if (!elements_[i].Equals(other->elements_[i])) return false;
}
return true;
}
void VirtualFrame::SetTypeForLocalAt(int index, TypeInfo info) {
elements_[local0_index() + index].set_type_info(info);
}
// Make the type of all elements be MEMORY.
void VirtualFrame::SpillAll() {
for (int i = 0; i < element_count(); i++) {
SpillElementAt(i);
}
}
void VirtualFrame::PrepareForReturn() {
// Spill all locals. This is necessary to make sure all locals have
// the right value when breaking at the return site in the debugger.
for (int i = 0; i < expression_base_index(); i++) {
SpillElementAt(i);
}
}
void VirtualFrame::SetTypeForParamAt(int index, TypeInfo info) {
elements_[param0_index() + index].set_type_info(info);
}
} } // namespace v8::internal
#endif // V8_VIRTUAL_FRAME_HEAVY_INL_H_
This diff is collapsed.
......@@ -30,61 +30,15 @@
#include "virtual-frame.h"
namespace v8 {
namespace internal {
// On entry to a function, the virtual frame already contains the receiver,
// the parameters, and a return address. All frame elements are in memory.
VirtualFrame::VirtualFrame()
: elements_(parameter_count() + local_count() + kPreallocatedElements),
stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
for (int i = 0; i <= stack_pointer_; i++) {
elements_.Add(FrameElement::MemoryElement(TypeInfo::Unknown()));
}
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
register_locations_[i] = kIllegalIndex;
}
}
// When cloned, a frame is a deep copy of the original.
VirtualFrame::VirtualFrame(VirtualFrame* original)
: elements_(original->element_count()),
stack_pointer_(original->stack_pointer_) {
elements_.AddAll(original->elements_);
// Copy register locations from original.
memcpy(&register_locations_,
original->register_locations_,
sizeof(register_locations_));
}
void VirtualFrame::PushFrameSlotAt(int index) {
elements_.Add(CopyElementAt(index));
}
void VirtualFrame::Push(Register reg, TypeInfo info) {
if (is_used(reg)) {
int index = register_location(reg);
FrameElement element = CopyElementAt(index, info);
elements_.Add(element);
} else {
Use(reg, element_count());
FrameElement element =
FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, info);
elements_.Add(element);
}
}
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
#include "virtual-frame-heavy-inl.h"
#else
#include "virtual-frame-light-inl.h"
#endif
void VirtualFrame::Push(Handle<Object> value) {
FrameElement element =
FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED);
elements_.Add(element);
}
namespace v8 {
namespace internal {
void VirtualFrame::Push(Smi* value) {
Push(Handle<Object> (value));
......@@ -101,35 +55,6 @@ void VirtualFrame::Nip(int num_dropped) {
SetElementAt(0, &tos);
}
bool VirtualFrame::Equals(VirtualFrame* other) {
#ifdef DEBUG
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
if (register_location(i) != other->register_location(i)) {
return false;
}
}
if (element_count() != other->element_count()) return false;
#endif
if (stack_pointer_ != other->stack_pointer_) return false;
for (int i = 0; i < element_count(); i++) {
if (!elements_[i].Equals(other->elements_[i])) return false;
}
return true;
}
void VirtualFrame::SetTypeForLocalAt(int index, TypeInfo info) {
elements_[local0_index() + index].set_type_info(info);
}
void VirtualFrame::SetTypeForParamAt(int index, TypeInfo info) {
elements_[param0_index() + index].set_type_info(info);
}
} } // namespace v8::internal
#endif // V8_VIRTUAL_FRAME_INL_H_
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_VIRTUAL_FRAME_LIGHT_INL_H_
#define V8_VIRTUAL_FRAME_LIGHT_INL_H_
#include "type-info.h"
#include "register-allocator.h"
#include "scopes.h"
namespace v8 {
namespace internal {
// On entry to a function, the virtual frame already contains the receiver,
// the parameters, and a return address. All frame elements are in memory.
VirtualFrame::VirtualFrame()
: element_count_(parameter_count() + 2),
stack_pointer_(parameter_count() + 1) {
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
register_locations_[i] = kIllegalIndex;
}
}
// When cloned, a frame is a deep copy of the original.
VirtualFrame::VirtualFrame(VirtualFrame* original)
: element_count_(original->element_count()),
stack_pointer_(original->stack_pointer_) {
memcpy(&register_locations_,
original->register_locations_,
sizeof(register_locations_));
}
void VirtualFrame::Push(Handle<Object> value) {
UNIMPLEMENTED();
}
bool VirtualFrame::Equals(VirtualFrame* other) {
#ifdef DEBUG
for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
if (register_location(i) != other->register_location(i)) {
return false;
}
}
if (element_count() != other->element_count()) return false;
#endif
if (stack_pointer_ != other->stack_pointer_) return false;
return true;
}
void VirtualFrame::SetTypeForLocalAt(int index, TypeInfo info) {
UNIMPLEMENTED();
}
// Everything is always spilled anyway.
void VirtualFrame::SpillAll() {
}
void VirtualFrame::PrepareForReturn() {
}
} } // namespace v8::internal
#endif // V8_VIRTUAL_FRAME_LIGHT_INL_H_
// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "v8.h"
#include "codegen-inl.h"
#include "register-allocator-inl.h"
#include "virtual-frame-inl.h"
namespace v8 {
namespace internal {
void VirtualFrame::Adjust(int count) {
ASSERT(count >= 0);
ASSERT(stack_pointer_ == element_count() - 1);
element_count_ += count;
stack_pointer_ += count;
}
// Make the type of the element at a given index be MEMORY.
void VirtualFrame::SpillElementAt(int index) {
UNIMPLEMENTED();
}
} } // namespace v8::internal
This diff is collapsed.
......@@ -139,7 +139,7 @@ class VirtualFrame : public ZoneObject {
void ForgetElements(int count);
// Spill all values from the frame to memory.
void SpillAll();
inline void SpillAll();
// Spill all occurrences of a specific register from the frame.
void Spill(Register reg) {
......@@ -200,7 +200,7 @@ class VirtualFrame : public ZoneObject {
// Prepare for returning from the frame by spilling locals. This
// avoids generating unnecessary merge code when jumping to the
// shared return site. Emits code for spills.
void PrepareForReturn();
inline void PrepareForReturn();
// Number of local variables after when we use a loop for allocating.
static const int kLocalVarBound = 7;
......
......@@ -276,6 +276,7 @@
'../../src/execution.h',
'../../src/factory.cc',
'../../src/factory.h',
'../../src/fast-codegen.cc',
'../../src/fast-codegen.h',
'../../src/fast-dtoa.cc',
'../../src/fast-dtoa.h',
......@@ -309,9 +310,13 @@
'../../src/ic.h',
'../../src/interpreter-irregexp.cc',
'../../src/interpreter-irregexp.h',
'../../src/jump-target-heavy-inl.h',
'../../src/jump-target-heavy.cc',
'../../src/jump-target-inl.h',
'../../src/jump-target-light-inl.h',
'../../src/jump-target-light.cc',
'../../src/jump-target.cc',
'../../src/jump-target.h',
'../../src/jump-target-inl.h',
'../../src/jsregexp.cc',
'../../src/jsregexp.h',
'../../src/list-inl.h',
......@@ -403,7 +408,11 @@
'../../src/variables.h',
'../../src/version.cc',
'../../src/version.h',
'../../src/virtual-frame-heavy-inl.h',
'../../src/virtual-frame-heavy.cc',
'../../src/virtual-frame-inl.h',
'../../src/virtual-frame-light-inl.h',
'../../src/virtual-frame-light.cc',
'../../src/virtual-frame.cc',
'../../src/virtual-frame.h',
'../../src/zone-inl.h',
......@@ -416,7 +425,10 @@
'../../src/arm',
],
'sources': [
'../../src/fast-codegen.cc',
'../../src/jump-target-light-inl.h',
'../../src/jump-target-light.cc',
'../../src/virtual-frame-light-inl.h',
'../../src/virtual-frame-light.cc',
'../../src/arm/assembler-arm-inl.h',
'../../src/arm/assembler-arm.cc',
'../../src/arm/assembler-arm.h',
......@@ -458,6 +470,10 @@
'../../src/ia32',
],
'sources': [
'../../src/jump-target-heavy-inl.h',
'../../src/jump-target-heavy.cc',
'../../src/virtual-frame-heavy-inl.h',
'../../src/virtual-frame-heavy.cc',
'../../src/ia32/assembler-ia32-inl.h',
'../../src/ia32/assembler-ia32.cc',
'../../src/ia32/assembler-ia32.h',
......@@ -489,7 +505,10 @@
'../../src/x64',
],
'sources': [
'../../src/fast-codegen.cc',
'../../src/jump-target-heavy-inl.h',
'../../src/jump-target-heavy.cc',
'../../src/virtual-frame-heavy-inl.h',
'../../src/virtual-frame-heavy.cc',
'../../src/x64/assembler-x64-inl.h',
'../../src/x64/assembler-x64.cc',
'../../src/x64/assembler-x64.h',
......
This diff is collapsed.
......@@ -600,6 +600,10 @@
RelativePath="..\..\src\jump-target-inl.h"
>
</File>
<File
RelativePath="..\..\src\jump-target-heavy-inl.h"
>
</File>
<File
RelativePath="..\..\src\jump-target.cc"
>
......@@ -608,6 +612,10 @@
RelativePath="..\..\src\ia32\jump-target-ia32.cc"
>
</File>
<File
RelativePath="..\..\src\jump-target-heavy.cc"
>
</File>
<File
RelativePath="..\..\src\jsregexp.cc"
>
......@@ -996,6 +1004,10 @@
RelativePath="..\..\src\virtual-frame-inl.h"
>
</File>
<File
RelativePath="..\..\src\virtual-frame-heavy-inl.h"
>
</File>
<File
RelativePath="..\..\src\virtual-frame.h"
>
......@@ -1012,6 +1024,10 @@
RelativePath="..\..\src\ia32\virtual-frame-ia32.cc"
>
</File>
<File
RelativePath="..\..\src\virtual-frame-heavy.cc"
>
</File>
<File
RelativePath="..\..\src\zone-inl.h"
>
......
......@@ -580,6 +580,14 @@
RelativePath="..\..\src\jump-target.h"
>
</File>
<File
RelativePath="..\..\src\jump-target-inl.h"
>
</File>
<File
RelativePath="..\..\src\jump-target-light-inl.h"
>
</File>
<File
RelativePath="..\..\src\jump-target.cc"
>
......@@ -588,6 +596,10 @@
RelativePath="..\..\src\arm\jump-target-arm.cc"
>
</File>
<File
RelativePath="..\..\src\jump-target-light.cc"
>
</File>
<File
RelativePath="..\..\src\jsregexp.cc"
>
......@@ -984,6 +996,10 @@
RelativePath="..\..\src\virtual-frame-inl.h"
>
</File>
<File
RelativePath="..\..\src\virtual-frame-light-inl.h"
>
</File>
<File
RelativePath="..\..\src\virtual-frame.h"
>
......@@ -1000,6 +1016,10 @@
RelativePath="..\..\src\arm\virtual-frame-arm.cc"
>
</File>
<File
RelativePath="..\..\src\virtual-frame-light.cc"
>
</File>
<File
RelativePath="..\..\src\zone-inl.h"
>
......
......@@ -577,6 +577,10 @@
RelativePath="..\..\src\jump-target-inl.h"
>
</File>
<File
RelativePath="..\..\src\jump-target-heavy-inl.h"
>
</File>
<File
RelativePath="..\..\src\jump-target.cc"
>
......@@ -585,6 +589,10 @@
RelativePath="..\..\src\x64\jump-target-x64.cc"
>
</File>
<File
RelativePath="..\..\src\jump-target-heavy.cc"
>
</File>
<File
RelativePath="..\..\src\jsregexp.cc"
>
......@@ -973,6 +981,10 @@
RelativePath="..\..\src\virtual-frame-inl.h"
>
</File>
<File
RelativePath="..\..\src\virtual-frame-heavy-inl.h"
>
</File>
<File
RelativePath="..\..\src\virtual-frame.h"
>
......@@ -989,6 +1001,10 @@
RelativePath="..\..\src\x64\virtual-frame-x64.cc"
>
</File>
<File
RelativePath="..\..\src\virtual-frame-heavy.cc"
>
</File>
<File
RelativePath="..\..\src\zone-inl.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