OLD | NEW |
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
6 // met: | 6 // met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 namespace internal { | 46 namespace internal { |
47 | 47 |
48 bool CpuFeatures::SupportsCrankshaft() { return true; } | 48 bool CpuFeatures::SupportsCrankshaft() { return true; } |
49 | 49 |
50 | 50 |
51 static const byte kCallOpcode = 0xE8; | 51 static const byte kCallOpcode = 0xE8; |
52 static const int kNoCodeAgeSequenceLength = 5; | 52 static const int kNoCodeAgeSequenceLength = 5; |
53 | 53 |
54 | 54 |
55 // The modes possibly affected by apply must be in kApplyMask. | 55 // The modes possibly affected by apply must be in kApplyMask. |
56 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { | 56 void RelocInfo::apply(intptr_t delta) { |
57 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; | |
58 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { | 57 if (IsRuntimeEntry(rmode_) || IsCodeTarget(rmode_)) { |
59 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 58 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
60 *p -= delta; // Relocate entry. | 59 *p -= delta; // Relocate entry. |
61 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
62 } else if (IsCodeAgeSequence(rmode_)) { | 60 } else if (IsCodeAgeSequence(rmode_)) { |
63 if (*pc_ == kCallOpcode) { | 61 if (*pc_ == kCallOpcode) { |
64 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 62 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
65 *p -= delta; // Relocate entry. | 63 *p -= delta; // Relocate entry. |
66 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
67 } | 64 } |
68 } else if (IsJSReturn(rmode_) && IsPatchedReturnSequence()) { | |
69 // Special handling of js_return when a break point is set (call | |
70 // instruction has been inserted). | |
71 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | |
72 *p -= delta; // Relocate entry. | |
73 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
74 } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) { | 65 } else if (IsDebugBreakSlot(rmode_) && IsPatchedDebugBreakSlotSequence()) { |
75 // Special handling of a debug break slot when a break point is set (call | 66 // Special handling of a debug break slot when a break point is set (call |
76 // instruction has been inserted). | 67 // instruction has been inserted). |
77 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 68 int32_t* p = reinterpret_cast<int32_t*>( |
| 69 pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); |
78 *p -= delta; // Relocate entry. | 70 *p -= delta; // Relocate entry. |
79 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
80 } else if (IsInternalReference(rmode_)) { | 71 } else if (IsInternalReference(rmode_)) { |
81 // absolute code pointer inside code object moves with the code object. | 72 // absolute code pointer inside code object moves with the code object. |
82 int32_t* p = reinterpret_cast<int32_t*>(pc_); | 73 int32_t* p = reinterpret_cast<int32_t*>(pc_); |
83 *p += delta; // Relocate entry. | 74 *p += delta; // Relocate entry. |
84 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
85 } | 75 } |
86 } | 76 } |
87 | 77 |
88 | 78 |
89 Address RelocInfo::target_address() { | 79 Address RelocInfo::target_address() { |
90 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 80 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
91 return Assembler::target_address_at(pc_, host_); | 81 return Assembler::target_address_at(pc_, host_); |
92 } | 82 } |
93 | 83 |
94 | 84 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 | 228 |
239 void RelocInfo::set_code_age_stub(Code* stub, | 229 void RelocInfo::set_code_age_stub(Code* stub, |
240 ICacheFlushMode icache_flush_mode) { | 230 ICacheFlushMode icache_flush_mode) { |
241 DCHECK(*pc_ == kCallOpcode); | 231 DCHECK(*pc_ == kCallOpcode); |
242 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 232 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
243 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 233 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
244 icache_flush_mode); | 234 icache_flush_mode); |
245 } | 235 } |
246 | 236 |
247 | 237 |
248 Address RelocInfo::call_address() { | 238 Address RelocInfo::debug_call_address() { |
249 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 239 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
250 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 240 Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset; |
251 return Assembler::target_address_at(pc_ + 1, host_); | 241 return Assembler::target_address_at(location, host_); |
252 } | 242 } |
253 | 243 |
254 | 244 |
255 void RelocInfo::set_call_address(Address target) { | 245 void RelocInfo::set_debug_call_address(Address target) { |
256 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 246 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
257 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 247 Address location = pc_ + Assembler::kPatchDebugBreakSlotAddressOffset; |
258 Assembler::set_target_address_at(pc_ + 1, host_, target); | 248 Assembler::set_target_address_at(location, host_, target); |
259 if (host() != NULL) { | 249 if (host() != NULL) { |
260 Object* target_code = Code::GetCodeFromTargetAddress(target); | 250 Object* target_code = Code::GetCodeFromTargetAddress(target); |
261 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 251 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
262 host(), this, HeapObject::cast(target_code)); | 252 host(), this, HeapObject::cast(target_code)); |
263 } | 253 } |
264 } | 254 } |
265 | 255 |
266 | 256 |
267 Object* RelocInfo::call_object() { | |
268 return *call_object_address(); | |
269 } | |
270 | |
271 | |
272 void RelocInfo::set_call_object(Object* target) { | |
273 *call_object_address() = target; | |
274 } | |
275 | |
276 | |
277 Object** RelocInfo::call_object_address() { | |
278 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | |
279 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | |
280 return reinterpret_cast<Object**>(pc_ + 1); | |
281 } | |
282 | |
283 | |
284 void RelocInfo::WipeOut() { | 257 void RelocInfo::WipeOut() { |
285 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || | 258 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || |
286 IsInternalReference(rmode_)) { | 259 IsInternalReference(rmode_)) { |
287 Memory::Address_at(pc_) = NULL; | 260 Memory::Address_at(pc_) = NULL; |
288 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 261 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
289 // Effectively write zero into the relocation. | 262 // Effectively write zero into the relocation. |
290 Assembler::set_target_address_at(pc_, host_, pc_ + sizeof(int32_t)); | 263 Assembler::set_target_address_at(pc_, host_, pc_ + sizeof(int32_t)); |
291 } else { | 264 } else { |
292 UNREACHABLE(); | 265 UNREACHABLE(); |
293 } | 266 } |
(...skipping 18 matching lines...) Expand all Loading... |
312 } else if (RelocInfo::IsCodeTarget(mode)) { | 285 } else if (RelocInfo::IsCodeTarget(mode)) { |
313 visitor->VisitCodeTarget(this); | 286 visitor->VisitCodeTarget(this); |
314 } else if (mode == RelocInfo::CELL) { | 287 } else if (mode == RelocInfo::CELL) { |
315 visitor->VisitCell(this); | 288 visitor->VisitCell(this); |
316 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 289 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
317 visitor->VisitExternalReference(this); | 290 visitor->VisitExternalReference(this); |
318 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 291 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
319 visitor->VisitInternalReference(this); | 292 visitor->VisitInternalReference(this); |
320 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 293 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
321 visitor->VisitCodeAgeSequence(this); | 294 visitor->VisitCodeAgeSequence(this); |
322 } else if (((RelocInfo::IsJSReturn(mode) && | 295 } else if (RelocInfo::IsDebugBreakSlot(mode) && |
323 IsPatchedReturnSequence()) || | 296 IsPatchedDebugBreakSlotSequence() && |
324 (RelocInfo::IsDebugBreakSlot(mode) && | |
325 IsPatchedDebugBreakSlotSequence())) && | |
326 isolate->debug()->has_break_points()) { | 297 isolate->debug()->has_break_points()) { |
327 visitor->VisitDebugTarget(this); | 298 visitor->VisitDebugTarget(this); |
328 } else if (IsRuntimeEntry(mode)) { | 299 } else if (IsRuntimeEntry(mode)) { |
329 visitor->VisitRuntimeEntry(this); | 300 visitor->VisitRuntimeEntry(this); |
330 } | 301 } |
331 } | 302 } |
332 | 303 |
333 | 304 |
334 template<typename StaticVisitor> | 305 template<typename StaticVisitor> |
335 void RelocInfo::Visit(Heap* heap) { | 306 void RelocInfo::Visit(Heap* heap) { |
336 RelocInfo::Mode mode = rmode(); | 307 RelocInfo::Mode mode = rmode(); |
337 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 308 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
338 StaticVisitor::VisitEmbeddedPointer(heap, this); | 309 StaticVisitor::VisitEmbeddedPointer(heap, this); |
339 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 310 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
340 } else if (RelocInfo::IsCodeTarget(mode)) { | 311 } else if (RelocInfo::IsCodeTarget(mode)) { |
341 StaticVisitor::VisitCodeTarget(heap, this); | 312 StaticVisitor::VisitCodeTarget(heap, this); |
342 } else if (mode == RelocInfo::CELL) { | 313 } else if (mode == RelocInfo::CELL) { |
343 StaticVisitor::VisitCell(heap, this); | 314 StaticVisitor::VisitCell(heap, this); |
344 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 315 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
345 StaticVisitor::VisitExternalReference(this); | 316 StaticVisitor::VisitExternalReference(this); |
346 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 317 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
347 StaticVisitor::VisitInternalReference(this); | 318 StaticVisitor::VisitInternalReference(this); |
348 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 319 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
349 StaticVisitor::VisitCodeAgeSequence(heap, this); | 320 StaticVisitor::VisitCodeAgeSequence(heap, this); |
350 } else if (heap->isolate()->debug()->has_break_points() && | 321 } else if (heap->isolate()->debug()->has_break_points() && |
351 ((RelocInfo::IsJSReturn(mode) && | 322 RelocInfo::IsDebugBreakSlot(mode) && |
352 IsPatchedReturnSequence()) || | 323 IsPatchedDebugBreakSlotSequence()) { |
353 (RelocInfo::IsDebugBreakSlot(mode) && | |
354 IsPatchedDebugBreakSlotSequence()))) { | |
355 StaticVisitor::VisitDebugTarget(heap, this); | 324 StaticVisitor::VisitDebugTarget(heap, this); |
356 } else if (IsRuntimeEntry(mode)) { | 325 } else if (IsRuntimeEntry(mode)) { |
357 StaticVisitor::VisitRuntimeEntry(this); | 326 StaticVisitor::VisitRuntimeEntry(this); |
358 } | 327 } |
359 } | 328 } |
360 | 329 |
361 | 330 |
362 | 331 |
363 Immediate::Immediate(int x) { | 332 Immediate::Immediate(int x) { |
364 x_ = x; | 333 x_ = x; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 CpuFeatures::FlushICache(p, sizeof(int32_t)); | 465 CpuFeatures::FlushICache(p, sizeof(int32_t)); |
497 } | 466 } |
498 } | 467 } |
499 | 468 |
500 | 469 |
501 Address Assembler::target_address_from_return_address(Address pc) { | 470 Address Assembler::target_address_from_return_address(Address pc) { |
502 return pc - kCallTargetAddressOffset; | 471 return pc - kCallTargetAddressOffset; |
503 } | 472 } |
504 | 473 |
505 | 474 |
506 Address Assembler::break_address_from_return_address(Address pc) { | |
507 return pc - Assembler::kPatchDebugBreakSlotReturnOffset; | |
508 } | |
509 | |
510 | |
511 Displacement Assembler::disp_at(Label* L) { | 475 Displacement Assembler::disp_at(Label* L) { |
512 return Displacement(long_at(L->pos())); | 476 return Displacement(long_at(L->pos())); |
513 } | 477 } |
514 | 478 |
515 | 479 |
516 void Assembler::disp_at_put(Label* L, Displacement disp) { | 480 void Assembler::disp_at_put(Label* L, Displacement disp) { |
517 long_at_put(L->pos(), disp.data()); | 481 long_at_put(L->pos(), disp.data()); |
518 } | 482 } |
519 | 483 |
520 | 484 |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 | 552 |
589 | 553 |
590 Operand::Operand(Immediate imm) { | 554 Operand::Operand(Immediate imm) { |
591 // [disp/r] | 555 // [disp/r] |
592 set_modrm(0, ebp); | 556 set_modrm(0, ebp); |
593 set_dispr(imm.x_, imm.rmode_); | 557 set_dispr(imm.x_, imm.rmode_); |
594 } | 558 } |
595 } } // namespace v8::internal | 559 } } // namespace v8::internal |
596 | 560 |
597 #endif // V8_X87_ASSEMBLER_X87_INL_H_ | 561 #endif // V8_X87_ASSEMBLER_X87_INL_H_ |
OLD | NEW |