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:
parent
efba01b86f
commit
bbd21a59fd
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user