}
bool Equals(FrameElement other) {
- if (value_ == other.value_) return true;
-
- if (type() != other.type() ||
- is_copied() != other.is_copied() ||
- is_synced() != other.is_synced() ||
- !(static_type() == other.static_type())) {
- return false;
+ uint32_t masked_difference = (value_ ^ other.value_) & ~CopiedField::mask();
+ if (!masked_difference) {
+ // The elements are equal if they agree exactly except on copied field.
+ return true;
+ } else {
+ // If two constants have the same value, and agree otherwise, return true.
+ return !(masked_difference & ~DataField::mask()) &&
+ is_constant() &&
+ handle().is_identical_to(other.handle());
}
+ }
- if (is_register()) {
- if (!reg().is(other.reg())) return false;
- } else if (is_constant()) {
- if (!handle().is_identical_to(other.handle())) return false;
- } else if (is_copy()) {
- if (index() != other.index()) return false;
+ // Test if two FrameElements refer to the same memory or register location.
+ bool SameLocation(FrameElement* other) {
+ if (type() == other->type()) {
+ if (value_ == other->value_) return true;
+ if (is_constant() && handle().is_identical_to(other->handle())) {
+ return true;
+ }
}
-
- return true;
+ return false;
}
// Given a pair of non-null frame element pointers, return one of them
if (!is_valid()) return this;
if (!other->is_valid()) return other;
- // If they do not have the exact same location we reallocate.
- bool not_same_location =
- (type() != other->type()) ||
- (is_register() && !reg().is(other->reg())) ||
- (is_constant() && !handle().is_identical_to(other->handle())) ||
- (is_copy() && index() != other->index());
- if (not_same_location) return NULL;
-
+ if (!SameLocation(other)) return NULL;
// If either is unsynced, the result is. The result static type is
// the merge of the static types. It's safe to set it on one of the
// frame elements, and harmless too (because we are only going to
ASSERT(mergable_elements <= elements_.length());
int start_index = elements_.length() - mergable_elements;
-
- // The is_copied flags on entry frame elements are expected to be
- // exact. Set them for the elements below the water mark.
- for (int i = 0; i < start_index; i++) {
- elements_[i].clear_copied();
- if (elements_[i].is_copy()) {
- elements_[elements_[i].index()].set_copied();
- }
- }
-
for (int i = start_index; i < elements_.length(); i++) {
FrameElement element = elements_[i];
MergeMoveRegistersToRegisters(expected);
MergeMoveMemoryToRegisters(expected);
- // Fix any sync flag problems from the bottom-up and make the copied
- // flags exact. This assumes that the backing store of copies is
- // always lower in the frame.
- for (int i = 0; i < elements_.length(); i++) {
- FrameElement source = elements_[i];
- FrameElement target = expected->elements_[i];
- if (source.is_synced() && !target.is_synced()) {
- elements_[i].clear_sync();
- } else if (!source.is_synced() && target.is_synced()) {
- SyncElementAt(i);
- }
- elements_[i].clear_copied();
- if (elements_[i].is_copy()) {
- elements_[elements_[i].index()].set_copied();
- }
- }
-
// Adjust the stack pointer downward if necessary.
if (stack_pointer_ > expected->stack_pointer_) {
int difference = stack_pointer_ - expected->stack_pointer_;
// of the index of the frame element esi is caching or kIllegalIndex
// if esi has not been disturbed.
int esi_caches = kIllegalIndex;
- // 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);
- for (int i = start; i >= 0; i--) {
+ for (int i = elements_.length() - 1; i >= 0; i--) {
FrameElement target = expected->elements_[i];
+ if (target.is_register()) continue; // Handle registers later.
if (target.is_memory()) {
FrameElement source = elements_[i];
switch (source.type()) {
}
break;
}
- elements_[i] = target;
}
+ elements_[i] = target;
}
if (esi_caches != kIllegalIndex) {
void VirtualFrame::MergeMoveMemoryToRegisters(VirtualFrame* expected) {
// Move memory, constants, and copies to registers. This is the
- // final step and is done from the bottom up so that the backing
+ // final step and since it is not done from the bottom up, but in
+ // register code order, we have special code to ensure that the backing
// elements of copies are in their correct locations when we
// encounter the copies.
for (int i = 0; i < kNumRegisters; i++) {
FrameElement source = elements_[index];
FrameElement target = expected->elements_[index];
Register target_reg = { i };
- ASSERT(expected->elements_[index].reg().is(target_reg));
+ ASSERT(target.reg().is(target_reg));
switch (source.type()) {
case FrameElement::INVALID: // Fall through.
UNREACHABLE();