| Index: runtime/vm/assembler_arm64.cc
|
| diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
|
| index c679d548e6eea6fc2d66e1d62f88f08d019985f0..a360a2d8d854f762fc04637cddbf8865b9c36ce1 100644
|
| --- a/runtime/vm/assembler_arm64.cc
|
| +++ b/runtime/vm/assembler_arm64.cc
|
| @@ -304,8 +304,11 @@ bool Operand::IsImmLogical(uint64_t value, uint8_t width, Operand* imm_op) {
|
|
|
|
|
| void Assembler::LoadPoolPointer(Register pp) {
|
| - CheckCodePointer();
|
| - ldr(pp, FieldAddress(CODE_REG, Code::object_pool_offset()));
|
| + const intptr_t object_pool_pc_dist =
|
| + Instructions::HeaderSize() - Instructions::object_pool_offset() +
|
| + CodeSize();
|
| + // PP <- Read(PC - object_pool_pc_dist).
|
| + ldr(pp, Address::PC(-object_pool_pc_dist));
|
|
|
| // When in the PP register, the pool pointer is untagged. When we
|
| // push it on the stack with TagAndPushPP it is tagged again. PopAndUntagPP
|
| @@ -318,20 +321,18 @@ void Assembler::LoadPoolPointer(Register pp) {
|
| }
|
|
|
|
|
| -void Assembler::LoadWordFromPoolOffset(Register dst,
|
| - uint32_t offset,
|
| - Register pp) {
|
| - ASSERT((pp != PP) || constant_pool_allowed());
|
| - ASSERT(dst != pp);
|
| +void Assembler::LoadWordFromPoolOffset(Register dst, uint32_t offset) {
|
| + ASSERT(constant_pool_allowed());
|
| + ASSERT(dst != PP);
|
| Operand op;
|
| const uint32_t upper20 = offset & 0xfffff000;
|
| if (Address::CanHoldOffset(offset)) {
|
| - ldr(dst, Address(pp, offset));
|
| + ldr(dst, Address(PP, offset));
|
| } else if (Operand::CanHold(upper20, kXRegSizeInBits, &op) ==
|
| Operand::Immediate) {
|
| const uint32_t lower12 = offset & 0x00000fff;
|
| ASSERT(Address::CanHoldOffset(lower12));
|
| - add(dst, pp, op);
|
| + add(dst, PP, op);
|
| ldr(dst, Address(dst, lower12));
|
| } else {
|
| const uint16_t offset_low = Utils::Low16Bits(offset);
|
| @@ -340,7 +341,7 @@ void Assembler::LoadWordFromPoolOffset(Register dst,
|
| if (offset_high != 0) {
|
| movk(dst, Immediate(offset_high), 1);
|
| }
|
| - ldr(dst, Address(pp, dst));
|
| + ldr(dst, Address(PP, dst));
|
| }
|
| }
|
|
|
| @@ -594,35 +595,48 @@ void Assembler::LoadDImmediate(VRegister vd, double immd) {
|
| }
|
|
|
|
|
| -void Assembler::Branch(const StubEntry& stub_entry,
|
| - Register pp,
|
| - Patchability patchable) {
|
| - const Code& target = Code::Handle(stub_entry.code());
|
| - const int32_t offset = ObjectPool::element_offset(
|
| - object_pool_wrapper_.FindObject(target, patchable));
|
| - LoadWordFromPoolOffset(CODE_REG, offset, pp);
|
| - ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
|
| +void Assembler::Branch(const ExternalLabel* label) {
|
| + LoadExternalLabel(TMP, label);
|
| + br(TMP);
|
| +}
|
| +
|
| +
|
| +void Assembler::Branch(const StubEntry& stub_entry) {
|
| + const ExternalLabel label(stub_entry.EntryPoint());
|
| + Branch(&label);
|
| +}
|
| +
|
| +
|
| +void Assembler::BranchPatchable(const ExternalLabel* label) {
|
| + // TODO(zra): Use LoadExternalLabelFixed if possible.
|
| + LoadImmediateFixed(TMP, label->address());
|
| br(TMP);
|
| }
|
|
|
| void Assembler::BranchPatchable(const StubEntry& stub_entry) {
|
| - Branch(stub_entry, PP, kPatchable);
|
| + BranchPatchable(&stub_entry.label());
|
| }
|
|
|
|
|
| -void Assembler::BranchLink(const StubEntry& stub_entry,
|
| - Patchability patchable) {
|
| - const Code& target = Code::Handle(stub_entry.code());
|
| - const int32_t offset = ObjectPool::element_offset(
|
| - object_pool_wrapper_.FindObject(target, patchable));
|
| - LoadWordFromPoolOffset(CODE_REG, offset);
|
| - ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
|
| +void Assembler::BranchLink(const ExternalLabel* label) {
|
| + LoadExternalLabel(TMP, label);
|
| + blr(TMP);
|
| +}
|
| +
|
| +
|
| +void Assembler::BranchLink(const StubEntry& stub_entry) {
|
| + BranchLink(&stub_entry.label());
|
| +}
|
| +
|
| +
|
| +void Assembler::BranchLinkPatchable(const ExternalLabel* label) {
|
| + LoadExternalLabelFixed(TMP, label, kPatchable);
|
| blr(TMP);
|
| }
|
|
|
|
|
| void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
|
| - BranchLink(stub_entry, kPatchable);
|
| + BranchLinkPatchable(&stub_entry.label());
|
| }
|
|
|
|
|
| @@ -912,7 +926,6 @@ void Assembler::StoreIntoObject(Register object,
|
| if (object != R0) {
|
| mov(R0, object);
|
| }
|
| - ldr(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
|
| ldr(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset()));
|
| blr(TMP);
|
| Pop(LR);
|
| @@ -1089,34 +1102,6 @@ void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
|
| }
|
|
|
|
|
| -void Assembler::RestoreCodePointer() {
|
| - ldr(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize));
|
| - CheckCodePointer();
|
| -}
|
| -
|
| -
|
| -void Assembler::CheckCodePointer() {
|
| -#ifdef DEBUG
|
| - Label cid_ok, instructions_ok;
|
| - Push(R0);
|
| - CompareClassId(CODE_REG, kCodeCid);
|
| - b(&cid_ok, EQ);
|
| - brk(0);
|
| - Bind(&cid_ok);
|
| -
|
| - const intptr_t entry_offset =
|
| - CodeSize() + Instructions::HeaderSize() - kHeapObjectTag;
|
| - adr(R0, Immediate(-entry_offset));
|
| - ldr(TMP, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
|
| - cmp(R0, Operand(TMP));
|
| - b(&instructions_ok, EQ);
|
| - brk(1);
|
| - Bind(&instructions_ok);
|
| - Pop(R0);
|
| -#endif
|
| -}
|
| -
|
| -
|
| void Assembler::EnterFrame(intptr_t frame_size) {
|
| PushPair(LR, FP);
|
| mov(FP, SP);
|
| @@ -1134,11 +1119,11 @@ void Assembler::LeaveFrame() {
|
|
|
|
|
| void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) {
|
| - CheckCodePointer();
|
| ASSERT(!constant_pool_allowed());
|
| // Setup the frame.
|
| + adr(TMP, Immediate(-CodeSize())); // TMP gets PC marker.
|
| EnterFrame(0);
|
| - TagAndPushPPAndPcMarker(); // Save PP and PC marker.
|
| + TagAndPushPPAndPcMarker(TMP); // Save PP and PC marker.
|
|
|
| // Load the pool pointer.
|
| if (new_pp == kNoRegister) {
|
| @@ -1163,8 +1148,17 @@ void Assembler::EnterDartFrame(intptr_t frame_size, Register new_pp) {
|
| void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) {
|
| ASSERT(!constant_pool_allowed());
|
| Comment("EnterOsrFrame");
|
| - RestoreCodePointer();
|
| - LoadPoolPointer();
|
| + adr(TMP, Immediate(-CodeSize()));
|
| +
|
| + StoreToOffset(TMP, FP, kPcMarkerSlotFromFp * kWordSize);
|
| +
|
| + // Setup pool pointer for this dart function.
|
| + if (new_pp == kNoRegister) {
|
| + LoadPoolPointer();
|
| + } else {
|
| + mov(PP, new_pp);
|
| + set_constant_pool_allowed(true);
|
| + }
|
|
|
| if (extra_size > 0) {
|
| AddImmediate(SP, SP, -extra_size);
|
| @@ -1172,13 +1166,11 @@ void Assembler::EnterOsrFrame(intptr_t extra_size, Register new_pp) {
|
| }
|
|
|
|
|
| -void Assembler::LeaveDartFrame(RestorePP restore_pp) {
|
| - if (restore_pp == kRestoreCallerPP) {
|
| - set_constant_pool_allowed(false);
|
| - // Restore and untag PP.
|
| - LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
|
| - sub(PP, PP, Operand(kHeapObjectTag));
|
| - }
|
| +void Assembler::LeaveDartFrame() {
|
| + set_constant_pool_allowed(false);
|
| + // Restore and untag PP.
|
| + LoadFromOffset(PP, FP, kSavedCallerPpSlotFromFp * kWordSize);
|
| + sub(PP, PP, Operand(kHeapObjectTag));
|
| LeaveFrame();
|
| }
|
|
|
| @@ -1244,7 +1236,11 @@ void Assembler::CallRuntime(const RuntimeEntry& entry,
|
|
|
|
|
| void Assembler::EnterStubFrame() {
|
| - EnterDartFrame(0);
|
| + set_constant_pool_allowed(false);
|
| + EnterFrame(0);
|
| + // Save caller's pool pointer. Push 0 in the saved PC area for stub frames.
|
| + TagAndPushPPAndPcMarker(ZR);
|
| + LoadPoolPointer();
|
| }
|
|
|
|
|
|
|