Commit ba16099e authored by whesse@chromium.org's avatar whesse@chromium.org

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
parent aa81281b
...@@ -290,14 +290,9 @@ void VirtualFrame::PushReceiverSlotAddress() { ...@@ -290,14 +290,9 @@ void VirtualFrame::PushReceiverSlotAddress() {
} }
// Before changing an element which is copied, adjust so that the int VirtualFrame::InvalidateFrameSlotAt(int index) {
// 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) {
UNIMPLEMENTED(); UNIMPLEMENTED();
return FrameElement::InvalidElement(); return kIllegalIndex;
} }
......
...@@ -440,13 +440,12 @@ class VirtualFrame : public Malloced { ...@@ -440,13 +440,12 @@ class VirtualFrame : public Malloced {
// should be equal. // should be equal.
void MergeMoveMemoryToRegisters(VirtualFrame* expected); void MergeMoveMemoryToRegisters(VirtualFrame* expected);
// Helper function to implement the copy-on-write semantics of an // Invalidates a frame slot (puts an invalid frame element in it).
// element's copies just before writing to the element. The copies // Copies on the frame are correctly handled, and if this slot was
// are updated, but the element is not changed. A copy of the new // the backing store of copies, the index of the new backing store
// backing store of all the copies is returned if there were any // is returned. Otherwise, returns kIllegalIndex.
// copies and in invalid frame element is returned if there were no // Register counts are correctly updated.
// copies. int InvalidateFrameSlotAt(int index);
FrameElement AdjustCopies(int index);
// Call a code stub that has already been prepared for calling (via // Call a code stub that has already been prepared for calling (via
// PrepareForCall). // PrepareForCall).
......
...@@ -498,63 +498,57 @@ void VirtualFrame::PushReceiverSlotAddress() { ...@@ -498,63 +498,57 @@ void VirtualFrame::PushReceiverSlotAddress() {
} }
// Before changing an element which is copied, adjust so that the int VirtualFrame::InvalidateFrameSlotAt(int index) {
// 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) {
FrameElement original = elements_[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()) { // Is this element the backing store of any copies?
// There was a first copy. Make it the new backing element. int new_backing_index = kIllegalIndex;
Register backing_reg; if (original.is_copied()) {
if (original.is_memory()) { // Verify it is copied, and find first copy.
Result fresh = cgen_->allocator()->Allocate(); for (int i = index + 1; i < elements_.length(); i++) {
ASSERT(fresh.is_valid()); if (elements_[i].is_copy() && elements_[i].index() == index) {
backing_reg = fresh.reg(); new_backing_index = i;
__ mov(backing_reg, Operand(ebp, fp_relative(index))); break;
} 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;
} }
} }
}
copy.clear_sync(); if (new_backing_index == kIllegalIndex) {
return copy; // No copies found, return kIllegalIndex.
if (original.is_register()) {
Unuse(original.reg());
}
elements_[index] = FrameElement::InvalidElement();
return kIllegalIndex;
} }
elements_[index].clear_copied(); // This is the backing store of copies.
return FrameElement::InvalidElement(); 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) { ...@@ -562,73 +556,38 @@ void VirtualFrame::TakeFrameSlotAt(int index) {
ASSERT(index >= 0); ASSERT(index >= 0);
ASSERT(index <= elements_.length()); ASSERT(index <= elements_.length());
FrameElement original = elements_[index]; 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()) { switch (original.type()) {
case FrameElement::INVALID:
UNREACHABLE();
break;
case FrameElement::MEMORY: { case FrameElement::MEMORY: {
// Allocate the element to a register. If it is not copied, // Emit code to load the original element's data into a register.
// push that register on top of the frame. If it is copied, // Push that register as a FrameElement on top of the frame.
// make the first copy the backing store and push a fresh copy Result fresh = cgen_->allocator()->Allocate();
// on top of the frame. ASSERT(fresh.is_valid());
FrameElement copy = original.is_copied() FrameElement new_element =
? AdjustCopies(index) FrameElement::RegisterElement(fresh.reg(),
: FrameElement::InvalidElement(); FrameElement::NOT_SYNCED);
if (copy.is_valid()) { Use(fresh.reg());
// The original element was a copy. Push the copy of the new elements_.Add(new_element);
// backing store. __ mov(fresh.reg(), Operand(ebp, fp_relative(index)));
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)));
}
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; break;
} }
case FrameElement::REGISTER:
Use(original.reg());
// Fall through.
case FrameElement::CONSTANT: case FrameElement::CONSTANT:
original.clear_sync();
elements_.Add(original);
break;
case FrameElement::COPY: case FrameElement::COPY:
original.clear_sync(); original.clear_sync();
elements_.Add(original); elements_.Add(original);
break; break;
case FrameElement::INVALID:
UNREACHABLE();
break;
} }
elements_[index] = FrameElement::InvalidElement();
} }
...@@ -639,23 +598,14 @@ void VirtualFrame::StoreToFrameSlotAt(int index) { ...@@ -639,23 +598,14 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
ASSERT(index >= 0); ASSERT(index >= 0);
ASSERT(index < elements_.length()); 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; int top_index = elements_.length() - 1;
FrameElement top = elements_[top_index]; FrameElement top = elements_[top_index];
FrameElement original = elements_[index];
if (top.is_copy() && top.index() == index) return;
ASSERT(top.is_valid()); ASSERT(top.is_valid());
InvalidateFrameSlotAt(index);
if (top.is_copy()) { if (top.is_copy()) {
// There are two cases based on the relative positions of the // There are two cases based on the relative positions of the
// stored-to slot and the backing slot of the top element. // stored-to slot and the backing slot of the top element.
...@@ -707,16 +657,11 @@ void VirtualFrame::StoreToFrameSlotAt(int index) { ...@@ -707,16 +657,11 @@ void VirtualFrame::StoreToFrameSlotAt(int index) {
// All the copies of the old backing element (including the top // All the copies of the old backing element (including the top
// element) become copies of the new backing element. // element) become copies of the new backing element.
for (int i = backing_index + 1; i < elements_.length(); i++) { for (int i = backing_index + 1; i < elements_.length(); i++) {
FrameElement current = elements_[i]; if (elements_[i].is_copy() && elements_[i].index() == backing_index) {
if (current.is_copy() && current.index() == backing_index) { elements_[i].set_index(index);
elements_[i] = new_element;
if (current.is_synced()) {
elements_[i].set_sync();
}
} }
} }
} }
return; return;
} }
......
...@@ -435,13 +435,12 @@ class VirtualFrame : public Malloced { ...@@ -435,13 +435,12 @@ class VirtualFrame : public Malloced {
// should be equal. // should be equal.
void MergeMoveMemoryToRegisters(VirtualFrame* expected); void MergeMoveMemoryToRegisters(VirtualFrame* expected);
// Helper function to implement the copy-on-write semantics of an // Invalidates a frame slot (puts an invalid frame element in it).
// element's copies just before writing to the element. The copies // Copies on the frame are correctly handled, and if this slot was
// are updated, but the element is not changed. A copy of the new // the backing store of copies, the index of the new backing store
// backing store of all the copies is returned if there were any // is returned. Otherwise, returns kIllegalIndex.
// copies and in invalid frame element is returned if there were no // Register counts are correctly updated.
// copies. int InvalidateFrameSlotAt(int index);
FrameElement AdjustCopies(int index);
// Call a code stub that has already been prepared for calling (via // Call a code stub that has already been prepared for calling (via
// PrepareForCall). // PrepareForCall).
......
...@@ -375,17 +375,7 @@ void VirtualFrame::SetElementAt(int index, Result* value) { ...@@ -375,17 +375,7 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
return; return;
} }
// If the original may be a copy, adjust to preserve the copy-on-write InvalidateFrameSlotAt(frame_index);
// 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());
}
FrameElement new_element; FrameElement new_element;
if (value->is_register()) { if (value->is_register()) {
...@@ -400,9 +390,9 @@ void VirtualFrame::SetElementAt(int index, Result* value) { ...@@ -400,9 +390,9 @@ void VirtualFrame::SetElementAt(int index, Result* value) {
for (int i = 0; i < elements_.length(); i++) { for (int i = 0; i < elements_.length(); i++) {
FrameElement element = elements_[i]; FrameElement element = elements_[i];
if (element.is_register() && element.reg().is(value->reg())) { 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) { if (i < frame_index) {
// The register backing store is lower in the frame than its
// copy.
elements_[frame_index] = CopyElementAt(i); elements_[frame_index] = CopyElementAt(i);
} else { } else {
// There was an early bailout for the case of setting a // There was an early bailout for the case of setting a
......
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