| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/code_patcher.h" | 9 #include "vm/code_patcher.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| 11 #include "vm/instructions.h" | 11 #include "vm/instructions.h" |
| 12 #include "vm/object.h" | 12 #include "vm/object.h" |
| 13 #include "vm/raw_object.h" | 13 #include "vm/raw_object.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 // The pattern of a Dart call is: | 17 // The pattern of a Dart instance call is: |
| 18 // 00: 48 bb imm64 mov RBX, immediate 1 | 18 // 00: 48 bb imm64 mov RBX, immediate 1 |
| 19 // 10: 49 ba imm64 mov R10, immediate 2 | 19 // 10: 49 ba imm64 mov R10, immediate 2 |
| 20 // 20: 49 bb imm64 mov R11, target_address | 20 // 20: 49 bb imm64 mov R11, target_address |
| 21 // 30: 41 ff d3 call R11 | 21 // 30: 41 ff d3 call R11 |
| 22 // 33: <- return_address | 22 // 33: <- return_address |
| 23 class DartCallPattern : public ValueObject { | 23 class DartCallPattern : public ValueObject { |
| 24 public: | 24 public: |
| 25 explicit DartCallPattern(uword return_address) | 25 explicit DartCallPattern(uword return_address) |
| 26 : start_(return_address - kCallPatternSize) { | 26 : start_(return_address - kCallPatternSize) { |
| 27 ASSERT(IsValid(return_address)); | 27 ASSERT(IsValid(return_address)); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 Smi& num_pos_args = Smi::Handle(); | 80 Smi& num_pos_args = Smi::Handle(); |
| 81 num_pos_args ^= args_desc.At(1); | 81 num_pos_args ^= args_desc.At(1); |
| 82 return num_args.Value() - num_pos_args.Value(); | 82 return num_args.Value() - num_pos_args.Value(); |
| 83 } | 83 } |
| 84 | 84 |
| 85 uword start_; | 85 uword start_; |
| 86 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern); | 86 DISALLOW_IMPLICIT_CONSTRUCTORS(DartCallPattern); |
| 87 }; | 87 }; |
| 88 | 88 |
| 89 | 89 |
| 90 // A Dart static call passes the function object in RBX. | |
| 91 class StaticCall : public DartCallPattern { | |
| 92 public: | |
| 93 explicit StaticCall(uword return_address) | |
| 94 : DartCallPattern(return_address) {} | |
| 95 | |
| 96 RawFunction* function() const { | |
| 97 Function& f = Function::Handle(); | |
| 98 f ^= reinterpret_cast<RawObject*>(immediate_one()); | |
| 99 return f.raw(); | |
| 100 } | |
| 101 | |
| 102 private: | |
| 103 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall); | |
| 104 }; | |
| 105 | |
| 106 | |
| 107 // A Dart instance call passes the ic-data in RBX. | 90 // A Dart instance call passes the ic-data in RBX. |
| 91 // The expected pattern of a dart instance call: |
| 92 // mov RBX, ic-data |
| 93 // mov R10, argument_descriptor_array |
| 94 // mov R11, target_address |
| 95 // call R11 |
| 96 // <- return address |
| 108 class InstanceCall : public DartCallPattern { | 97 class InstanceCall : public DartCallPattern { |
| 109 public: | 98 public: |
| 110 explicit InstanceCall(uword return_address) | 99 explicit InstanceCall(uword return_address) |
| 111 : DartCallPattern(return_address) {} | 100 : DartCallPattern(return_address) {} |
| 112 | 101 |
| 113 RawICData* ic_data() const { | 102 RawICData* ic_data() const { |
| 114 ICData& ic_data = ICData::Handle(); | 103 ICData& ic_data = ICData::Handle(); |
| 115 ic_data ^= reinterpret_cast<RawObject*>(immediate_one()); | 104 ic_data ^= reinterpret_cast<RawObject*>(immediate_one()); |
| 116 return ic_data.raw(); | 105 return ic_data.raw(); |
| 117 } | 106 } |
| 118 | 107 |
| 119 private: | 108 private: |
| 120 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); | 109 DISALLOW_IMPLICIT_CONSTRUCTORS(InstanceCall); |
| 121 }; | 110 }; |
| 122 | 111 |
| 123 | 112 |
| 113 // The expected pattern of a dart static call: |
| 114 // mov R10, argument_descriptor_array (10 bytes) |
| 115 // mov R11, target_address (10 bytes) |
| 116 // call R11 (3 bytes) |
| 117 // <- return address |
| 118 class StaticCall : public ValueObject { |
| 119 public: |
| 120 explicit StaticCall(uword return_address) |
| 121 : start_(return_address - kCallPatternSize) { |
| 122 ASSERT(IsValid(return_address)); |
| 123 ASSERT((kCallPatternSize - 10) == Assembler::kCallExternalLabelSize); |
| 124 } |
| 125 |
| 126 static const int kCallPatternSize = 23; |
| 127 |
| 128 static bool IsValid(uword return_address) { |
| 129 uint8_t* code_bytes = |
| 130 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); |
| 131 return (code_bytes[00] == 0x49) && (code_bytes[01] == 0xBA) && |
| 132 (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) && |
| 133 (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) && |
| 134 (code_bytes[22] == 0xD3); |
| 135 } |
| 136 |
| 137 uword target() const { |
| 138 return *reinterpret_cast<uword*>(start_ + 10 + 2); |
| 139 } |
| 140 |
| 141 void set_target(uword target) const { |
| 142 uword* target_addr = reinterpret_cast<uword*>(start_ + 10 + 2); |
| 143 *target_addr = target; |
| 144 CPU::FlushICache(start_ + 10, 2 + 8); |
| 145 } |
| 146 |
| 147 private: |
| 148 uword start_; |
| 149 |
| 150 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall); |
| 151 }; |
| 152 |
| 153 |
| 124 uword CodePatcher::GetStaticCallTargetAt(uword return_address) { | 154 uword CodePatcher::GetStaticCallTargetAt(uword return_address) { |
| 125 StaticCall call(return_address); | 155 StaticCall call(return_address); |
| 126 return call.target(); | 156 return call.target(); |
| 127 } | 157 } |
| 128 | 158 |
| 129 | 159 |
| 130 void CodePatcher::PatchStaticCallAt(uword return_address, uword new_target) { | 160 void CodePatcher::PatchStaticCallAt(uword return_address, uword new_target) { |
| 131 StaticCall call(return_address); | 161 StaticCall call(return_address); |
| 132 call.set_target(new_target); | 162 call.set_target(new_target); |
| 133 } | 163 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 *reinterpret_cast<uint8_t*>(start) = 0xE8; | 271 *reinterpret_cast<uint8_t*>(start) = 0xE8; |
| 242 ShortCallPattern call(start); | 272 ShortCallPattern call(start); |
| 243 call.SetTargetAddress(target); | 273 call.SetTargetAddress(target); |
| 244 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); | 274 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); |
| 245 } | 275 } |
| 246 | 276 |
| 247 | 277 |
| 248 } // namespace dart | 278 } // namespace dart |
| 249 | 279 |
| 250 #endif // defined TARGET_ARCH_X64 | 280 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |