| Index: runtime/vm/code_patcher_x64.cc
|
| diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
|
| index 58478bfe09c0f5160a4acb04642ea75391cad02e..e9e678d3321e5ee104ad69bbb3a167bb400babcb 100644
|
| --- a/runtime/vm/code_patcher_x64.cc
|
| +++ b/runtime/vm/code_patcher_x64.cc
|
| @@ -23,8 +23,8 @@ namespace dart {
|
| class UnoptimizedCall : public ValueObject {
|
| public:
|
| UnoptimizedCall(uword return_address, const Code& code)
|
| - : start_(return_address - kCallPatternSize),
|
| - object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
|
| + : object_pool_(ObjectPool::Handle(code.GetObjectPool())),
|
| + start_(return_address - kCallPatternSize) {
|
| ASSERT(IsValid(return_address));
|
| ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize);
|
| }
|
| @@ -40,9 +40,12 @@ class UnoptimizedCall : public ValueObject {
|
| (code_bytes[9] == 0x97);
|
| }
|
|
|
| + intptr_t argument_index() const {
|
| + return IndexFromPPLoad(start_ + 3);
|
| + }
|
| +
|
| RawObject* ic_data() const {
|
| - intptr_t index = IndexFromPPLoad(start_ + 3);
|
| - return object_pool_.ObjectAt(index);
|
| + return object_pool_.ObjectAt(argument_index());
|
| }
|
|
|
| uword target() const {
|
| @@ -56,13 +59,36 @@ class UnoptimizedCall : public ValueObject {
|
| // No need to flush the instruction cache, since the code is not modified.
|
| }
|
|
|
| + protected:
|
| + const ObjectPool& object_pool_;
|
| +
|
| private:
|
| uword start_;
|
| - const ObjectPool& object_pool_;
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
|
| };
|
|
|
|
|
| +class NativeCall : public UnoptimizedCall {
|
| + public:
|
| + NativeCall(uword return_address, const Code& code)
|
| + : UnoptimizedCall(return_address, code) {
|
| + }
|
| +
|
| + NativeFunction native_function() const {
|
| + return reinterpret_cast<NativeFunction>(
|
| + object_pool_.RawValueAt(argument_index()));
|
| + }
|
| +
|
| + void set_native_function(NativeFunction func) const {
|
| + object_pool_.SetRawValueAt(argument_index(),
|
| + reinterpret_cast<uword>(func));
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(NativeCall);
|
| +};
|
| +
|
| +
|
| class InstanceCall : public UnoptimizedCall {
|
| public:
|
| InstanceCall(uword return_address, const Code& code)
|
| @@ -211,6 +237,27 @@ RawFunction* CodePatcher::GetUnoptimizedStaticCallAt(
|
| }
|
|
|
|
|
| +void CodePatcher::PatchNativeCallAt(uword return_address,
|
| + const Code& code,
|
| + NativeFunction target,
|
| + const Code& trampoline) {
|
| + ASSERT(code.ContainsInstructionAt(return_address));
|
| + NativeCall call(return_address, code);
|
| + call.set_target(trampoline.EntryPoint());
|
| + call.set_native_function(target);
|
| +}
|
| +
|
| +
|
| +uword CodePatcher::GetNativeCallAt(uword return_address,
|
| + const Code& code,
|
| + NativeFunction* target) {
|
| + ASSERT(code.ContainsInstructionAt(return_address));
|
| + NativeCall call(return_address, code);
|
| + *target = call.native_function();
|
| + return call.target();
|
| +}
|
| +
|
| +
|
| // The expected code pattern of an edge counter in unoptimized code:
|
| // 49 8b 87 imm32 mov RAX, [PP + offset]
|
| class EdgeCounter : public ValueObject {
|
|
|