Index: runtime/vm/flow_graph_compiler.cc |
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc |
index 55add2450e04d880b06938a28cc4d9eec7e2d342..085707fb7e48b0dd78dd85be63bc82a6f57647a3 100644 |
--- a/runtime/vm/flow_graph_compiler.cc |
+++ b/runtime/vm/flow_graph_compiler.cc |
@@ -79,7 +79,7 @@ RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
for (intptr_t i = current->Length() - 1; |
i >= current->fixed_parameter_count(); |
i--) { |
- builder->AddCopy(current->LocationAt(i), slot_ix++); |
+ builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++); |
} |
// PC marker and caller FP. |
@@ -98,14 +98,18 @@ RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
// The values of outgoing arguments can be changed from the inlined call so |
// we must read them from the previous environment. |
for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { |
- builder->AddCopy(previous->LocationAt(i), slot_ix++); |
+ builder->AddCopy(previous->ValueAt(i), |
+ previous->LocationAt(i), |
+ slot_ix++); |
} |
// Set the locals, note that outgoing arguments are not in the environment. |
for (intptr_t i = current->Length() - 1; |
i >= current->fixed_parameter_count(); |
i--) { |
- builder->AddCopy(current->LocationAt(i), slot_ix++); |
+ builder->AddCopy(current->ValueAt(i), |
+ current->LocationAt(i), |
+ slot_ix++); |
} |
// PC marker and caller FP. |
@@ -124,7 +128,7 @@ RawDeoptInfo* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler, |
// For the outermost environment, set the incoming arguments. |
for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) { |
- builder->AddCopy(previous->LocationAt(i), slot_ix++); |
+ builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++); |
} |
const DeoptInfo& deopt_info = DeoptInfo::Handle(builder->CreateDeoptInfo()); |
@@ -416,7 +420,7 @@ void FlowGraphCompiler::RecordSafepoint(LocationSummary* locs) { |
// FPU registers have the highest register number at the highest |
// address (i.e., first in the stackmap). |
const intptr_t kFpuRegisterSpillFactor = |
- FlowGraphAllocator::kFpuRegisterSpillFactor; |
+ kFpuRegisterSize / kWordSize; |
for (intptr_t i = kNumberOfFpuRegisters - 1; i >= 0; --i) { |
FpuRegister reg = static_cast<FpuRegister>(i); |
if (regs->ContainsFpuRegister(reg)) { |
@@ -944,6 +948,99 @@ void ParallelMoveResolver::PerformMove(int index) { |
} |
+bool ParallelMoveResolver::IsScratchLocation(Location loc) { |
+ for (int i = 0; i < moves_.length(); ++i) { |
+ if (moves_[i]->Blocks(loc)) { |
+ return false; |
+ } |
+ } |
+ |
+ for (int i = 0; i < moves_.length(); ++i) { |
+ if (moves_[i]->dest().Equals(loc)) { |
+ return true; |
+ } |
+ } |
+ |
+ return false; |
+} |
+ |
+ |
+intptr_t ParallelMoveResolver::AllocateScratchRegister(Location::Kind kind, |
+ intptr_t blocked, |
+ intptr_t register_count, |
+ bool* spilled) { |
+ intptr_t scratch = -1; |
+ for (intptr_t reg = 0; reg < register_count; reg++) { |
+ if ((blocked != reg) && |
+ IsScratchLocation(Location::MachineRegisterLocation(kind, reg))) { |
+ scratch = reg; |
+ break; |
+ } |
+ } |
+ |
+ if (scratch == -1) { |
+ *spilled = true; |
+ for (intptr_t reg = 0; reg < register_count; reg++) { |
+ if (blocked != reg) { |
+ scratch = reg; |
+ } |
+ } |
+ } else { |
+ *spilled = false; |
+ } |
+ |
+ return scratch; |
+} |
+ |
+ |
+ParallelMoveResolver::ScratchFpuRegisterScope::ScratchFpuRegisterScope( |
+ ParallelMoveResolver* resolver, FpuRegister blocked) |
+ : resolver_(resolver), |
+ reg_(kNoFpuRegister), |
+ spilled_(false) { |
+ reg_ = static_cast<FpuRegister>( |
+ resolver_->AllocateScratchRegister(Location::kFpuRegister, |
+ blocked, |
+ kNumberOfFpuRegisters, |
+ &spilled_)); |
+ |
+ if (spilled_) { |
+ resolver->SpillFpuScratch(reg_); |
+ } |
+} |
+ |
+ |
+ParallelMoveResolver::ScratchFpuRegisterScope::~ScratchFpuRegisterScope() { |
+ if (spilled_) { |
+ resolver_->RestoreFpuScratch(reg_); |
+ } |
+} |
+ |
+ |
+ParallelMoveResolver::ScratchRegisterScope::ScratchRegisterScope( |
+ ParallelMoveResolver* resolver, Register blocked) |
+ : resolver_(resolver), |
+ reg_(kNoRegister), |
+ spilled_(false) { |
+ reg_ = static_cast<Register>( |
+ resolver_->AllocateScratchRegister(Location::kRegister, |
+ blocked, |
+ kNumberOfCpuRegisters, |
+ &spilled_)); |
+ |
+ if (spilled_) { |
+ resolver->SpillScratch(reg_); |
+ } |
+} |
+ |
+ |
+ParallelMoveResolver::ScratchRegisterScope::~ScratchRegisterScope() { |
+ if (spilled_) { |
+ resolver_->RestoreScratch(reg_); |
+ } |
+} |
+ |
+ |
intptr_t FlowGraphCompiler::ElementSizeFor(intptr_t cid) { |
if (RawObject::IsExternalTypedDataClassId(cid)) { |
return ExternalTypedData::ElementSizeInBytes(cid); |