Merge "ART: Hot fix for an inliner issue"
diff --git a/compiler/optimizing/register_allocator.cc b/compiler/optimizing/register_allocator.cc
index 2fbd051..a02b1da 100644
--- a/compiler/optimizing/register_allocator.cc
+++ b/compiler/optimizing/register_allocator.cc
@@ -1422,7 +1422,6 @@
: Location::StackSlot(interval->GetParent()->GetSpillSlot()));
}
UsePosition* use = current->GetFirstUse();
- SafepointPosition* safepoint_position = interval->GetFirstSafepoint();
// Walk over all siblings, updating locations of use positions, and
// connecting them when they are adjacent.
@@ -1473,11 +1472,10 @@
InsertParallelMoveAt(current->GetEnd(), interval->GetDefinedBy(), source, destination);
}
- for (; safepoint_position != nullptr; safepoint_position = safepoint_position->GetNext()) {
- if (!current->Covers(safepoint_position->GetPosition())) {
- DCHECK(next_sibling != nullptr);
- break;
- }
+ for (SafepointPosition* safepoint_position = current->GetFirstSafepoint();
+ safepoint_position != nullptr;
+ safepoint_position = safepoint_position->GetNext()) {
+ DCHECK(current->Covers(safepoint_position->GetPosition()));
LocationSummary* locations = safepoint_position->GetLocations();
if ((current->GetType() == Primitive::kPrimNot) && current->GetParent()->HasSpillSlot()) {
@@ -1523,7 +1521,6 @@
} while (current != nullptr);
if (kIsDebugBuild) {
- DCHECK(safepoint_position == nullptr);
// Following uses can only be environment uses. The location for
// these environments will be none.
while (use != nullptr) {
diff --git a/compiler/optimizing/ssa_liveness_analysis.h b/compiler/optimizing/ssa_liveness_analysis.h
index 2b51f94..98f98a2 100644
--- a/compiler/optimizing/ssa_liveness_analysis.h
+++ b/compiler/optimizing/ssa_liveness_analysis.h
@@ -492,6 +492,15 @@
return defined_by_;
}
+ SafepointPosition* FindSafepointJustBefore(size_t position) const {
+ for (SafepointPosition* safepoint = first_safepoint_, *previous = nullptr;
+ safepoint != nullptr;
+ previous = safepoint, safepoint = safepoint->GetNext()) {
+ if (safepoint->GetPosition() >= position) return previous;
+ }
+ return last_safepoint_;
+ }
+
/**
* Split this interval at `position`. This interval is changed to:
* [start ... position).
@@ -510,6 +519,19 @@
}
LiveInterval* new_interval = new (allocator_) LiveInterval(allocator_, type_);
+ SafepointPosition* new_last_safepoint = FindSafepointJustBefore(position);
+ if (new_last_safepoint == nullptr) {
+ new_interval->first_safepoint_ = first_safepoint_;
+ new_interval->last_safepoint_ = last_safepoint_;
+ first_safepoint_ = last_safepoint_ = nullptr;
+ } else if (last_safepoint_ != new_last_safepoint) {
+ new_interval->last_safepoint_ = last_safepoint_;
+ new_interval->first_safepoint_ = new_last_safepoint->GetNext();
+ DCHECK(new_interval->first_safepoint_ != nullptr);
+ last_safepoint_ = new_last_safepoint;
+ last_safepoint_->SetNext(nullptr);
+ }
+
new_interval->next_sibling_ = next_sibling_;
next_sibling_ = new_interval;
new_interval->parent_ = parent_;
@@ -748,7 +770,6 @@
}
SafepointPosition* GetFirstSafepoint() const {
- DCHECK_EQ(GetParent(), this) << "Only the first sibling lists safepoints";
return first_safepoint_;
}
@@ -822,7 +843,7 @@
LiveRange* first_range_;
LiveRange* last_range_;
- // Safepoints where this interval is live. Only set in the parent interval.
+ // Safepoints where this interval is live.
SafepointPosition* first_safepoint_;
SafepointPosition* last_safepoint_;