| 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 } else { | 71 } else { |
| 72 code_targets_.Add(target); | 72 code_targets_.Add(target); |
| 73 emitl(current); | 73 emitl(current); |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 77 | 77 |
| 78 void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { | 78 void Assembler::emit_runtime_entry(Address entry, RelocInfo::Mode rmode) { |
| 79 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); | 79 DCHECK(RelocInfo::IsRuntimeEntry(rmode)); |
| 80 RecordRelocInfo(rmode); | 80 RecordRelocInfo(rmode); |
| 81 emitl(static_cast<uint32_t>( | 81 emitl(static_cast<uint32_t>(entry - isolate_data().code_range_start_)); |
| 82 entry - isolate()->heap()->memory_allocator()->code_range()->start())); | |
| 83 } | 82 } |
| 84 | 83 |
| 85 void Assembler::emit(Immediate x) { | 84 void Assembler::emit(Immediate x) { |
| 86 if (!RelocInfo::IsNone(x.rmode_)) { | 85 if (!RelocInfo::IsNone(x.rmode_)) { |
| 87 RecordRelocInfo(x.rmode_); | 86 RecordRelocInfo(x.rmode_); |
| 88 } | 87 } |
| 89 emitl(x.value_); | 88 emitl(x.value_); |
| 90 } | 89 } |
| 91 | 90 |
| 92 void Assembler::emit_rex_64(Register reg, Register rm_reg) { | 91 void Assembler::emit_rex_64(Register reg, Register rm_reg) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 | 272 |
| 274 | 273 |
| 275 Address Assembler::target_address_at(Address pc, Address constant_pool) { | 274 Address Assembler::target_address_at(Address pc, Address constant_pool) { |
| 276 return Memory::int32_at(pc) + pc + 4; | 275 return Memory::int32_at(pc) + pc + 4; |
| 277 } | 276 } |
| 278 | 277 |
| 279 | 278 |
| 280 void Assembler::set_target_address_at(Isolate* isolate, Address pc, | 279 void Assembler::set_target_address_at(Isolate* isolate, Address pc, |
| 281 Address constant_pool, Address target, | 280 Address constant_pool, Address target, |
| 282 ICacheFlushMode icache_flush_mode) { | 281 ICacheFlushMode icache_flush_mode) { |
| 282 DCHECK_IMPLIES(isolate == nullptr, icache_flush_mode == SKIP_ICACHE_FLUSH); |
| 283 Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); | 283 Memory::int32_at(pc) = static_cast<int32_t>(target - pc - 4); |
| 284 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 284 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 285 Assembler::FlushICache(isolate, pc, sizeof(int32_t)); | 285 Assembler::FlushICache(isolate, pc, sizeof(int32_t)); |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 | 288 |
| 289 Address Assembler::target_address_at(Address pc, Code* code) { | 289 Address Assembler::target_address_at(Address pc, Code* code) { |
| 290 Address constant_pool = code ? code->constant_pool() : NULL; | 290 Address constant_pool = code ? code->constant_pool() : NULL; |
| 291 return target_address_at(pc, constant_pool); | 291 return target_address_at(pc, constant_pool); |
| 292 } | 292 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 312 Isolate* isolate, Address instruction_payload, Code* code, Address target) { | 312 Isolate* isolate, Address instruction_payload, Code* code, Address target) { |
| 313 set_target_address_at(isolate, instruction_payload, code, target); | 313 set_target_address_at(isolate, instruction_payload, code, target); |
| 314 } | 314 } |
| 315 | 315 |
| 316 Handle<Code> Assembler::code_target_object_handle_at(Address pc) { | 316 Handle<Code> Assembler::code_target_object_handle_at(Address pc) { |
| 317 return code_targets_[Memory::int32_at(pc)]; | 317 return code_targets_[Memory::int32_at(pc)]; |
| 318 } | 318 } |
| 319 | 319 |
| 320 | 320 |
| 321 Address Assembler::runtime_entry_at(Address pc) { | 321 Address Assembler::runtime_entry_at(Address pc) { |
| 322 return Memory::int32_at(pc) + | 322 return Memory::int32_at(pc) + isolate_data().code_range_start_; |
| 323 isolate()->heap()->memory_allocator()->code_range()->start(); | |
| 324 } | 323 } |
| 325 | 324 |
| 326 // ----------------------------------------------------------------------------- | 325 // ----------------------------------------------------------------------------- |
| 327 // Implementation of RelocInfo | 326 // Implementation of RelocInfo |
| 328 | 327 |
| 329 // The modes possibly affected by apply must be in kApplyMask. | 328 // The modes possibly affected by apply must be in kApplyMask. |
| 330 void RelocInfo::apply(intptr_t delta) { | 329 void RelocInfo::apply(intptr_t delta) { |
| 331 if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 330 if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
| 332 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); | 331 Memory::int32_at(pc_) -= static_cast<int32_t>(delta); |
| 333 } else if (IsCodeAgeSequence(rmode_)) { | 332 } else if (IsCodeAgeSequence(rmode_)) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 DCHECK(rmode_ == INTERNAL_REFERENCE); | 399 DCHECK(rmode_ == INTERNAL_REFERENCE); |
| 401 return reinterpret_cast<Address>(pc_); | 400 return reinterpret_cast<Address>(pc_); |
| 402 } | 401 } |
| 403 | 402 |
| 404 void RelocInfo::set_target_object(HeapObject* target, | 403 void RelocInfo::set_target_object(HeapObject* target, |
| 405 WriteBarrierMode write_barrier_mode, | 404 WriteBarrierMode write_barrier_mode, |
| 406 ICacheFlushMode icache_flush_mode) { | 405 ICacheFlushMode icache_flush_mode) { |
| 407 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); | 406 DCHECK(IsCodeTarget(rmode_) || rmode_ == EMBEDDED_OBJECT); |
| 408 Memory::Object_at(pc_) = target; | 407 Memory::Object_at(pc_) = target; |
| 409 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 408 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 410 Assembler::FlushICache(isolate_, pc_, sizeof(Address)); | 409 Assembler::FlushICache(target->GetIsolate(), pc_, sizeof(Address)); |
| 411 } | 410 } |
| 412 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { | 411 if (write_barrier_mode == UPDATE_WRITE_BARRIER && host() != NULL) { |
| 413 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, | 412 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, |
| 414 target); | 413 target); |
| 415 host()->GetHeap()->RecordWriteIntoCode(host(), this, target); | 414 host()->GetHeap()->RecordWriteIntoCode(host(), this, target); |
| 416 } | 415 } |
| 417 } | 416 } |
| 418 | 417 |
| 419 | 418 |
| 420 Address RelocInfo::target_runtime_entry(Assembler* origin) { | 419 Address RelocInfo::target_runtime_entry(Assembler* origin) { |
| 421 DCHECK(IsRuntimeEntry(rmode_)); | 420 DCHECK(IsRuntimeEntry(rmode_)); |
| 422 return origin->runtime_entry_at(pc_); | 421 return origin->runtime_entry_at(pc_); |
| 423 } | 422 } |
| 424 | 423 |
| 425 | 424 void RelocInfo::set_target_runtime_entry(Isolate* isolate, Address target, |
| 426 void RelocInfo::set_target_runtime_entry(Address target, | |
| 427 WriteBarrierMode write_barrier_mode, | 425 WriteBarrierMode write_barrier_mode, |
| 428 ICacheFlushMode icache_flush_mode) { | 426 ICacheFlushMode icache_flush_mode) { |
| 429 DCHECK(IsRuntimeEntry(rmode_)); | 427 DCHECK(IsRuntimeEntry(rmode_)); |
| 430 if (target_address() != target) { | 428 if (target_address() != target) { |
| 431 set_target_address(target, write_barrier_mode, icache_flush_mode); | 429 set_target_address(isolate, target, write_barrier_mode, icache_flush_mode); |
| 432 } | 430 } |
| 433 } | 431 } |
| 434 | 432 |
| 435 | 433 |
| 436 Handle<Cell> RelocInfo::target_cell_handle() { | 434 Handle<Cell> RelocInfo::target_cell_handle() { |
| 437 DCHECK(rmode_ == RelocInfo::CELL); | 435 DCHECK(rmode_ == RelocInfo::CELL); |
| 438 Address address = Memory::Address_at(pc_); | 436 Address address = Memory::Address_at(pc_); |
| 439 return Handle<Cell>(reinterpret_cast<Cell**>(address)); | 437 return Handle<Cell>(reinterpret_cast<Cell**>(address)); |
| 440 } | 438 } |
| 441 | 439 |
| 442 | 440 |
| 443 Cell* RelocInfo::target_cell() { | 441 Cell* RelocInfo::target_cell() { |
| 444 DCHECK(rmode_ == RelocInfo::CELL); | 442 DCHECK(rmode_ == RelocInfo::CELL); |
| 445 return Cell::FromValueAddress(Memory::Address_at(pc_)); | 443 return Cell::FromValueAddress(Memory::Address_at(pc_)); |
| 446 } | 444 } |
| 447 | 445 |
| 448 | 446 |
| 449 void RelocInfo::set_target_cell(Cell* cell, | 447 void RelocInfo::set_target_cell(Cell* cell, |
| 450 WriteBarrierMode write_barrier_mode, | 448 WriteBarrierMode write_barrier_mode, |
| 451 ICacheFlushMode icache_flush_mode) { | 449 ICacheFlushMode icache_flush_mode) { |
| 452 DCHECK(rmode_ == RelocInfo::CELL); | 450 DCHECK(rmode_ == RelocInfo::CELL); |
| 453 Address address = cell->address() + Cell::kValueOffset; | 451 Address address = cell->address() + Cell::kValueOffset; |
| 454 Memory::Address_at(pc_) = address; | 452 Memory::Address_at(pc_) = address; |
| 455 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { | 453 if (icache_flush_mode != SKIP_ICACHE_FLUSH) { |
| 456 Assembler::FlushICache(isolate_, pc_, sizeof(Address)); | 454 Assembler::FlushICache(cell->GetIsolate(), pc_, sizeof(Address)); |
| 457 } | 455 } |
| 458 if (write_barrier_mode == UPDATE_WRITE_BARRIER && | 456 if (write_barrier_mode == UPDATE_WRITE_BARRIER && |
| 459 host() != NULL) { | 457 host() != NULL) { |
| 460 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, | 458 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, |
| 461 cell); | 459 cell); |
| 462 } | 460 } |
| 463 } | 461 } |
| 464 | 462 |
| 465 | 463 void RelocInfo::WipeOut(Isolate* isolate) { |
| 466 void RelocInfo::WipeOut() { | |
| 467 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || | 464 if (IsEmbeddedObject(rmode_) || IsExternalReference(rmode_) || |
| 468 IsInternalReference(rmode_)) { | 465 IsInternalReference(rmode_)) { |
| 469 Memory::Address_at(pc_) = NULL; | 466 Memory::Address_at(pc_) = NULL; |
| 470 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { | 467 } else if (IsCodeTarget(rmode_) || IsRuntimeEntry(rmode_)) { |
| 471 // Effectively write zero into the relocation. | 468 // Effectively write zero into the relocation. |
| 472 Assembler::set_target_address_at(isolate_, pc_, host_, | 469 Assembler::set_target_address_at(isolate, pc_, host_, |
| 473 pc_ + sizeof(int32_t)); | 470 pc_ + sizeof(int32_t)); |
| 474 } else { | 471 } else { |
| 475 UNREACHABLE(); | 472 UNREACHABLE(); |
| 476 } | 473 } |
| 477 } | 474 } |
| 478 | 475 |
| 479 Handle<Code> RelocInfo::code_age_stub_handle(Assembler* origin) { | 476 Handle<Code> RelocInfo::code_age_stub_handle(Assembler* origin) { |
| 480 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 477 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 481 DCHECK(*pc_ == kCallOpcode); | 478 DCHECK(*pc_ == kCallOpcode); |
| 482 return origin->code_target_object_handle_at(pc_ + 1); | 479 return origin->code_target_object_handle_at(pc_ + 1); |
| 483 } | 480 } |
| 484 | 481 |
| 485 | 482 |
| 486 Code* RelocInfo::code_age_stub() { | 483 Code* RelocInfo::code_age_stub() { |
| 487 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 484 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 488 DCHECK(*pc_ == kCallOpcode); | 485 DCHECK(*pc_ == kCallOpcode); |
| 489 return Code::GetCodeFromTargetAddress( | 486 return Code::GetCodeFromTargetAddress( |
| 490 Assembler::target_address_at(pc_ + 1, host_)); | 487 Assembler::target_address_at(pc_ + 1, host_)); |
| 491 } | 488 } |
| 492 | 489 |
| 493 | 490 |
| 494 void RelocInfo::set_code_age_stub(Code* stub, | 491 void RelocInfo::set_code_age_stub(Code* stub, |
| 495 ICacheFlushMode icache_flush_mode) { | 492 ICacheFlushMode icache_flush_mode) { |
| 496 DCHECK(*pc_ == kCallOpcode); | 493 DCHECK(*pc_ == kCallOpcode); |
| 497 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); | 494 DCHECK(rmode_ == RelocInfo::CODE_AGE_SEQUENCE); |
| 498 Assembler::set_target_address_at( | 495 Assembler::set_target_address_at(stub->GetIsolate(), pc_ + 1, host_, |
| 499 isolate_, pc_ + 1, host_, stub->instruction_start(), icache_flush_mode); | 496 stub->instruction_start(), |
| 497 icache_flush_mode); |
| 500 } | 498 } |
| 501 | 499 |
| 502 | 500 |
| 503 Address RelocInfo::debug_call_address() { | 501 Address RelocInfo::debug_call_address() { |
| 504 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); | 502 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
| 505 return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); | 503 return Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset); |
| 506 } | 504 } |
| 507 | 505 |
| 508 | 506 void RelocInfo::set_debug_call_address(Isolate* isolate, Address target) { |
| 509 void RelocInfo::set_debug_call_address(Address target) { | |
| 510 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); | 507 DCHECK(IsDebugBreakSlot(rmode()) && IsPatchedDebugBreakSlotSequence()); |
| 511 Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) = | 508 Memory::Address_at(pc_ + Assembler::kPatchDebugBreakSlotAddressOffset) = |
| 512 target; | 509 target; |
| 513 Assembler::FlushICache(isolate_, | 510 Assembler::FlushICache(isolate, |
| 514 pc_ + Assembler::kPatchDebugBreakSlotAddressOffset, | 511 pc_ + Assembler::kPatchDebugBreakSlotAddressOffset, |
| 515 sizeof(Address)); | 512 sizeof(Address)); |
| 516 if (host() != NULL) { | 513 if (host() != NULL) { |
| 517 Code* target_code = Code::GetCodeFromTargetAddress(target); | 514 Code* target_code = Code::GetCodeFromTargetAddress(target); |
| 518 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, | 515 host()->GetHeap()->incremental_marking()->RecordWriteIntoCode(host(), this, |
| 519 target_code); | 516 target_code); |
| 520 } | 517 } |
| 521 } | 518 } |
| 522 | 519 |
| 523 template <typename ObjectVisitor> | 520 template <typename ObjectVisitor> |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 void Operand::set_disp64(int64_t disp) { | 607 void Operand::set_disp64(int64_t disp) { |
| 611 DCHECK_EQ(1, len_); | 608 DCHECK_EQ(1, len_); |
| 612 int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); | 609 int64_t* p = reinterpret_cast<int64_t*>(&buf_[len_]); |
| 613 *p = disp; | 610 *p = disp; |
| 614 len_ += sizeof(disp); | 611 len_ += sizeof(disp); |
| 615 } | 612 } |
| 616 } // namespace internal | 613 } // namespace internal |
| 617 } // namespace v8 | 614 } // namespace v8 |
| 618 | 615 |
| 619 #endif // V8_X64_ASSEMBLER_X64_INL_H_ | 616 #endif // V8_X64_ASSEMBLER_X64_INL_H_ |
| OLD | NEW |