OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 } | 167 } |
168 | 168 |
169 | 169 |
170 // ----------------------------------------------------------------------------- | 170 // ----------------------------------------------------------------------------- |
171 // Implementation of RelocInfo | 171 // Implementation of RelocInfo |
172 | 172 |
173 // Patch the code at the current PC with a call to the target address. | 173 // Patch the code at the current PC with a call to the target address. |
174 // Additional guard int3 instructions can be added if required. | 174 // Additional guard int3 instructions can be added if required. |
175 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { | 175 void RelocInfo::PatchCodeWithCall(Address target, int guard_bytes) { |
176 // Call instruction takes up 13 bytes and int3 takes up one byte. | 176 // Call instruction takes up 13 bytes and int3 takes up one byte. |
| 177 static const int kCallInstructionSize = 13; |
177 Address patch_site = pc_; | 178 Address patch_site = pc_; |
178 Memory::uint16_at(patch_site) = 0xBA49u; // movq r10, imm64 | 179 Memory::uint16_at(patch_site) = 0xBA49u; // movq r10, imm64 |
179 // Write "0x00, call r10" starting at last byte of address. We overwrite | 180 // Write "0x00, call r10" starting at last byte of address. We overwrite |
180 // the 0x00 later, and this lets us write a uint32. | 181 // the 0x00 later, and this lets us write a uint32. |
181 Memory::uint32_at(patch_site + 9) = 0xD2FF4900u; // 0x00, call r10 | 182 Memory::uint32_at(patch_site + 9) = 0xD2FF4900u; // 0x00, call r10 |
182 Memory::Address_at(patch_site + 2) = target; | 183 Memory::Address_at(patch_site + 2) = target; |
183 | 184 |
184 // Add the requested number of int3 instructions after the call. | 185 // Add the requested number of int3 instructions after the call. |
185 for (int i = 0; i < guard_bytes; i++) { | 186 for (int i = 0; i < guard_bytes; i++) { |
186 *(patch_site + 13 + i) = 0xCC; // int3 | 187 *(patch_site + kCallInstructionSize + i) = 0xCC; // int3 |
187 } | 188 } |
| 189 |
| 190 // Indicate that code has changed. |
| 191 CPU::FlushICache(patch_site, kCallInstructionSize + guard_bytes); |
188 } | 192 } |
189 | 193 |
190 | 194 |
191 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { | 195 void RelocInfo::PatchCode(byte* instructions, int instruction_count) { |
192 // Patch the code at the current address with the supplied instructions. | 196 // Patch the code at the current address with the supplied instructions. |
193 for (int i = 0; i < instruction_count; i++) { | 197 for (int i = 0; i < instruction_count; i++) { |
194 *(pc_ + i) = *(instructions + i); | 198 *(pc_ + i) = *(instructions + i); |
195 } | 199 } |
196 } | 200 } |
197 | 201 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 } else { | 272 } else { |
269 // use externally provided buffer instead | 273 // use externally provided buffer instead |
270 ASSERT(buffer_size > 0); | 274 ASSERT(buffer_size > 0); |
271 buffer_ = static_cast<byte*>(buffer); | 275 buffer_ = static_cast<byte*>(buffer); |
272 buffer_size_ = buffer_size; | 276 buffer_size_ = buffer_size; |
273 own_buffer_ = false; | 277 own_buffer_ = false; |
274 } | 278 } |
275 | 279 |
276 // Clear the buffer in debug mode unless it was provided by the | 280 // Clear the buffer in debug mode unless it was provided by the |
277 // caller in which case we can't be sure it's okay to overwrite | 281 // caller in which case we can't be sure it's okay to overwrite |
278 // existing code in it; see CodePatcher::CodePatcher(...). | 282 // existing code in it. |
279 #ifdef DEBUG | 283 #ifdef DEBUG |
280 if (own_buffer_) { | 284 if (own_buffer_) { |
281 memset(buffer_, 0xCC, buffer_size); // int3 | 285 memset(buffer_, 0xCC, buffer_size); // int3 |
282 } | 286 } |
283 #endif | 287 #endif |
284 | 288 |
285 // setup buffer pointers | 289 // setup buffer pointers |
286 ASSERT(buffer_ != NULL); | 290 ASSERT(buffer_ != NULL); |
287 pc_ = buffer_; | 291 pc_ = buffer_; |
288 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); | 292 reloc_info_writer.Reposition(buffer_ + buffer_size, pc_); |
(...skipping 2069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2358 RecordRelocInfo(RelocInfo::POSITION, current_position_); | 2362 RecordRelocInfo(RelocInfo::POSITION, current_position_); |
2359 written_position_ = current_position_; | 2363 written_position_ = current_position_; |
2360 } | 2364 } |
2361 } | 2365 } |
2362 | 2366 |
2363 | 2367 |
2364 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; | 2368 const int RelocInfo::kApplyMask = 1 << RelocInfo::INTERNAL_REFERENCE; |
2365 | 2369 |
2366 | 2370 |
2367 } } // namespace v8::internal | 2371 } } // namespace v8::internal |
OLD | NEW |