Files
sdk/runtime/vm/code_patcher_dbc.cc
T
Vyacheslav Egorov 655bc90489 Enable optimizer pipeline for DBC.
Most of the infrastructure is fixed to work with DBC stack layout:

- register allocator allocates DBC registers with the limitation that we allocate only 20 registers and bail out if anything needs spilling (there is no use implementing spilling on DBC because registers are memory locations themselves). We should be able to bump number of CPU registers on DBC up to 256 but this requires major surgery in some parts - so I postponed this;
- lazy deoptimization is implemented, eager deoptimization is not - because we don't emit any code that actually requires it. it's a minor change to support it once we have a target;
- stack scanning respects stack maps built by registers allocator;

We bailout from all unsupported instructions.

R=zra@google.com

Review URL: https://codereview.chromium.org/1992963002 .
2016-05-24 14:35:50 +02:00

106 lines
3.3 KiB
C++

// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/globals.h" // Needed here to get TARGET_ARCH_DBC.
#if defined(TARGET_ARCH_DBC)
#include "vm/code_patcher.h"
#include "vm/flow_graph_compiler.h"
#include "vm/instructions.h"
#include "vm/object.h"
namespace dart {
RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
const Code& code) {
ASSERT(code.ContainsInstructionAt(return_address));
CallPattern call(return_address, code);
return call.TargetCode();
}
void CodePatcher::PatchStaticCallAt(uword return_address,
const Code& code,
const Code& new_target) {
ASSERT(code.ContainsInstructionAt(return_address));
CallPattern call(return_address, code);
call.SetTargetCode(new_target);
}
void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
ASSERT(target == 0); // Always 0 on DBC.
CallPattern::InsertDeoptCallAt(start, target);
}
RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
const Code& code,
ICData* ic_data) {
ASSERT(code.ContainsInstructionAt(return_address));
CallPattern call(return_address, code);
if (ic_data != NULL) {
*ic_data = call.IcData();
}
return call.TargetCode();
}
intptr_t CodePatcher::InstanceCallSizeInBytes() {
UNREACHABLE();
return 0;
}
RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(
uword return_address, const Code& code, ICData* ic_data_result) {
ASSERT(code.ContainsInstructionAt(return_address));
CallPattern static_call(return_address, code);
ICData& ic_data = ICData::Handle();
ic_data ^= static_call.IcData();
if (ic_data_result != NULL) {
*ic_data_result = ic_data.raw();
}
return ic_data.GetTargetAt(0);
}
void CodePatcher::PatchSwitchableCallAt(uword return_address,
const Code& code,
const ICData& ic_data,
const MegamorphicCache& cache,
const Code& lookup_stub) {
ASSERT(code.ContainsInstructionAt(return_address));
SwitchableCallPattern call(return_address, code);
ASSERT(call.cache() == ic_data.raw());
call.SetLookupStub(lookup_stub);
call.SetCache(cache);
}
void CodePatcher::PatchNativeCallAt(uword return_address,
const Code& code,
NativeFunction target,
const Code& trampoline) {
ASSERT(code.ContainsInstructionAt(return_address));
NativeCallPattern call(return_address, code);
call.set_target(trampoline);
call.set_native_function(target);
}
RawCode* CodePatcher::GetNativeCallAt(uword return_address,
const Code& code,
NativeFunction* target) {
ASSERT(code.ContainsInstructionAt(return_address));
NativeCallPattern call(return_address, code);
*target = call.native_function();
return call.target();
}
} // namespace dart
#endif // defined TARGET_ARCH_DBC