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 |