| 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);
|
|
|