| 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 |