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:
parent
94879a93b0
commit
a77d81c59b
@ -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_);
|
||||
|
@ -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;
|
||||
|
@ -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_);
|
||||
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user