9c4a322b08
This reverts commit 922ea3e9b6 in patchset 1, fix for assertion triggered in https://ci.chromium.org/b/8883214567628884960 in patchset 2, fix for deadlock around symbols table mutex in patchset 4.
Original commit description:
Speed up is achieved by sharing most of the dart code, object store
and class table between isolates in single isolate group. So
instead of bootstrapping isolate from the snapshot, isolate is
initialized by setting pointers to existing data structures already
set up for first isolate, and only few isolate-specific structures (moved
to newly introducted isolate_object_store) are created.
To allow for safe cross-isolate switchable call site, type test cache
mutations additional synchronization via RunWithStoppedMutators(that
relies on safepoints) was added.
Besides switchable call sites, no other mutation to the dart code is
done in AOT, which allows such sharing.
Bug: https://github.com/dart-lang/sdk/issues/37835
Bug: https://github.com/dart-lang/sdk/issues/36097
Change-Id: I655e337198214c9dfacbe76f7852b941b5a7e910
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143462
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
129 lines
5.3 KiB
C++
129 lines
5.3 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 RUNTIME_VM_CODE_PATCHER_H_
|
|
#define RUNTIME_VM_CODE_PATCHER_H_
|
|
|
|
#include "vm/allocation.h"
|
|
#include "vm/native_entry.h"
|
|
|
|
namespace dart {
|
|
|
|
// Forward declaration.
|
|
class Code;
|
|
class ICData;
|
|
class RawArray;
|
|
class RawCode;
|
|
class RawFunction;
|
|
class RawObject;
|
|
|
|
#if defined(TARGET_ARCH_IA32)
|
|
// Stack-allocated class to create a scope where the specified region
|
|
// [address, address + size] has write access enabled. This is used
|
|
// when patching generated code. Access is reset to read-execute in
|
|
// the destructor of this scope.
|
|
// Dual mapping of instructions pages is not supported on these target arch.
|
|
class WritableInstructionsScope : public ValueObject {
|
|
public:
|
|
WritableInstructionsScope(uword address, intptr_t size);
|
|
~WritableInstructionsScope();
|
|
|
|
private:
|
|
const uword address_;
|
|
const intptr_t size_;
|
|
};
|
|
#endif // defined(TARGET_ARCH_IA32)
|
|
|
|
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 the output
|
|
// parameter data if non-NULL.
|
|
static RawCode* GetInstanceCallAt(uword return_address,
|
|
const Code& caller_code,
|
|
Object* data);
|
|
|
|
// Change the state of an instance call by patching the corresponding object
|
|
// pool entries (non-IA32) or instructions (IA32).
|
|
static void PatchInstanceCallAt(uword return_address,
|
|
const Code& caller_code,
|
|
const Object& data,
|
|
const Code& target);
|
|
static void PatchInstanceCallAtWithMutatorsStopped(Thread* thread,
|
|
uword return_address,
|
|
const Code& caller_code,
|
|
const Object& data,
|
|
const Code& target);
|
|
|
|
// 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 void InsertDeoptimizationCallAt(uword start);
|
|
|
|
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 void PatchSwitchableCallAtWithMutatorsStopped(Thread* thread,
|
|
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& caller_code,
|
|
NativeFunction* target);
|
|
|
|
static void PatchNativeCallAt(uword return_address,
|
|
const Code& caller_code,
|
|
NativeFunction target,
|
|
const Code& trampoline);
|
|
|
|
static intptr_t GetSubtypeTestCachePoolIndex(uword return_address);
|
|
};
|
|
|
|
// Beginning from [end - size] we compare [size] bytes with [pattern]. All
|
|
// [0..255] values in [pattern] have to match, negative values are skipped.
|
|
//
|
|
// Example pattern: `[0x3d, 0x8b, -1, -1]`.
|
|
bool MatchesPattern(uword end, const int16_t* pattern, intptr_t size);
|
|
|
|
class KBCPatcher : public AllStatic {
|
|
public:
|
|
static NativeFunctionWrapper GetNativeCallAt(uword return_address,
|
|
const Bytecode& bytecode,
|
|
NativeFunction* function);
|
|
|
|
static void PatchNativeCallAt(uword return_address,
|
|
const Bytecode& bytecode,
|
|
NativeFunction function,
|
|
NativeFunctionWrapper trampoline);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // RUNTIME_VM_CODE_PATCHER_H_
|