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 { |