Files
sdk/runtime/vm/code_patcher.h
T
Ryan Macnak 7ff2dd4117 Optimize AOT's switchable calls for the monomorphic case.
The call sequence is very similar to a classic IC call, except the guarded class and the target are loaded indirectly from the constant pool instead of as immediates. In the monomorphic case, we call directly to the expected target with a class check in the callee. In the unlinked, polymorphic and megamorphic cases, we call a stub; these case are now call-through instead of call-and-return.

Every code, except stubs involved in switchable calls, includes the class check sequence at the beginning. So we now distinguish between a checked and an unchecked entry point. Generated code except the switchable call continues to use the unchecked entry point.

PC offsets are calculated relative to the beginning of the instruction stream, rather than either entry point.

BUG=
R=fschneider@google.com

Review URL: https://codereview.chromium.org/2226893002 .
2016-08-12 11:18:35 -07:00

99 lines
3.4 KiB
C++

// Copyright (c) 2012, 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.
// Class for patching compiled code.
#ifndef VM_CODE_PATCHER_H_
#define VM_CODE_PATCHER_H_
#include "vm/allocation.h"
#include "vm/native_entry.h"
namespace dart {
// Forward declaration.
class Array;
class Code;
class ExternalLabel;
class Function;
class ICData;
class RawArray;
class RawCode;
class RawFunction;
class RawICData;
class RawObject;
class String;
// Stack-allocated class to create a scope where the specified region
// [address, addresss + size] has write access enabled. This is used
// when patching generated code. Access is reset to read-execute in
// the destructor of this scope.
class WritableInstructionsScope : public ValueObject {
public:
WritableInstructionsScope(uword address, intptr_t size);
~WritableInstructionsScope();
private:
const uword address_;
const intptr_t size_;
};
class CodePatcher : public AllStatic {
public:
// Dart static calls have a distinct, machine-dependent code pattern.
// Patch static call before return_address in given code to the new target.
static void PatchStaticCallAt(uword return_address,
const Code& code,
const Code& new_target);
// Return the target address of the static call before return_address
// in given code.
static RawCode* GetStaticCallTargetAt(uword return_address, const Code& code);
// Get instance call information. Returns the call target and sets each
// of the output parameters ic_data and arguments_descriptor if they are
// non-NULL.
static RawCode* GetInstanceCallAt(uword return_address,
const Code& code,
ICData* ic_data);
// Return target of an unoptimized static call and its ICData object
// (calls target via a stub).
static RawFunction* GetUnoptimizedStaticCallAt(uword return_address,
const Code& code,
ICData* ic_data);
static intptr_t InstanceCallSizeInBytes();
static void InsertDeoptimizationCallAt(uword start, uword target);
static void PatchPoolPointerCallAt(uword return_address,
const Code& code,
const Code& new_target);
static void PatchSwitchableCallAt(uword return_address,
const Code& caller_code,
const Object& data,
const Code& target);
static RawObject* GetSwitchableCallDataAt(uword return_address,
const Code& caller_code);
static RawCode* GetSwitchableCallTargetAt(uword return_address,
const Code& caller_code);
static RawCode* GetNativeCallAt(uword return_address,
const Code& code,
NativeFunction* target);
static void PatchNativeCallAt(uword return_address,
const Code& code,
NativeFunction target,
const Code& trampoline);
};
} // namespace dart
#endif // VM_CODE_PATCHER_H_