| Index: runtime/vm/code_patcher_ia32.cc
|
| diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
|
| index 08c7caf03b2ac44ea8bf3d027643369ed5393084..95d64e08e59c73a8175017f3b67af494df5627e5 100644
|
| --- a/runtime/vm/code_patcher_ia32.cc
|
| +++ b/runtime/vm/code_patcher_ia32.cc
|
| @@ -44,6 +44,8 @@ class UnoptimizedCall : public ValueObject {
|
| void set_target(uword target) const {
|
| uword* target_addr = reinterpret_cast<uword*>(call_address() + 1);
|
| uword offset = target - return_address();
|
| + WritableInstructionsScope writable(reinterpret_cast<uword>(target_addr),
|
| + sizeof(offset));
|
| *target_addr = offset;
|
| CPU::FlushICache(call_address(), kInstructionSize);
|
| }
|
| @@ -64,11 +66,33 @@ class UnoptimizedCall : public ValueObject {
|
| return start_ + 1 * kInstructionSize;
|
| }
|
|
|
| + protected:
|
| uword start_;
|
| +
|
| + private:
|
| DISALLOW_IMPLICIT_CONSTRUCTORS(UnoptimizedCall);
|
| };
|
|
|
|
|
| +class NativeCall : public UnoptimizedCall {
|
| + public:
|
| + explicit NativeCall(uword return_address) : UnoptimizedCall(return_address) {
|
| + }
|
| +
|
| + NativeFunction native_function() const {
|
| + return *reinterpret_cast<NativeFunction*>(start_ + 1);
|
| + }
|
| +
|
| + void set_native_function(NativeFunction func) const {
|
| + WritableInstructionsScope writable(start_ + 1, sizeof(func));
|
| + *reinterpret_cast<NativeFunction*>(start_ + 1) = func;
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(NativeCall);
|
| +};
|
| +
|
| +
|
| class InstanceCall : public UnoptimizedCall {
|
| public:
|
| explicit InstanceCall(uword return_address)
|
| @@ -210,6 +234,28 @@ 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);
|
| + 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);
|
| + *target = call.native_function();
|
| + return call.target();
|
| +}
|
| +
|
| +
|
| +
|
| intptr_t CodePatcher::InstanceCallSizeInBytes() {
|
| return InstanceCall::kNumInstructions * InstanceCall::kInstructionSize;
|
| }
|
|
|