| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 CPU::FlushICache(call_address(), kInstructionSize); | 42 CPU::FlushICache(call_address(), kInstructionSize); |
| 43 } | 43 } |
| 44 | 44 |
| 45 uint32_t immediate_one() const { | 45 uint32_t immediate_one() const { |
| 46 return *reinterpret_cast<uint32_t*>(start_ + 1); | 46 return *reinterpret_cast<uint32_t*>(start_ + 1); |
| 47 } | 47 } |
| 48 | 48 |
| 49 void set_immediate_one(uint32_t value) { | 49 void set_immediate_one(uint32_t value) { |
| 50 uint32_t* target_addr = reinterpret_cast<uint32_t*>(start_ + 1); | 50 uint32_t* target_addr = reinterpret_cast<uint32_t*>(start_ + 1); |
| 51 *target_addr = value; | 51 *target_addr = value; |
| 52 CPU::FlushICache(call_address(), kInstructionSize); | 52 CPU::FlushICache(start_, kInstructionSize); |
| 53 } | 53 } |
| 54 | 54 |
| 55 uint32_t immediate_two() const { | 55 uint32_t immediate_two() const { |
| 56 return *reinterpret_cast<uint32_t*>(start_ + kInstructionSize + 1); | 56 return *reinterpret_cast<uint32_t*>(start_ + kInstructionSize + 1); |
| 57 } | 57 } |
| 58 | 58 |
| 59 int argument_count() const { | 59 int argument_count() const { |
| 60 Array& args_desc = Array::Handle(); | 60 Array& args_desc = Array::Handle(); |
| 61 args_desc ^= reinterpret_cast<RawObject*>(immediate_two()); | 61 args_desc ^= reinterpret_cast<RawObject*>(immediate_two()); |
| 62 Smi& num_args = Smi::Handle(); | 62 Smi& num_args = Smi::Handle(); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 *function = call.function(); | 147 *function = call.function(); |
| 148 } | 148 } |
| 149 | 149 |
| 150 | 150 |
| 151 void CodePatcher::PatchStaticCallAt(uword return_address, uword new_target) { | 151 void CodePatcher::PatchStaticCallAt(uword return_address, uword new_target) { |
| 152 StaticCall call(return_address); | 152 StaticCall call(return_address); |
| 153 call.set_target(new_target); | 153 call.set_target(new_target); |
| 154 } | 154 } |
| 155 | 155 |
| 156 | 156 |
| 157 static void InsertCallOrJump(uword at_addr, | |
| 158 const ExternalLabel* label, | |
| 159 uint8_t op) { | |
| 160 const int kInstructionSize = 5; | |
| 161 *reinterpret_cast<uint8_t*>(at_addr) = op; // Call. | |
| 162 uword* target_addr = reinterpret_cast<uword*>(at_addr + 1); | |
| 163 uword offset = label->address() - (at_addr + kInstructionSize); | |
| 164 *target_addr = offset; | |
| 165 CPU::FlushICache(at_addr, kInstructionSize); | |
| 166 } | |
| 167 | |
| 168 | |
| 169 void CodePatcher::InsertCall(uword at_addr, const ExternalLabel* label) { | |
| 170 const uint8_t kCallOp = 0xE8; | |
| 171 InsertCallOrJump(at_addr, label, kCallOp); | |
| 172 } | |
| 173 | |
| 174 | |
| 175 void CodePatcher::InsertJump(uword at_addr, const ExternalLabel* label) { | |
| 176 const uint8_t kJumpOp = 0xE9; | |
| 177 InsertCallOrJump(at_addr, label, kJumpOp); | |
| 178 } | |
| 179 | |
| 180 | |
| 181 static void SwapCode(intptr_t num_bytes, char* a, char* b) { | 157 static void SwapCode(intptr_t num_bytes, char* a, char* b) { |
| 182 for (intptr_t i = 0; i < num_bytes; i++) { | 158 for (intptr_t i = 0; i < num_bytes; i++) { |
| 183 char tmp = *a; | 159 char tmp = *a; |
| 184 *a = *b; | 160 *a = *b; |
| 185 *b = tmp; | 161 *b = tmp; |
| 186 a++; | 162 a++; |
| 187 b++; | 163 b++; |
| 188 } | 164 } |
| 189 } | 165 } |
| 190 | 166 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 ASSERT(target != NULL); | 228 ASSERT(target != NULL); |
| 253 InstanceCall call(return_address); | 229 InstanceCall call(return_address); |
| 254 *num_arguments = call.argument_count(); | 230 *num_arguments = call.argument_count(); |
| 255 *num_named_arguments = call.named_argument_count(); | 231 *num_named_arguments = call.named_argument_count(); |
| 256 *target = call.target(); | 232 *target = call.target(); |
| 257 ICData ic_data(Array::ZoneHandle(call.ic_data())); | 233 ICData ic_data(Array::ZoneHandle(call.ic_data())); |
| 258 *function_name = ic_data.FunctionName(); | 234 *function_name = ic_data.FunctionName(); |
| 259 } | 235 } |
| 260 | 236 |
| 261 | 237 |
| 262 void CodePatcher::PatchInstanceCallAt(uword return_address, uword new_target) { | |
| 263 InstanceCall call(return_address); | |
| 264 call.set_target(new_target); | |
| 265 } | |
| 266 | |
| 267 | |
| 268 RawArray* CodePatcher::GetInstanceCallIcDataAt(uword return_address) { | 238 RawArray* CodePatcher::GetInstanceCallIcDataAt(uword return_address) { |
| 269 InstanceCall call(return_address); | 239 InstanceCall call(return_address); |
| 270 return call.ic_data(); | 240 return call.ic_data(); |
| 271 } | 241 } |
| 272 | 242 |
| 273 | 243 |
| 274 void CodePatcher::SetInstanceCallIcDataAt(uword return_address, | 244 void CodePatcher::SetInstanceCallIcDataAt(uword return_address, |
| 275 const Array& ic_data) { | 245 const Array& ic_data) { |
| 276 InstanceCall call(return_address); | 246 InstanceCall call(return_address); |
| 277 call.SetIcData(ic_data); | 247 call.SetIcData(ic_data); |
| 278 } | 248 } |
| 279 | 249 |
| 280 | 250 |
| 281 intptr_t CodePatcher::InstanceCallSizeInBytes() { | 251 intptr_t CodePatcher::InstanceCallSizeInBytes() { |
| 282 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize; | 252 return DartCallPattern::kNumInstructions * DartCallPattern::kInstructionSize; |
| 283 } | 253 } |
| 284 | 254 |
| 285 } // namespace dart | 255 } // namespace dart |
| 286 | 256 |
| 287 #endif // defined TARGET_ARCH_IA32 | 257 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |