Change VirtualFrame::AdjustCopies to mark target as invalid.

Change its name to VirtualFrame::InvalidateFrameSlot
Review URL: http://codereview.chromium.org/50012

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1575 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2009-03-23 13:37:55 +00:00
parent aa81281b3d
commit ba16099e40
5 changed files with 89 additions and 161 deletions

View File

@ -290,14 +290,9 @@ void VirtualFrame::PushReceiverSlotAddress() {
}
// Before changing an element which is copied, adjust so that the
// first copy becomes the new backing store and all the other copies
// are updated. If the original was in memory, the new backing store
// is allocated to a register. Return a copy of the new backing store
// or an invalid element if the original was not a copy.
FrameElement VirtualFrame::AdjustCopies(int index) {
int VirtualFrame::InvalidateFrameSlotAt(int index) {
UNIMPLEMENTED();
return FrameElement::InvalidElement();
return kIllegalIndex;
}

View File

@ -440,13 +440,12 @@ class VirtualFrame : public Malloced {
// should be equal.
void MergeMoveMemoryToRegisters(VirtualFrame* expected);
// Helper function to implement the copy-on-write semantics of an
// element's copies just before writing to the element. The copies
// are updated, but the element is not changed. A copy of the new
// backing store of all the copies is returned if there were any
// copies and in invalid frame element is returned if there were no
// copies.
FrameElement AdjustCopies(int index);
// Invalidates a frame slot (puts an invalid frame element in it).
// Copies on the frame are correctly handled, and if this slot was
// the backing store of copies, the index of the new backing store
// is returned. Otherwise, returns kIllegalIndex.
// Register counts are correctly updated.
int InvalidateFrameSlotAt(int index);
// Call a code stub that has already been prepared for calling (via
// PrepareForCall).

View File

@ -498,63 +498,57 @@ void VirtualFrame::PushReceiverSlotAddress() {
}
// Before changing an element which is copied, adjust so that the
// first copy becomes the new backing store and all the other copies
// are updated. If the original was in memory, the new backing store
// is allocated to a register. Return a copy of the new backing store
// or an invalid element if the original was not a copy.
FrameElement VirtualFrame::AdjustCopies(int index) {
int VirtualFrame::InvalidateFrameSlotAt(int index) {
FrameElement original = elements_[index];
ASSERT(original.is_memory() || original.is_register());
// Go looking for a first copy above index.
int i = index + 1;
while (i < elements_.length()) {
FrameElement elt = elements_[i];
if (elt.is_copy() && elt.index() == index) break;
i++;
}
if (i < elements_.length()) {
// There was a first copy. Make it the new backing element.
Register backing_reg;
if (original.is_memory()) {
Result fresh = cgen_->allocator()->Allocate();
ASSERT(fresh.is_valid());
backing_reg = fresh.reg();
__ mov(backing_reg, Operand(ebp, fp_relative(index)));
} else {
// The original was in a register.
backing_reg = original.reg();
}
FrameElement new_backing_element =
FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED);
if (elements_[i].is_synced()) {
new_backing_element.set_sync();
}
Use(backing_reg);
elements_[i] = new_backing_element;
// Update the other copies.
FrameElement copy = CopyElementAt(i);
for (int j = i; j < elements_.length(); j++) {
FrameElement elt = elements_[j];
if (elt.is_copy() && elt.index() == index) {
if (elt.is_synced()) {
copy.set_sync();
} else {
copy.clear_sync();
}
elements_[j] = copy;
// Is this element the backing store of any copies?
int new_backing_index = kIllegalIndex;
if (original.is_copied()) {
// Verify it is copied, and find first copy.
for (int i = index + 1; i < elements_.length(); i++) {
if (elements_[i].is_copy() && elements_[i].index() == index) {
new_backing_index = i;
break;
}
}
copy.clear_sync();
return copy;
}
elements_[index].clear_copied();
return FrameElement::InvalidElement();
if (new_backing_index == kIllegalIndex) {
// No copies found, return kIllegalIndex.
if (original.is_register()) {
Unuse(original.reg());
}
elements_[index] = FrameElement::InvalidElement();
return kIllegalIndex;
}
// This is the backing store of copies.
Register backing_reg;
if (original.is_memory()) {
Result fresh = cgen_->allocator()->Allocate();
ASSERT(fresh.is_valid());
Use(fresh.reg());
backing_reg = fresh.reg();
__ mov(backing_reg, Operand(ebp, fp_relative(index)));
} else {
// The original was in a register.
backing_reg = original.reg();
}
if (elements_[new_backing_index].is_synced()) {
elements_[new_backing_index] =
FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED);
} else {
elements_[new_backing_index] =
FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED);
}
// Update the other copies.
for (int i = new_backing_index + 1; i < elements_.length(); i++) {
if (elements_[i].is_copy() && elements_[i].index() == index) {
elements_[i].set_index(new_backing_index);
elements_[new_backing_index].set_copied();
}
}
return new_backing_index;
}
@ -562,73 +556,38 @@ void VirtualFrame::TakeFrameSlotAt(int index) {
ASSERT(index >= 0);
ASSERT(index <= elements_.length());
FrameElement original = elements_[index];
int new_backing_store_index = InvalidateFrameSlotAt(index);
if (new_backing_store_index != kIllegalIndex) {
elements_.Add(CopyElementAt(new_backing_store_index));
return;
}
switch (original.type()) {
case FrameElement::INVALID:
UNREACHABLE();
break;
case FrameElement::MEMORY: {
// Allocate the element to a register. If it is not copied,
// push that register on top of the frame. If it is copied,
// make the first copy the backing store and push a fresh copy
// on top of the frame.
FrameElement copy = original.is_copied()
? AdjustCopies(index)
: FrameElement::InvalidElement();
if (copy.is_valid()) {
// The original element was a copy. Push the copy of the new
// backing store.
elements_.Add(copy);
} else {
// The element was not a copy. Move it to a register and push
// that.
Result fresh = cgen_->allocator()->Allocate();
ASSERT(fresh.is_valid());
FrameElement new_element =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED);
Use(fresh.reg());
elements_.Add(new_element);
__ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
}
// Emit code to load the original element's data into a register.
// Push that register as a FrameElement on top of the frame.
Result fresh = cgen_->allocator()->Allocate();
ASSERT(fresh.is_valid());
FrameElement new_element =
FrameElement::RegisterElement(fresh.reg(),
FrameElement::NOT_SYNCED);
Use(fresh.reg());
elements_.Add(new_element);
__ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
break;
}
case FrameElement::REGISTER: {
// If the element is not copied, push it on top of the frame.
// If it is copied, make the first copy be the new backing store
// and push a fresh copy on top of the frame.
FrameElement copy = original.is_copied()
? AdjustCopies(index)
: FrameElement::InvalidElement();
if (copy.is_valid()) {
// The original element was a copy. Push the copy of the new
// backing store.
elements_.Add(copy);
// This is the only case where we have to unuse the original
// register. The original is still counted and so is the new
// backing store of the copies.
Unuse(original.reg());
} else {
// The element was not a copy. Push it.
original.clear_sync();
elements_.Add(original);
}
break;
}
case FrameElement::REGISTER:
Use(original.reg());
// Fall through.
case FrameElement::CONSTANT:
original.clear_sync();
elements_.Add(original);
break;
case FrameElement::COPY:
original.clear_sync();
elements_.Add(original);
break;
case FrameElement::INVALID:
UNREACHABLE();
break;
}
elements_[index] = FrameElement::InvalidElement();
}
@ -639,23 +598,14 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
ASSERT(index >= 0);
ASSERT(index < elements_.length());
FrameElement original = elements_[index];
// If the stored-to slot may be copied, adjust to preserve the
// copy-on-write semantics of copied elements.
if (original.is_copied() &&
(original.is_register() || original.is_memory())) {
FrameElement ignored = AdjustCopies(index);
}
// If the stored-to slot is a register reference, deallocate it.
if (original.is_register()) {
Unuse(original.reg());
}
int top_index = elements_.length() - 1;
FrameElement top = elements_[top_index];
FrameElement original = elements_[index];
if (top.is_copy() && top.index() == index) return;
ASSERT(top.is_valid());
InvalidateFrameSlotAt(index);
if (top.is_copy()) {
// There are two cases based on the relative positions of the
// stored-to slot and the backing slot of the top element.
@ -707,16 +657,11 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
// All the copies of the old backing element (including the top
// element) become copies of the new backing element.
for (int i = backing_index + 1; i < elements_.length(); i++) {
FrameElement current = elements_[i];
if (current.is_copy() && current.index() == backing_index) {
elements_[i] = new_element;
if (current.is_synced()) {
elements_[i].set_sync();
}
if (elements_[i].is_copy() && elements_[i].index() == backing_index) {
elements_[i].set_index(index);
}
}
}
return;
}

View File

@ -435,13 +435,12 @@ class VirtualFrame : public Malloced {
// should be equal.
void MergeMoveMemoryToRegisters(VirtualFrame* expected);
// Helper function to implement the copy-on-write semantics of an
// element's copies just before writing to the element. The copies
// are updated, but the element is not changed. A copy of the new
// backing store of all the copies is returned if there were any
// copies and in invalid frame element is returned if there were no
// copies.
FrameElement AdjustCopies(int index);
// Invalidates a frame slot (puts an invalid frame element in it).
// Copies on the frame are correctly handled, and if this slot was
// the backing store of copies, the index of the new backing store
// is returned. Otherwise, returns kIllegalIndex.
// Register counts are correctly updated.
int InvalidateFrameSlotAt(int index);
// Call a code stub that has already been prepared for calling (via
// PrepareForCall).

View File

@ -375,17 +375,7 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
return;
}
// If the original may be a copy, adjust to preserve the copy-on-write
// semantics of copied elements.
if (original.is_copied() &&
(original.is_register() || original.is_memory())) {
FrameElement ignored = AdjustCopies(frame_index);
}
// If the original is a register reference, deallocate it.
if (original.is_register()) {
Unuse(original.reg());
}
InvalidateFrameSlotAt(frame_index);
FrameElement new_element;
if (value->is_register()) {
@ -400,9 +390,9 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
for (int i = 0; i < elements_.length(); i++) {
FrameElement element = elements_[i];
if (element.is_register() && element.reg().is(value->reg())) {
// The register backing store is lower in the frame than its
// copy.
if (i < frame_index) {
// The register backing store is lower in the frame than its
// copy.
elements_[frame_index] = CopyElementAt(i);
} else {
// There was an early bailout for the case of setting a