Fix a failure to correctly set the static type on a frame element at a

backward jump.  The frame entering the backward block is not used, so
the this is mostly just a bookkeeping change.
Review URL: http://codereview.chromium.org/115464

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1989 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
kmillikin@chromium.org 2009-05-18 13:16:35 +00:00
parent 94879a93b0
commit a77d81c59b
5 changed files with 28 additions and 17 deletions

View File

@ -48,6 +48,7 @@ void JumpTarget::DoJump() {
if (is_bound()) {
// Backward jump. There is an expected frame to merge to.
ASSERT(direction_ == BIDIRECTIONAL);
cgen()->frame()->PrepareMergeTo(entry_frame_);
cgen()->frame()->MergeTo(entry_frame_);
cgen()->DeleteFrame();
__ jmp(&entry_label_);

View File

@ -156,7 +156,10 @@ class FrameElement BASE_EMBEDDED {
if (type() != other.type() ||
is_copied() != other.is_copied() ||
is_synced() != other.is_synced()) return false;
is_synced() != other.is_synced() ||
!(static_type() == other.static_type())) {
return false;
}
if (is_register()) {
if (!reg().is(other.reg())) return false;

View File

@ -48,6 +48,7 @@ void JumpTarget::DoJump() {
if (is_bound()) {
// Backward jump. There is an expected frame to merge to.
ASSERT(direction_ == BIDIRECTIONAL);
cgen()->frame()->PrepareMergeTo(entry_frame_);
cgen()->frame()->MergeTo(entry_frame_);
cgen()->DeleteFrame();
__ jmp(&entry_label_);

View File

@ -314,8 +314,6 @@ void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame* expected) {
// of the index of the frame element esi is caching or kIllegalIndex
// if esi has not been disturbed.
int esi_caches = kIllegalIndex;
// A "singleton" memory element.
FrameElement memory_element = FrameElement::MemoryElement();
// Loop downward from the stack pointer or the top of the frame if
// the stack pointer is floating above the frame.
int start = Min(static_cast<int>(stack_pointer_), elements_.length() - 1);
@ -370,7 +368,7 @@ void VirtualFrame::MergeMoveRegistersToMemory(VirtualFrame* expected) {
}
break;
}
elements_[i] = memory_element;
elements_[i] = target;
}
}
@ -388,28 +386,35 @@ void VirtualFrame::MergeMoveRegistersToRegisters(VirtualFrame* expected) {
// Move the right value into register i if it is currently in a register.
int index = expected->register_locations_[i];
int use_index = register_locations_[i];
// Fast check if register is unused in target or already correct
if (index != kIllegalIndex
&& index != use_index
&& elements_[index].is_register()) {
Register source = elements_[index].reg();
Register target = { i };
// Skip if register i is unused in the target or else if source is
// not a register (this is not a register-to-register move).
if (index == kIllegalIndex || !elements_[index].is_register()) continue;
Register target = { i };
Register source = elements_[index].reg();
if (index != use_index) {
if (use_index == kIllegalIndex) { // Target is currently unused.
// Copy contents of source from source to target.
// Set frame element register to target.
elements_[index].set_reg(target);
Use(target, index);
Unuse(source);
__ mov(target, source);
} else {
// Exchange contents of registers source and target.
// Nothing except the register backing use_index has changed.
elements_[use_index].set_reg(source);
elements_[index].set_reg(target);
register_locations_[target.code()] = index;
register_locations_[source.code()] = use_index;
__ xchg(source, target);
}
}
if (!elements_[index].is_synced() &&
expected->elements_[index].is_synced()) {
__ mov(Operand(ebp, fp_relative(index)), target);
}
elements_[index] = expected->elements_[index];
}
}

View File

@ -307,11 +307,12 @@ void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) {
void VirtualFrame::PrepareForReturn() {
// Spill all locals. This is necessary to make sure all locals have
// the right value when breaking at the return site in the debugger.
//
// TODO(203): It is also necessary to ensure that merging at the
// return site does not generate code to overwrite eax, where the
// return value is kept in a non-refcounted register reference.
for (int i = 0; i < expression_base_index(); i++) SpillElementAt(i);
// Set their static type to unknown so that they will match the known
// return frame.
for (int i = 0; i < expression_base_index(); i++) {
SpillElementAt(i);
elements_[i].set_static_type(StaticType::unknown());
}
}