OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_X64_ASSEMBLER_X64_INL_H_ | 5 #ifndef V8_X64_ASSEMBLER_X64_INL_H_ |
6 #define V8_X64_ASSEMBLER_X64_INL_H_ | 6 #define V8_X64_ASSEMBLER_X64_INL_H_ |
7 | 7 |
8 #include "src/x64/assembler-x64.h" | 8 #include "src/x64/assembler-x64.h" |
9 | 9 |
10 #include "src/base/cpu.h" | 10 #include "src/base/cpu.h" |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 Address pc, Address target, RelocInfo::Mode mode) { | 286 Address pc, Address target, RelocInfo::Mode mode) { |
287 Memory::Address_at(pc) = target; | 287 Memory::Address_at(pc) = target; |
288 } | 288 } |
289 | 289 |
290 | 290 |
291 Address Assembler::target_address_from_return_address(Address pc) { | 291 Address Assembler::target_address_from_return_address(Address pc) { |
292 return pc - kCallTargetAddressOffset; | 292 return pc - kCallTargetAddressOffset; |
293 } | 293 } |
294 | 294 |
295 | 295 |
296 Address Assembler::break_address_from_return_address(Address pc) { | |
297 return pc - Assembler::kPatchDebugBreakSlotReturnOffset; | |
298 } | |
299 | |
300 | |
301 Handle<Object> Assembler::code_target_object_handle_at(Address pc) { | 296 Handle<Object> Assembler::code_target_object_handle_at(Address pc) { |
302 return code_targets_[Memory::int32_at(pc)]; | 297 return code_targets_[Memory::int32_at(pc)]; |
303 } | 298 } |
304 | 299 |
305 | 300 |
306 Address Assembler::runtime_entry_at(Address pc) { | 301 Address Assembler::runtime_entry_at(Address pc) { |
307 return Memory::int32_at(pc) + isolate()->code_range()->start(); | 302 return Memory::int32_at(pc) + isolate()->code_range()->start(); |
308 } | 303 } |
309 | 304 |
310 // ----------------------------------------------------------------------------- | 305 // ----------------------------------------------------------------------------- |
311 // Implementation of RelocInfo | 306 // Implementation of RelocInfo |
312 | 307 |
313 // The modes possibly affected by apply must be in kApplyMask. | 308 // The modes possibly affected by apply must be in kApplyMask. |
314 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { | 309 void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { |
315 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; | 310 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; |
316 if (IsInternalReference(rmode_)) { | 311 if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
| 312 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); |
| 313 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(int32_t)); |
| 314 } else if (IsCodeAgeSequence(rmode_)) { |
| 315 if (*pc_ == kCallOpcode) { |
| 316 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
| 317 *p -= static_cast<int32_t>(delta); // Relocate entry. |
| 318 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(int32_t)); |
| 319 } |
| 320 } else if (IsInternalReference(rmode_)) { |
317 // absolute code pointer inside code object moves with the code object. | 321 // absolute code pointer inside code object moves with the code object. |
318 Memory::Address_at(pc_) += delta; | 322 Memory::Address_at(pc_) += delta; |
319 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(Address)); | 323 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(Address)); |
320 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | |
321 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); | |
322 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(int32_t)); | |
323 } else if (rmode_ == CODE_AGE_SEQUENCE) { | |
324 if (*pc_ == kCallOpcode) { | |
325 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | |
326 *p -= static_cast<int32_t>(delta); // Relocate entry. | |
327 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
328 } | |
329 } | 324 } |
330 } | 325 } |
331 | 326 |
332 | 327 |
333 Address RelocInfo::target_address() { | 328 Address RelocInfo::target_address() { |
334 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 329 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
335 return Assembler::target_address_at(pc_, host_); | 330 return Assembler::target_address_at(pc_, host_); |
336 } | 331 } |
337 | 332 |
338 | 333 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 | 514 |
520 void RelocInfo::set_code_age_stub(Code* stub, | 515 void RelocInfo::set_code_age_stub(Code* stub, |
521 ICacheFlushMode icache_flush_mode) { | 516 ICacheFlushMode icache_flush_mode) { |
522 DCHECK(*pc_ == kCallOpcode); | 517 DCHECK(*pc_ == kCallOpcode); |
523 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 518 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
524 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 519 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
525 icache_flush_mode); | 520 icache_flush_mode); |
526 } | 521 } |
527 | 522 |
528 | 523 |
529 Address RelocInfo::call_address() { | 524 Address RelocInfo::debug_call_address() { |
530 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 525 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
531 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 526 return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); |
532 return Memory::Address_at( | |
533 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); | |
534 } | 527 } |
535 | 528 |
536 | 529 |
537 void RelocInfo::set_call_address(Address target) { | 530 void RelocInfo::set_debug_call_address(Address target) { |
538 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 531 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
539 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 532 Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) = |
540 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = | |
541 target; | 533 target; |
542 CpuFeatures::FlushICache( | 534 CpuFeatures::FlushICache(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset, |
543 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); | 535 sizeof(Address)); |
544 if (host() != NULL) { | 536 if (host() != NULL) { |
545 Object* target_code = Code::GetCodeFromTargetAddress(target); | 537 Object* target_code = Code::GetCodeFromTargetAddress(target); |
546 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 538 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
547 host(), this, HeapObject::cast(target_code)); | 539 host(), this, HeapObject::cast(target_code)); |
548 } | 540 } |
549 } | 541 } |
550 | 542 |
551 | 543 |
552 Object* RelocInfo::call_object() { | |
553 return *call_object_address(); | |
554 } | |
555 | |
556 | |
557 void RelocInfo::set_call_object(Object* target) { | |
558 *call_object_address() = target; | |
559 } | |
560 | |
561 | |
562 Object** RelocInfo::call_object_address() { | |
563 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | |
564 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | |
565 return reinterpret_cast<Object**>( | |
566 pc_ + Assembler::kPatchReturnSequenceAddressOffset); | |
567 } | |
568 | |
569 | |
570 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { | 544 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
571 RelocInfo::Mode mode = rmode(); | 545 RelocInfo::Mode mode = rmode(); |
572 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 546 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
573 visitor->VisitEmbeddedPointer(this); | 547 visitor->VisitEmbeddedPointer(this); |
574 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 548 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
575 } else if (RelocInfo::IsCodeTarget(mode)) { | 549 } else if (RelocInfo::IsCodeTarget(mode)) { |
576 visitor->VisitCodeTarget(this); | 550 visitor->VisitCodeTarget(this); |
577 } else if (mode == RelocInfo::CELL) { | 551 } else if (mode == RelocInfo::CELL) { |
578 visitor->VisitCell(this); | 552 visitor->VisitCell(this); |
579 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 553 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
580 visitor->VisitExternalReference(this); | 554 visitor->VisitExternalReference(this); |
581 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 555 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
582 visitor->VisitInternalReference(this); | 556 visitor->VisitInternalReference(this); |
583 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 557 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
584 visitor->VisitCodeAgeSequence(this); | 558 visitor->VisitCodeAgeSequence(this); |
585 } else if (((RelocInfo::IsJSReturn(mode) && | 559 } else if (RelocInfo::IsDebugBreakSlot(mode) && |
586 IsPatchedReturnSequence()) || | 560 IsPatchedDebugBreakSlotSequence() && |
587 (RelocInfo::IsDebugBreakSlot(mode) && | |
588 IsPatchedDebugBreakSlotSequence())) && | |
589 isolate->debug()->has_break_points()) { | 561 isolate->debug()->has_break_points()) { |
590 visitor->VisitDebugTarget(this); | 562 visitor->VisitDebugTarget(this); |
591 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 563 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
592 visitor->VisitRuntimeEntry(this); | 564 visitor->VisitRuntimeEntry(this); |
593 } | 565 } |
594 } | 566 } |
595 | 567 |
596 | 568 |
597 template<typename StaticVisitor> | 569 template<typename StaticVisitor> |
598 void RelocInfo::Visit(Heap* heap) { | 570 void RelocInfo::Visit(Heap* heap) { |
599 RelocInfo::Mode mode = rmode(); | 571 RelocInfo::Mode mode = rmode(); |
600 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 572 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
601 StaticVisitor::VisitEmbeddedPointer(heap, this); | 573 StaticVisitor::VisitEmbeddedPointer(heap, this); |
602 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 574 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
603 } else if (RelocInfo::IsCodeTarget(mode)) { | 575 } else if (RelocInfo::IsCodeTarget(mode)) { |
604 StaticVisitor::VisitCodeTarget(heap, this); | 576 StaticVisitor::VisitCodeTarget(heap, this); |
605 } else if (mode == RelocInfo::CELL) { | 577 } else if (mode == RelocInfo::CELL) { |
606 StaticVisitor::VisitCell(heap, this); | 578 StaticVisitor::VisitCell(heap, this); |
607 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 579 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
608 StaticVisitor::VisitExternalReference(this); | 580 StaticVisitor::VisitExternalReference(this); |
609 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 581 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
610 StaticVisitor::VisitInternalReference(this); | 582 StaticVisitor::VisitInternalReference(this); |
611 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 583 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
612 StaticVisitor::VisitCodeAgeSequence(heap, this); | 584 StaticVisitor::VisitCodeAgeSequence(heap, this); |
613 } else if (heap->isolate()->debug()->has_break_points() && | 585 } else if (heap->isolate()->debug()->has_break_points() && |
614 ((RelocInfo::IsJSReturn(mode) && | 586 RelocInfo::IsDebugBreakSlot(mode) && |
615 IsPatchedReturnSequence()) || | 587 IsPatchedDebugBreakSlotSequence()) { |
616 (RelocInfo::IsDebugBreakSlot(mode) && | |
617 IsPatchedDebugBreakSlotSequence()))) { | |
618 StaticVisitor::VisitDebugTarget(heap, this); | 588 StaticVisitor::VisitDebugTarget(heap, this); |
619 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 589 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
620 StaticVisitor::VisitRuntimeEntry(this); | 590 StaticVisitor::VisitRuntimeEntry(this); |
621 } | 591 } |
622 } | 592 } |
623 | 593 |
624 | 594 |
625 // ----------------------------------------------------------------------------- | 595 // ----------------------------------------------------------------------------- |
626 // Implementation of Operand | 596 // Implementation of Operand |
627 | 597 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 | 631 |
662 void Operand::set_disp64(int64_t disp) { | 632 void Operand::set_disp64(int64_t disp) { |
663 DCHECK_EQ(1, len_); | 633 DCHECK_EQ(1, len_); |
664 int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); | 634 int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); |
665 *p = disp; | 635 *p = disp; |
666 len_ += sizeof(disp); | 636 len_ += sizeof(disp); |
667 } | 637 } |
668 } } // namespace v8::internal | 638 } } // namespace v8::internal |
669 | 639 |
670 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 640 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
OLD | NEW |