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 // Set the copied flags in the frame to be exact. This assumes that
// the backing store of copies is always lower in the frame. // the backing store of copies is always lower in the frame.
// Set the register counts and indices.
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
FrameElement current = entry_frame_->elements_[i];
entry_frame_->elements_[i].clear_copied(); entry_frame_->elements_[i].clear_copied();
if (entry_frame_->elements_[i].is_copy()) { if (current.is_copy()) {
int index = entry_frame_->elements_[i].index(); entry_frame_->elements_[current.index()].set_copied();
entry_frame_->elements_[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--; stack_pointer--;
} }
entry_frame_->stack_pointer_ = 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 // Record an occurrence of a register in the virtual frame. This has the
// effect of incrementing both the register's frame-internal reference // effect of incrementing the register's external reference count and
// count and its external reference count. // of updating the index of the register's location in the frame.
void Use(Register reg); void Use(Register reg, int index);
// Record that a register reference has been dropped from the frame. This // 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); void Unuse(Register reg);
// Spill the element at a particular index---write it to memory if // Spill the element at a particular index---write it to memory if

View File

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

View File

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

View File

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