| Index: runtime/vm/code_patcher_x64.cc
|
| ===================================================================
|
| --- runtime/vm/code_patcher_x64.cc (revision 15101)
|
| +++ runtime/vm/code_patcher_x64.cc (working copy)
|
| @@ -14,7 +14,7 @@
|
|
|
| namespace dart {
|
|
|
| -// The pattern of a Dart call is:
|
| +// The pattern of a Dart instance call is:
|
| // 00: 48 bb imm64 mov RBX, immediate 1
|
| // 10: 49 ba imm64 mov R10, immediate 2
|
| // 20: 49 bb imm64 mov R11, target_address
|
| @@ -87,24 +87,13 @@
|
| };
|
|
|
|
|
| -// A Dart static call passes the function object in RBX.
|
| -class StaticCall : public DartCallPattern {
|
| - public:
|
| - explicit StaticCall(uword return_address)
|
| - : DartCallPattern(return_address) {}
|
| -
|
| - RawFunction* function() const {
|
| - Function& f = Function::Handle();
|
| - f ^= reinterpret_cast<RawObject*>(immediate_one());
|
| - return f.raw();
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
|
| -};
|
| -
|
| -
|
| // A Dart instance call passes the ic-data in RBX.
|
| +// The expected pattern of a dart instance call:
|
| +// mov RBX, ic-data
|
| +// mov R10, argument_descriptor_array
|
| +// mov R11, target_address
|
| +// call R11
|
| +// <- return address
|
| class InstanceCall : public DartCallPattern {
|
| public:
|
| explicit InstanceCall(uword return_address)
|
| @@ -121,6 +110,47 @@
|
| };
|
|
|
|
|
| +// The expected pattern of a dart static call:
|
| +// mov R10, argument_descriptor_array (10 bytes)
|
| +// mov R11, target_address (10 bytes)
|
| +// call R11 (3 bytes)
|
| +// <- return address
|
| +class StaticCall : public ValueObject {
|
| + public:
|
| + explicit StaticCall(uword return_address)
|
| + : start_(return_address - kCallPatternSize) {
|
| + ASSERT(IsValid(return_address));
|
| + ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize);
|
| + }
|
| +
|
| + static const int kCallPatternSize = 23;
|
| +
|
| + static bool IsValid(uword return_address) {
|
| + uint8_t* code_bytes =
|
| + reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
|
| + return (code_bytes[00] == 0x49) && (code_bytes[01] == 0xBA) &&
|
| + (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) &&
|
| + (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) &&
|
| + (code_bytes[22] == 0xD3);
|
| + }
|
| +
|
| + uword target() const {
|
| + return *reinterpret_cast<uword*>(start_ + 10 + 2);
|
| + }
|
| +
|
| + void set_target(uword target) const {
|
| + uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2);
|
| + *target_addr = target;
|
| + CPU::FlushICache(start_ + 10, 2 + 8);
|
| + }
|
| +
|
| + private:
|
| + uword start_;
|
| +
|
| + DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall);
|
| +};
|
| +
|
| +
|
| uword CodePatcher::GetStaticCallTargetAt(uword return_address) {
|
| StaticCall call(return_address);
|
| return call.target();
|
|
|