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" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 CPU::FlushICache(start_, 2 + 8); | 118 CPU::FlushICache(start_, 2 + 8); |
119 } | 119 } |
120 | 120 |
121 private: | 121 private: |
122 uword start_; | 122 uword start_; |
123 | 123 |
124 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall); | 124 DISALLOW_IMPLICIT_CONSTRUCTORS(StaticCall); |
125 }; | 125 }; |
126 | 126 |
127 | 127 |
| 128 // The expected code pattern of a dart closure call: |
| 129 // 00: 49 ba imm64 mov R10, immediate 2 ; 10 bytes |
| 130 // 10: 49 bb imm64 mov R11, target_address ; 10 bytes |
| 131 // 20: 41 ff d3 call R11 ; 3 bytes |
| 132 // 23: <- return_address |
| 133 class ClosureCall : public ValueObject { |
| 134 public: |
| 135 explicit ClosureCall(uword return_address) |
| 136 : start_(return_address - kCallPatternSize) { |
| 137 ASSERT(IsValid(return_address)); |
| 138 } |
| 139 |
| 140 static bool IsValid(uword return_address) { |
| 141 uint8_t* code_bytes = |
| 142 reinterpret_cast<uint8_t*>(return_address - kCallPatternSize); |
| 143 return (code_bytes[00] == 0x49) && (code_bytes[01] == 0xBA) && |
| 144 (code_bytes[10] == 0x49) && (code_bytes[11] == 0xBB) && |
| 145 (code_bytes[20] == 0x41) && (code_bytes[21] == 0xFF) && |
| 146 (code_bytes[22] == 0xD3); |
| 147 } |
| 148 |
| 149 RawArray* arguments_descriptor() const { |
| 150 return *reinterpret_cast<RawArray**>(start_ + 2); |
| 151 } |
| 152 |
| 153 private: |
| 154 static const int kCallPatternSize = 10 + 10 + 3; |
| 155 uword start_; |
| 156 DISALLOW_IMPLICIT_CONSTRUCTORS(ClosureCall); |
| 157 }; |
| 158 |
| 159 |
| 160 RawArray* CodePatcher::GetClosureArgDescAt(uword return_address, |
| 161 const Code& code) { |
| 162 ASSERT(code.ContainsInstructionAt(return_address)); |
| 163 ClosureCall call(return_address); |
| 164 return call.arguments_descriptor(); |
| 165 } |
| 166 |
| 167 |
128 uword CodePatcher::GetStaticCallTargetAt(uword return_address, | 168 uword CodePatcher::GetStaticCallTargetAt(uword return_address, |
129 const Code& code) { | 169 const Code& code) { |
130 ASSERT(code.ContainsInstructionAt(return_address)); | 170 ASSERT(code.ContainsInstructionAt(return_address)); |
131 StaticCall call(return_address); | 171 StaticCall call(return_address); |
132 return call.target(); | 172 return call.target(); |
133 } | 173 } |
134 | 174 |
135 | 175 |
136 void CodePatcher::PatchStaticCallAt(uword return_address, | 176 void CodePatcher::PatchStaticCallAt(uword return_address, |
137 const Code& code, | 177 const Code& code, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 *reinterpret_cast<uint8_t*>(start) = 0xE8; | 218 *reinterpret_cast<uint8_t*>(start) = 0xE8; |
179 ShortCallPattern call(start); | 219 ShortCallPattern call(start); |
180 call.SetTargetAddress(target); | 220 call.SetTargetAddress(target); |
181 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); | 221 CPU::FlushICache(start, ShortCallPattern::InstructionLength()); |
182 } | 222 } |
183 | 223 |
184 | 224 |
185 } // namespace dart | 225 } // namespace dart |
186 | 226 |
187 #endif // defined TARGET_ARCH_X64 | 227 #endif // defined TARGET_ARCH_X64 |
OLD | NEW |