Index: runtime/vm/assembler_x64.cc |
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc |
index e39d8b21aecfb658f2ee652343ffeb8c386218f4..523f29f9ca8fdc3cc7229e3fe75c955c6445f283 100644 |
--- a/runtime/vm/assembler_x64.cc |
+++ b/runtime/vm/assembler_x64.cc |
@@ -93,25 +93,20 @@ void Assembler::call(const ExternalLabel* label) { |
void Assembler::CallPatchable(const StubEntry& stub_entry) { |
ASSERT(constant_pool_allowed()); |
- const Code& target = Code::Handle(stub_entry.code()); |
intptr_t call_start = buffer_.GetPosition(); |
const int32_t offset = ObjectPool::element_offset( |
- object_pool_wrapper_.FindObject(target, kPatchable)); |
- LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); |
- movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
- call(TMP); |
+ object_pool_wrapper_.FindExternalLabel(&stub_entry.label(), kPatchable)); |
+ call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); |
ASSERT((buffer_.GetPosition() - call_start) == kCallExternalLabelSize); |
} |
void Assembler::Call(const StubEntry& stub_entry) { |
ASSERT(constant_pool_allowed()); |
- const Code& target = Code::Handle(stub_entry.code()); |
const int32_t offset = ObjectPool::element_offset( |
- object_pool_wrapper_.FindObject(target, kNotPatchable)); |
- LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag); |
- movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
- call(TMP); |
+ object_pool_wrapper_.FindExternalLabel(&stub_entry.label(), |
+ kNotPatchable)); |
+ call(Address::AddressBaseImm32(PP, offset - kHeapObjectTag)); |
} |
@@ -2548,12 +2543,11 @@ void Assembler::j(Condition condition, Label* label, bool near) { |
} |
-void Assembler::J(Condition condition, |
- const StubEntry& stub_entry, |
+void Assembler::J(Condition condition, const StubEntry& stub_entry, |
Register pp) { |
Label no_jump; |
// Negate condition. |
- j(static_cast<Condition>(condition ^ 1), &no_jump, kNearJump); |
+ j(static_cast<Condition>(condition ^ 1), &no_jump, Assembler::kNearJump); |
Jmp(stub_entry, pp); |
Bind(&no_jump); |
} |
@@ -2614,25 +2608,28 @@ void Assembler::jmp(const ExternalLabel* label) { |
} |
+void Assembler::jmp(const StubEntry& stub_entry) { |
+ jmp(&stub_entry.label()); |
+} |
+ |
+ |
void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) { |
ASSERT((pp != PP) || constant_pool_allowed()); |
- const Code& target = Code::Handle(stub_entry.code()); |
+ intptr_t call_start = buffer_.GetPosition(); |
const int32_t offset = ObjectPool::element_offset( |
- object_pool_wrapper_.FindObject(target, kPatchable)); |
- movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
- movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
- jmp(TMP); |
+ object_pool_wrapper_.FindExternalLabel(&stub_entry.label(), kPatchable)); |
+ // Patchable jumps always use a 32-bit immediate encoding. |
+ jmp(Address::AddressBaseImm32(pp, offset - kHeapObjectTag)); |
+ ASSERT((buffer_.GetPosition() - call_start) == JumpPattern::kLengthInBytes); |
} |
void Assembler::Jmp(const StubEntry& stub_entry, Register pp) { |
ASSERT((pp != PP) || constant_pool_allowed()); |
- const Code& target = Code::Handle(stub_entry.code()); |
const int32_t offset = ObjectPool::element_offset( |
- object_pool_wrapper_.FindObject(target, kNotPatchable)); |
- movq(CODE_REG, FieldAddress(pp, offset)); |
- movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset())); |
- jmp(TMP); |
+ object_pool_wrapper_.FindExternalLabel(&stub_entry.label(), |
+ kNotPatchable)); |
+ jmp(Address(pp, offset - kHeapObjectTag)); |
} |
@@ -3080,12 +3077,8 @@ void Assembler::StoreIntoObject(Register object, |
if (object != RDX) { |
movq(RDX, object); |
} |
- pushq(CODE_REG); |
- movq(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset())); |
movq(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset())); |
call(TMP); |
- |
- popq(CODE_REG); |
if (value != RDX) popq(RDX); |
Bind(&done); |
} |
@@ -3386,30 +3379,27 @@ void Assembler::CallRuntime(const RuntimeEntry& entry, |
} |
-void Assembler::RestoreCodePointer() { |
- movq(CODE_REG, Address(RBP, kPcMarkerSlotFromFp * kWordSize)); |
-} |
- |
- |
void Assembler::LoadPoolPointer(Register pp) { |
// Load new pool pointer. |
- CheckCodePointer(); |
- movq(pp, FieldAddress(CODE_REG, Code::object_pool_offset())); |
+ const intptr_t kRIPRelativeMovqSize = 7; |
+ const intptr_t entry_to_rip_offset = CodeSize() + kRIPRelativeMovqSize; |
+ const intptr_t object_pool_pc_dist = |
+ Instructions::HeaderSize() - Instructions::object_pool_offset(); |
+ movq(pp, Address::AddressRIPRelative( |
+ -entry_to_rip_offset - object_pool_pc_dist)); |
+ ASSERT(CodeSize() == entry_to_rip_offset); |
set_constant_pool_allowed(pp == PP); |
} |
-void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) { |
- CheckCodePointer(); |
+void Assembler::EnterDartFrame(intptr_t frame_size, |
+ Register new_pp, |
+ Register pc_marker_override) { |
ASSERT(!constant_pool_allowed()); |
EnterFrame(0); |
- pushq(CODE_REG); |
+ pushq(pc_marker_override); |
pushq(PP); |
- if (new_pp == kNoRegister) { |
- LoadPoolPointer(PP); |
- } else { |
- movq(PP, new_pp); |
- } |
+ movq(PP, new_pp); |
set_constant_pool_allowed(true); |
if (frame_size != 0) { |
subq(RSP, Immediate(frame_size)); |
@@ -3417,57 +3407,30 @@ void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) { |
} |
-void Assembler::LeaveDartFrame(RestorePP restore_pp) { |
+void Assembler::LeaveDartFrame() { |
+ set_constant_pool_allowed(false); |
// Restore caller's PP register that was pushed in EnterDartFrame. |
- if (restore_pp == kRestoreCallerPP) { |
- movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); |
- set_constant_pool_allowed(false); |
- } |
+ movq(PP, Address(RBP, (kSavedCallerPpSlotFromFp * kWordSize))); |
LeaveFrame(); |
} |
-void Assembler::CheckCodePointer() { |
-#ifdef DEBUG |
- Label cid_ok, instructions_ok; |
- pushq(RAX); |
- LoadClassId(RAX, CODE_REG); |
- cmpq(RAX, Immediate(kCodeCid)); |
- j(EQUAL, &cid_ok); |
- int3(); |
- Bind(&cid_ok); |
- { |
- const intptr_t kRIPRelativeLeaqSize = 7; |
- const intptr_t header_to_entry_offset = |
- (Instructions::HeaderSize() - kHeapObjectTag); |
- const intptr_t header_to_rip_offset = |
- CodeSize() + kRIPRelativeLeaqSize + header_to_entry_offset; |
- leaq(RAX, Address::AddressRIPRelative(-header_to_rip_offset)); |
- ASSERT(CodeSize() == (header_to_rip_offset - header_to_entry_offset)); |
- } |
- cmpq(RAX, FieldAddress(CODE_REG, Code::saved_instructions_offset())); |
- j(EQUAL, &instructions_ok); |
- int3(); |
- Bind(&instructions_ok); |
- popq(RAX); |
-#endif |
-} |
- |
- |
// On entry to a function compiled for OSR, the caller's frame pointer, the |
// stack locals, and any copied parameters are already in place. The frame |
// pointer is already set up. The PC marker is not correct for the |
// optimized function and there may be extra space for spill slots to |
// allocate. |
-void Assembler::EnterOsrFrame(intptr_t extra_size) { |
+void Assembler::EnterOsrFrame(intptr_t extra_size, |
+ Register new_pp, |
+ Register pc_marker_override) { |
ASSERT(!constant_pool_allowed()); |
if (prologue_offset_ == -1) { |
Comment("PrologueOffset = %" Pd "", CodeSize()); |
prologue_offset_ = CodeSize(); |
} |
- RestoreCodePointer(); |
- LoadPoolPointer(); |
- |
+ movq(Address(RBP, kPcMarkerSlotFromFp * kWordSize), pc_marker_override); |
+ movq(PP, new_pp); |
+ set_constant_pool_allowed(true); |
if (extra_size != 0) { |
subq(RSP, Immediate(extra_size)); |
} |
@@ -3475,7 +3438,11 @@ void Assembler::EnterOsrFrame(intptr_t extra_size) { |
void Assembler::EnterStubFrame() { |
- EnterDartFrame(0, kNoRegister); |
+ set_constant_pool_allowed(false); |
+ EnterFrame(0); |
+ pushq(Immediate(0)); // Push 0 in the saved PC area for stub frames. |
+ pushq(PP); // Save caller's pool pointer |
+ LoadPoolPointer(); |
} |