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 |