| Index: src/virtual-frame-ia32.cc
|
| ===================================================================
|
| --- src/virtual-frame-ia32.cc (revision 1574)
|
| +++ src/virtual-frame-ia32.cc (working copy)
|
| @@ -498,63 +498,57 @@
|
| }
|
|
|
|
|
| -// 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++;
|
| + // 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;
|
| + }
|
| + }
|
| }
|
|
|
| - 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();
|
| + if (new_backing_index == kIllegalIndex) {
|
| + // No copies found, return kIllegalIndex.
|
| + if (original.is_register()) {
|
| + Unuse(original.reg());
|
| }
|
| - FrameElement new_backing_element =
|
| + 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);
|
| - if (elements_[i].is_synced()) {
|
| - new_backing_element.set_sync();
|
| + }
|
| + // 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();
|
| }
|
| - 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();
|
| - return copy;
|
| }
|
| -
|
| - elements_[index].clear_copied();
|
| - return FrameElement::InvalidElement();
|
| + return new_backing_index;
|
| }
|
|
|
|
|
| @@ -562,73 +556,38 @@
|
| 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 @@
|
| 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 @@
|
| // 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;
|
| }
|
|
|
|
|