Index: src/compiler/register-allocator.cc |
diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc |
index 7b2caff60ce993125c3c877c3e92b2bd6a5ddc29..1ba456b847c765456993a6d3635fead84a34a107 100644 |
--- a/src/compiler/register-allocator.cc |
+++ b/src/compiler/register-allocator.cc |
@@ -902,6 +902,7 @@ RegisterAllocationData::RegisterAllocationData( |
fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, |
allocation_zone()), |
spill_ranges_(allocation_zone()), |
+ delayed_references_(allocation_zone()), |
assigned_registers_(nullptr), |
assigned_double_registers_(nullptr), |
virtual_register_count_(code->VirtualRegisterCount()) { |
@@ -1057,7 +1058,7 @@ InstructionOperand* ConstraintBuilder::AllocateFixed( |
TRACE("Fixed reg is tagged at %d\n", pos); |
auto instr = InstructionAt(pos); |
if (instr->HasReferenceMap()) { |
- instr->reference_map()->RecordReference(*operand); |
+ instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); |
} |
} |
return operand; |
@@ -1206,10 +1207,13 @@ void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { |
int input_vreg = cur_input->virtual_register(); |
UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); |
cur_input->set_virtual_register(second_output->virtual_register()); |
- data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); |
+ auto gap_move = data()->AddGapMove(instr_index, Instruction::END, |
+ input_copy, *cur_input); |
if (IsReference(input_vreg) && !IsReference(output_vreg)) { |
if (second->HasReferenceMap()) { |
- second->reference_map()->RecordReference(input_copy); |
+ RegisterAllocationData::DelayedReference delayed_reference = { |
+ second->reference_map(), &gap_move->source()}; |
+ data()->delayed_references().push_back(delayed_reference); |
} |
} else if (!IsReference(input_vreg) && IsReference(output_vreg)) { |
// The input is assumed to immediately have a tagged representation, |
@@ -2755,7 +2759,11 @@ bool ReferenceMapPopulator::SafePointsAreInOrder() const { |
void ReferenceMapPopulator::PopulateReferenceMaps() { |
DCHECK(SafePointsAreInOrder()); |
- |
+ // Map all delayed references. |
+ for (auto& delayed_reference : data()->delayed_references()) { |
+ delayed_reference.map->RecordReference( |
+ AllocatedOperand::cast(*delayed_reference.operand)); |
+ } |
// Iterate over all safe point positions and record a pointer |
// for all spilled live ranges at this point. |
int last_range_start = 0; |
@@ -2792,6 +2800,20 @@ void ReferenceMapPopulator::PopulateReferenceMaps() { |
if (map->instruction_position() >= start) break; |
} |
+ InstructionOperand spill_operand; |
+ if (((range->HasSpillOperand() && |
+ !range->GetSpillOperand()->IsConstant()) || |
+ range->HasSpillRange())) { |
+ if (range->HasSpillOperand()) { |
+ spill_operand = *range->GetSpillOperand(); |
+ } else { |
+ spill_operand = range->GetSpillRangeOperand(); |
+ } |
+ DCHECK(spill_operand.IsStackSlot()); |
+ DCHECK_EQ(kRepTagged, |
+ AllocatedOperand::cast(spill_operand).machine_type()); |
+ } |
+ |
// Step through the safe points to see whether they are in the range. |
for (auto it = first_it; it != reference_maps->end(); ++it) { |
auto map = *it; |
@@ -2812,21 +2834,11 @@ void ReferenceMapPopulator::PopulateReferenceMaps() { |
// Check if the live range is spilled and the safe point is after |
// the spill position. |
- if (((range->HasSpillOperand() && |
- !range->GetSpillOperand()->IsConstant()) || |
- range->HasSpillRange()) && |
+ if (!spill_operand.IsInvalid() && |
safe_point >= range->spill_start_index()) { |
TRACE("Pointer for range %d (spilled at %d) at safe point %d\n", |
range->id(), range->spill_start_index(), safe_point); |
- InstructionOperand operand; |
- if (range->HasSpillOperand()) { |
- operand = *range->GetSpillOperand(); |
- } else { |
- operand = range->GetSpillRangeOperand(); |
- } |
- DCHECK(operand.IsStackSlot()); |
- DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type()); |
- map->RecordReference(operand); |
+ map->RecordReference(AllocatedOperand::cast(spill_operand)); |
} |
if (!cur->spilled()) { |
@@ -2837,7 +2849,7 @@ void ReferenceMapPopulator::PopulateReferenceMaps() { |
auto operand = cur->GetAssignedOperand(); |
DCHECK(!operand.IsStackSlot()); |
DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type()); |
- map->RecordReference(operand); |
+ map->RecordReference(AllocatedOperand::cast(operand)); |
} |
} |
} |