Add pointers to a VirtualFrame that keep track of the indexes of register

frame elements.
Review URL: http://codereview.chromium.org/53005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1593 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2009-03-24 11:52:33 +00:00
parent efba01b86f
commit bbd21a59fd
5 changed files with 58 additions and 30 deletions

View File

@ -272,11 +272,15 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
// Set the copied flags in the frame to be exact. This assumes that
// the backing store of copies is always lower in the frame.
// Set the register counts and indices.
for (int i = 0; i < length; i++) {
FrameElement current = entry_frame_->elements_[i];
entry_frame_->elements_[i].clear_copied();
if (entry_frame_->elements_[i].is_copy()) {
int index = entry_frame_->elements_[i].index();
entry_frame_->elements_[index].set_copied();
if (current.is_copy()) {
entry_frame_->elements_[current.index()].set_copied();
} else if (current.is_register()) {
entry_frame_->frame_registers_.Use(current.reg());
entry_frame_->register_locations_[current.reg().code()] = i;
}
}
@ -292,11 +296,6 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
stack_pointer--;
}
entry_frame_->stack_pointer_ = stack_pointer;
// Unuse the reserved registers---they do not actually appear in
// the entry frame.
RegisterAllocator::UnuseReserved(&frame_registers);
entry_frame_->frame_registers_ = frame_registers;
}

View File

@ -377,12 +377,13 @@ class VirtualFrame : public Malloced {
}
// Record an occurrence of a register in the virtual frame. This has the
// effect of incrementing both the register's frame-internal reference
// count and its external reference count.
void Use(Register reg);
// 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);
// Record that a register reference has been dropped from the frame. This
// decrements both the register's internal and external reference counts.
// decrements the register's external reference count and invalidates the
// index of the register's location in the frame.
void Unuse(Register reg);
// Spill the element at a particular index---write it to memory if

View File

@ -51,6 +51,9 @@ VirtualFrame::VirtualFrame(CodeGenerator* cgen)
for (int i = 0; i < parameter_count_ + 2; i++) {
elements_.Add(FrameElement::MemoryElement());
}
for (int i = 0; i < kNumRegisters; i++) {
register_locations_[i] = kIllegalIndex;
}
}
@ -325,7 +328,7 @@ void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) {
if (target.is_synced() && !source.is_synced()) {
SyncElementAt(i);
}
Use(target.reg());
Use(target.reg(), i);
Unuse(source.reg());
elements_[i] = target;
__ mov(target.reg(), source.reg());
@ -388,7 +391,7 @@ void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame *expected) {
if (target.is_synced() && !source.is_memory()) {
SyncElementAt(i);
}
Use(target.reg());
Use(target.reg(), i);
elements_[i] = target;
}
}
@ -527,12 +530,13 @@ int VirtualFrame::InvalidateFrameSlotAt(int index) {
if (original.is_memory()) {
Result fresh = cgen_->allocator()->Allocate();
ASSERT(fresh.is_valid());
Use(fresh.reg());
Use(fresh.reg(), new_backing_index);
backing_reg = fresh.reg();
__ mov(backing_reg, Operand(ebp, fp_relative(index)));
} else {
// The original was in a register.
backing_reg = original.reg();
register_locations_[backing_reg.code()] = new_backing_index;
}
if (elements_[new_backing_index].is_synced()) {
elements_[new_backing_index] =
@ -571,13 +575,13 @@ void VirtualFrame::TakeFrameSlotAt(int index) {
FrameElement new_element =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED);
Use(fresh.reg());
Use(fresh.reg(), elements_.length());
elements_.Add(new_element);
__ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
break;
}
case FrameElement::REGISTER:
Use(original.reg());
Use(original.reg(), elements_.length());
// Fall through.
case FrameElement::CONSTANT:
case FrameElement::COPY:
@ -638,11 +642,14 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
ASSERT(temp.is_valid());
__ mov(temp.reg(), Operand(ebp, fp_relative(backing_index)));
__ mov(Operand(ebp, fp_relative(index)), temp.reg());
} else if (backing_element.is_synced()) {
// If the element is a register, we will not actually move
// anything on the stack but only update the virtual frame
// element.
backing_element.clear_sync();
} else {
register_locations_[backing_element.reg().code()] = index;
if (backing_element.is_synced()) {
// If the element is a register, we will not actually move
// anything on the stack but only update the virtual frame
// element.
backing_element.clear_sync();
}
}
elements_[index] = backing_element;
@ -683,6 +690,7 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
__ mov(temp.reg(), Operand(esp, 0));
__ mov(Operand(ebp, fp_relative(index)), temp.reg());
} else if (top.is_register()) {
register_locations_[top.reg().code()] = index;
// The stored-to slot has the (unsynced) register reference and
// the top element becomes a copy. The sync state of the top is
// preserved.
@ -889,7 +897,7 @@ Result VirtualFrame::Pop() {
ASSERT(index <= stack_pointer_);
Result temp = cgen_->allocator()->Allocate();
ASSERT(temp.is_valid());
Use(temp.reg());
Use(temp.reg(), index);
FrameElement new_element =
FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED);
elements_[index] = new_element;

View File

@ -337,6 +337,10 @@ class VirtualFrame : public Malloced {
// used in the frame.
RegisterFile frame_registers_;
// 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 index of the first parameter. The receiver lies below the first
// parameter.
int param0_index() const { return 1; }
@ -372,12 +376,13 @@ class VirtualFrame : public Malloced {
}
// Record an occurrence of a register in the virtual frame. This has the
// effect of incrementing both the register's frame-internal reference
// count and its external reference count.
void Use(Register reg);
// 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);
// Record that a register reference has been dropped from the frame. This
// decrements both the register's internal and external reference counts.
// decrements the register's external reference count and invalidates the
// index of the register's location in the frame.
void Unuse(Register reg);
// Spill the element at a particular index---write it to memory if

View File

@ -63,6 +63,9 @@ VirtualFrame::VirtualFrame(VirtualFrame* original)
for (int i = 0; i < original->elements_.length(); i++) {
elements_.Add(original->elements_[i]);
}
for (int i = 0; i < kNumRegisters; i++) {
register_locations_[i] = original->register_locations_[i];
}
}
@ -150,19 +153,26 @@ void VirtualFrame::ForgetElements(int count) {
Unuse(last.reg());
} else {
frame_registers_.Unuse(last.reg());
register_locations_[last.reg().code()] = kIllegalIndex;
}
}
}
}
void VirtualFrame::Use(Register reg) {
void VirtualFrame::Use(Register reg, int index) {
ASSERT(frame_registers_.count(reg) == 0);
ASSERT(register_locations_[reg.code()] == kIllegalIndex);
register_locations_[reg.code()] = index;
frame_registers_.Use(reg);
cgen_->allocator()->Use(reg);
}
void VirtualFrame::Unuse(Register reg) {
ASSERT(frame_registers_.count(reg) == 1);
ASSERT(register_locations_[reg.code()] != kIllegalIndex);
register_locations_[reg.code()] = kIllegalIndex;
frame_registers_.Unuse(reg);
cgen_->allocator()->Unuse(reg);
}
@ -270,6 +280,7 @@ void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) {
Unuse(source.reg());
} else {
frame_registers_.Unuse(source.reg());
register_locations_[source.reg().code()] = kIllegalIndex;
}
}
elements_[i] = target;
@ -382,7 +393,7 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
// There are two cases depending no whether the register already
// occurs in the frame or not.
if (register_count(value->reg()) == 0) {
Use(value->reg());
Use(value->reg(), frame_index);
elements_[frame_index] =
FrameElement::RegisterElement(value->reg(),
FrameElement::NOT_SYNCED);
@ -408,6 +419,7 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
elements_[i].set_sync();
}
elements_[frame_index].clear_sync();
register_locations_[value->reg().code()] = frame_index;
for (int j = i + 1; j < elements_.length(); j++) {
if (elements_[j].is_copy() && elements_[j].index() == i) {
elements_[j].set_index(frame_index);
@ -487,7 +499,7 @@ Result VirtualFrame::CallCodeObject(Handle<Code> code,
void VirtualFrame::Push(Register reg) {
FrameElement new_element;
if (register_count(reg) == 0) {
Use(reg);
Use(reg, elements_.length());
new_element =
FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED);
} else {
@ -560,6 +572,9 @@ bool VirtualFrame::Equals(VirtualFrame* other) {
if (frame_registers_.count(i) != other->frame_registers_.count(i)) {
return false;
}
if (register_locations_[i] != other->register_locations_[i]) {
return false;
}
}
if (elements_.length() != other->elements_.length()) return false;
#endif