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) { |
315 bool flush_icache = icache_flush_mode != SKIP_ICACHE_FLUSH; | 310 if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
316 if (IsInternalReference(rmode_)) { | |
317 // absolute code pointer inside code object moves with the code object. | |
318 Memory::Address_at(pc_) += delta; | |
319 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); | 311 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); |
322 if (flush_icache) CpuFeatures::FlushICache(pc_, sizeof(int32_t)); | 312 } else if (IsCodeAgeSequence(rmode_)) { |
323 } else if (rmode_ == CODE_AGE_SEQUENCE) { | |
324 if (*pc_ == kCallOpcode) { | 313 if (*pc_ == kCallOpcode) { |
325 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); | 314 int32_t* p = reinterpret_cast<int32_t*>(pc_ + 1); |
326 *p -= static_cast<int32_t>(delta); // Relocate entry. | 315 *p -= static_cast<int32_t>(delta); // Relocate entry. |
327 if (flush_icache) CpuFeatures::FlushICache(p, sizeof(uint32_t)); | |
328 } | 316 } |
| 317 } else if (IsInternalReference(rmode_)) { |
| 318 // absolute code pointer inside code object moves with the code object. |
| 319 Memory::Address_at(pc_) += delta; |
329 } | 320 } |
330 } | 321 } |
331 | 322 |
332 | 323 |
333 Address RelocInfo::target_address() { | 324 Address RelocInfo::target_address() { |
334 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); | 325 DCHECK(IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)); |
335 return Assembler::target_address_at(pc_, host_); | 326 return Assembler::target_address_at(pc_, host_); |
336 } | 327 } |
337 | 328 |
338 | 329 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 | 510 |
520 void RelocInfo::set_code_age_stub(Code* stub, | 511 void RelocInfo::set_code_age_stub(Code* stub, |
521 ICacheFlushMode icache_flush_mode) { | 512 ICacheFlushMode icache_flush_mode) { |
522 DCHECK(*pc_ == kCallOpcode); | 513 DCHECK(*pc_ == kCallOpcode); |
523 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 514 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
524 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), | 515 Assembler::set_target_address_at(pc_ + 1, host_, stub->instruction_start(), |
525 icache_flush_mode); | 516 icache_flush_mode); |
526 } | 517 } |
527 | 518 |
528 | 519 |
529 Address RelocInfo::call_address() { | 520 Address RelocInfo::debug_call_address() { |
530 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 521 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
531 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 522 return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); |
532 return Memory::Address_at( | |
533 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset); | |
534 } | 523 } |
535 | 524 |
536 | 525 |
537 void RelocInfo::set_call_address(Address target) { | 526 void RelocInfo::set_debug_call_address(Address target) { |
538 DCHECK((IsJSReturn(rmode()) && IsPatchedReturnSequence()) || | 527 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
539 (IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence())); | 528 Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) = |
540 Memory::Address_at(pc_ + Assembler::kRealPatchReturnSequenceAddressOffset) = | |
541 target; | 529 target; |
542 CpuFeatures::FlushICache( | 530 CpuFeatures::FlushICache(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset, |
543 pc_ + Assembler::kRealPatchReturnSequenceAddressOffset, sizeof(Address)); | 531 sizeof(Address)); |
544 if (host() != NULL) { | 532 if (host() != NULL) { |
545 Object* target_code = Code::GetCodeFromTargetAddress(target); | 533 Object* target_code = Code::GetCodeFromTargetAddress(target); |
546 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( | 534 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode( |
547 host(), this, HeapObject::cast(target_code)); | 535 host(), this, HeapObject::cast(target_code)); |
548 } | 536 } |
549 } | 537 } |
550 | 538 |
551 | 539 |
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) { | 540 void RelocInfo::Visit(Isolate* isolate, ObjectVisitor* visitor) { |
571 RelocInfo::Mode mode = rmode(); | 541 RelocInfo::Mode mode = rmode(); |
572 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 542 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
573 visitor->VisitEmbeddedPointer(this); | 543 visitor->VisitEmbeddedPointer(this); |
574 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 544 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
575 } else if (RelocInfo::IsCodeTarget(mode)) { | 545 } else if (RelocInfo::IsCodeTarget(mode)) { |
576 visitor->VisitCodeTarget(this); | 546 visitor->VisitCodeTarget(this); |
577 } else if (mode == RelocInfo::CELL) { | 547 } else if (mode == RelocInfo::CELL) { |
578 visitor->VisitCell(this); | 548 visitor->VisitCell(this); |
579 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 549 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
580 visitor->VisitExternalReference(this); | 550 visitor->VisitExternalReference(this); |
581 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 551 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
582 visitor->VisitInternalReference(this); | 552 visitor->VisitInternalReference(this); |
583 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 553 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
584 visitor->VisitCodeAgeSequence(this); | 554 visitor->VisitCodeAgeSequence(this); |
585 } else if (((RelocInfo::IsJSReturn(mode) && | 555 } else if (RelocInfo::IsDebugBreakSlot(mode) && |
586 IsPatchedReturnSequence()) || | 556 IsPatchedDebugBreakSlotSequence() && |
587 (RelocInfo::IsDebugBreakSlot(mode) && | |
588 IsPatchedDebugBreakSlotSequence())) && | |
589 isolate->debug()->has_break_points()) { | 557 isolate->debug()->has_break_points()) { |
590 visitor->VisitDebugTarget(this); | 558 visitor->VisitDebugTarget(this); |
591 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 559 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
592 visitor->VisitRuntimeEntry(this); | 560 visitor->VisitRuntimeEntry(this); |
593 } | 561 } |
594 } | 562 } |
595 | 563 |
596 | 564 |
597 template<typename StaticVisitor> | 565 template<typename StaticVisitor> |
598 void RelocInfo::Visit(Heap* heap) { | 566 void RelocInfo::Visit(Heap* heap) { |
599 RelocInfo::Mode mode = rmode(); | 567 RelocInfo::Mode mode = rmode(); |
600 if (mode == RelocInfo::EMBEDDED_OBJECT) { | 568 if (mode == RelocInfo::EMBEDDED_OBJECT) { |
601 StaticVisitor::VisitEmbeddedPointer(heap, this); | 569 StaticVisitor::VisitEmbeddedPointer(heap, this); |
602 CpuFeatures::FlushICache(pc_, sizeof(Address)); | 570 CpuFeatures::FlushICache(pc_, sizeof(Address)); |
603 } else if (RelocInfo::IsCodeTarget(mode)) { | 571 } else if (RelocInfo::IsCodeTarget(mode)) { |
604 StaticVisitor::VisitCodeTarget(heap, this); | 572 StaticVisitor::VisitCodeTarget(heap, this); |
605 } else if (mode == RelocInfo::CELL) { | 573 } else if (mode == RelocInfo::CELL) { |
606 StaticVisitor::VisitCell(heap, this); | 574 StaticVisitor::VisitCell(heap, this); |
607 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { | 575 } else if (mode == RelocInfo::EXTERNAL_REFERENCE) { |
608 StaticVisitor::VisitExternalReference(this); | 576 StaticVisitor::VisitExternalReference(this); |
609 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { | 577 } else if (mode == RelocInfo::INTERNAL_REFERENCE) { |
610 StaticVisitor::VisitInternalReference(this); | 578 StaticVisitor::VisitInternalReference(this); |
611 } else if (RelocInfo::IsCodeAgeSequence(mode)) { | 579 } else if (RelocInfo::IsCodeAgeSequence(mode)) { |
612 StaticVisitor::VisitCodeAgeSequence(heap, this); | 580 StaticVisitor::VisitCodeAgeSequence(heap, this); |
613 } else if (heap->isolate()->debug()->has_break_points() && | 581 } else if (heap->isolate()->debug()->has_break_points() && |
614 ((RelocInfo::IsJSReturn(mode) && | 582 RelocInfo::IsDebugBreakSlot(mode) && |
615 IsPatchedReturnSequence()) || | 583 IsPatchedDebugBreakSlotSequence()) { |
616 (RelocInfo::IsDebugBreakSlot(mode) && | |
617 IsPatchedDebugBreakSlotSequence()))) { | |
618 StaticVisitor::VisitDebugTarget(heap, this); | 584 StaticVisitor::VisitDebugTarget(heap, this); |
619 } else if (RelocInfo::IsRuntimeEntry(mode)) { | 585 } else if (RelocInfo::IsRuntimeEntry(mode)) { |
620 StaticVisitor::VisitRuntimeEntry(this); | 586 StaticVisitor::VisitRuntimeEntry(this); |
621 } | 587 } |
622 } | 588 } |
623 | 589 |
624 | 590 |
625 // ----------------------------------------------------------------------------- | 591 // ----------------------------------------------------------------------------- |
626 // Implementation of Operand | 592 // Implementation of Operand |
627 | 593 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 | 627 |
662 void Operand::set_disp64(int64_t disp) { | 628 void Operand::set_disp64(int64_t disp) { |
663 DCHECK_EQ(1, len_); | 629 DCHECK_EQ(1, len_); |
664 int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); | 630 int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); |
665 *p = disp; | 631 *p = disp; |
666 len_ += sizeof(disp); | 632 len_ += sizeof(disp); |
667 } | 633 } |
668 } } // namespace v8::internal | 634 } } // namespace v8::internal |
669 | 635 |
670 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 636 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
OLD | NEW |