Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(169)

Unified Diff: runtime/vm/assembler_arm.cc

Issue 1343373003: Revert "VM: New calling convention for generated code." (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_arm.cc
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index d5fecd6d117dca82bb07c45a00d2d4e0fe7d532b..afb5744960a19789ed8a5b8d27763062f13fd6f7 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -1534,64 +1534,34 @@ intptr_t Assembler::FindImmediate(int32_t imm) {
// Uses a code sequence that can easily be decoded.
void Assembler::LoadWordFromPoolOffset(Register rd,
int32_t offset,
- Register pp,
Condition cond) {
- ASSERT((pp != PP) || constant_pool_allowed());
- ASSERT(rd != pp);
+ ASSERT(constant_pool_allowed());
+ ASSERT(rd != PP);
int32_t offset_mask = 0;
if (Address::CanHoldLoadOffset(kWord, offset, &offset_mask)) {
- ldr(rd, Address(pp, offset), cond);
+ ldr(rd, Address(PP, offset), cond);
} else {
int32_t offset_hi = offset & ~offset_mask; // signed
uint32_t offset_lo = offset & offset_mask; // unsigned
- // Inline a simplified version of AddImmediate(rd, pp, offset_hi).
+ // Inline a simplified version of AddImmediate(rd, PP, offset_hi).
Operand o;
if (Operand::CanHold(offset_hi, &o)) {
- add(rd, pp, o, cond);
+ add(rd, PP, o, cond);
} else {
LoadImmediate(rd, offset_hi, cond);
- add(rd, pp, Operand(rd), cond);
+ add(rd, PP, Operand(rd), cond);
}
ldr(rd, Address(rd, offset_lo), cond);
}
}
-void Assembler::CheckCodePointer() {
-#ifdef DEBUG
- Label cid_ok, instructions_ok;
- Push(R0);
- Push(IP);
- CompareClassId(CODE_REG, kCodeCid, R0);
- b(&cid_ok, EQ);
- bkpt(0);
- Bind(&cid_ok);
-
- const intptr_t offset = CodeSize() + Instr::kPCReadOffset +
- Instructions::HeaderSize() - kHeapObjectTag;
- mov(R0, Operand(PC));
- AddImmediate(R0, R0, -offset);
- ldr(IP, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
- cmp(R0, Operand(IP));
- b(&instructions_ok, EQ);
- bkpt(1);
- Bind(&instructions_ok);
- Pop(IP);
- Pop(R0);
-#endif
-}
-
-
-void Assembler::RestoreCodePointer() {
- ldr(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize));
- CheckCodePointer();
-}
-
-void Assembler::LoadPoolPointer(Register reg) {
- // Load new pool pointer.
- CheckCodePointer();
- ldr(reg, FieldAddress(CODE_REG, Code::object_pool_offset()));
- set_constant_pool_allowed(reg == PP);
+void Assembler::LoadPoolPointer() {
+ const intptr_t object_pool_pc_dist =
+ Instructions::HeaderSize() - Instructions::object_pool_offset() +
+ CodeSize() + Instr::kPCReadOffset;
+ LoadFromOffset(kWord, PP, PC, -object_pool_pc_dist);
+ set_constant_pool_allowed(true);
}
@@ -1603,8 +1573,7 @@ void Assembler::LoadIsolate(Register rd) {
void Assembler::LoadObjectHelper(Register rd,
const Object& object,
Condition cond,
- bool is_unique,
- Register pp) {
+ bool is_unique) {
// Load common VM constants from the thread. This works also in places where
// no constant pool is set up (e.g. intrinsic code).
if (Thread::CanLoadFromThread(object)) {
@@ -1625,20 +1594,20 @@ void Assembler::LoadObjectHelper(Register rd,
const int32_t offset = ObjectPool::element_offset(
is_unique ? object_pool_wrapper_.AddObject(object)
: object_pool_wrapper_.FindObject(object));
- LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
+ LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
}
}
void Assembler::LoadObject(Register rd, const Object& object, Condition cond) {
- LoadObjectHelper(rd, object, cond, /* is_unique = */ false, PP);
+ LoadObjectHelper(rd, object, cond, false);
}
void Assembler::LoadUniqueObject(Register rd,
const Object& object,
Condition cond) {
- LoadObjectHelper(rd, object, cond, /* is_unique = */ true, PP);
+ LoadObjectHelper(rd, object, cond, true);
}
@@ -1648,16 +1617,7 @@ void Assembler::LoadExternalLabel(Register rd,
Condition cond) {
const int32_t offset = ObjectPool::element_offset(
object_pool_wrapper_.FindExternalLabel(label, patchable));
- LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
-}
-
-
-void Assembler::LoadFunctionFromCalleePool(Register dst,
- const Function& function,
- Register new_pp) {
- const int32_t offset =
- ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
- LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp, AL);
+ LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
}
@@ -1667,7 +1627,7 @@ void Assembler::LoadNativeEntry(Register rd,
Condition cond) {
const int32_t offset = ObjectPool::element_offset(
object_pool_wrapper_.FindNativeEntry(label, patchable));
- LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
+ LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
}
@@ -1864,7 +1824,7 @@ void Assembler::StoreIntoObject(Register object,
StoreIntoObjectFilterNoSmi(object, value, &done);
}
// A store buffer update is required.
- RegList regs = (1 << CODE_REG) | (1 << LR);
+ RegList regs = (1 << LR);
if (value != R0) {
regs |= (1 << R0); // Preserve R0.
}
@@ -1872,7 +1832,6 @@ void Assembler::StoreIntoObject(Register object,
if (object != R0) {
mov(R0, Operand(object));
}
- ldr(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
ldr(LR, Address(THR, Thread::update_store_buffer_entry_point_offset()));
blx(LR);
PopList(regs);
@@ -2728,52 +2687,49 @@ void Assembler::Vdivqs(QRegister qd, QRegister qn, QRegister qm) {
}
-void Assembler::Branch(const StubEntry& stub_entry,
- Patchability patchable,
- Register pp,
- Condition cond) {
- const Code& target_code = Code::Handle(stub_entry.code());
- const int32_t offset = ObjectPool::element_offset(
- object_pool_wrapper_.FindObject(target_code, patchable));
- LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond);
- ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()), cond);
+void Assembler::Branch(const StubEntry& stub_entry, Condition cond) {
+ // Address is never patched.
+ LoadImmediate(IP, stub_entry.label().address(), cond);
bx(IP, cond);
}
-void Assembler::BranchLink(const Code& target, Patchability patchable) {
+void Assembler::BranchPatchable(const StubEntry& stub_entry) {
+ // Use a fixed size code sequence, since a function prologue may be patched
+ // with this branch sequence.
+ // Contrarily to BranchLinkPatchable, BranchPatchable requires an instruction
+ // cache flush upon patching.
+ LoadPatchableImmediate(IP, stub_entry.label().address());
+ bx(IP);
+}
+
+
+void Assembler::BranchLink(const ExternalLabel* label) {
+ LoadImmediate(LR, label->address()); // Target address is never patched.
+ blx(LR); // Use blx instruction so that the return branch prediction works.
+}
+
+
+void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) {
// Make sure that class CallPattern is able to patch the label referred
// to by this code sequence.
// For added code robustness, use 'blx lr' in a patchable sequence and
// use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
const int32_t offset = ObjectPool::element_offset(
- object_pool_wrapper_.FindObject(target, patchable));
- LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL);
- ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ object_pool_wrapper_.FindExternalLabel(label, patchable));
+ LoadWordFromPoolOffset(LR, offset - kHeapObjectTag, AL);
blx(LR); // Use blx instruction so that the return branch prediction works.
}
void Assembler::BranchLink(const StubEntry& stub_entry,
Patchability patchable) {
- const Code& code = Code::Handle(stub_entry.code());
- BranchLink(code, patchable);
-}
-
-
-void Assembler::BranchLinkPatchable(const Code& target) {
- BranchLink(target, kPatchable);
-}
-
-
-void Assembler::BranchLink(const ExternalLabel* label) {
- LoadImmediate(LR, label->address()); // Target address is never patched.
- blx(LR); // Use blx instruction so that the return branch prediction works.
+ BranchLink(&stub_entry.label(), patchable);
}
void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
- BranchLinkPatchable(Code::Handle(stub_entry.code()));
+ BranchLink(&stub_entry.label(), kPatchable);
}
@@ -2814,7 +2770,7 @@ void Assembler::LoadDecodableImmediate(
if ((version == ARMv5TE) || (version == ARMv6)) {
if (constant_pool_allowed()) {
const int32_t offset = Array::element_offset(FindImmediate(value));
- LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
+ LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, cond);
} else {
LoadPatchableImmediate(rd, value, cond);
}
@@ -3349,11 +3305,20 @@ void Assembler::CallRuntime(const RuntimeEntry& entry,
void Assembler::EnterDartFrame(intptr_t frame_size) {
- CheckCodePointer();
ASSERT(!constant_pool_allowed());
+ const intptr_t offset = CodeSize();
- // Registers are pushed in descending order: R9 | R10 | R11 | R14.
- EnterFrame((1 << PP) | (1 << CODE_REG) | (1 << FP) | (1 << LR), 0);
+ // Save PC in frame for fast identification of corresponding code.
+ // Note that callee-saved registers can be added to the register list.
+ EnterFrame((1 << PP) | (1 << FP) | (1 << LR) | (1 << PC), 0);
+
+ if (offset != 0) {
+ // Adjust saved PC for any intrinsic code that could have been generated
+ // before a frame is created. Use PP as temp register.
+ ldr(PP, Address(FP, 2 * kWordSize));
+ AddImmediate(PP, PP, -offset);
+ str(PP, Address(FP, 2 * kWordSize));
+ }
// Setup pool pointer for this dart function.
LoadPoolPointer();
@@ -3370,26 +3335,41 @@ void Assembler::EnterDartFrame(intptr_t frame_size) {
// allocate. We must also set up the pool pointer for the function.
void Assembler::EnterOsrFrame(intptr_t extra_size) {
ASSERT(!constant_pool_allowed());
+ // mov(IP, Operand(PC)) loads PC + Instr::kPCReadOffset (8). This may be
+ // different from EntryPointToPcMarkerOffset().
+ const intptr_t offset =
+ CodeSize() + Instr::kPCReadOffset - EntryPointToPcMarkerOffset();
+
Comment("EnterOsrFrame");
- RestoreCodePointer();
+ mov(IP, Operand(PC));
+
+ AddImmediate(IP, -offset);
+ str(IP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
+
+ // Setup pool pointer for this dart function.
LoadPoolPointer();
AddImmediate(SP, -extra_size);
}
-void Assembler::LeaveDartFrame(RestorePP restore_pp) {
- if (restore_pp == kRestoreCallerPP) {
- ldr(PP, Address(FP, kSavedCallerPpSlotFromFp * kWordSize));
- set_constant_pool_allowed(false);
- }
- Drop(2); // Drop saved PP, PC marker.
- LeaveFrame((1 << FP) | (1 << LR));
+void Assembler::LeaveDartFrame() {
+ set_constant_pool_allowed(false);
+ LeaveFrame((1 << PP) | (1 << FP) | (1 << LR));
+ // Adjust SP for PC pushed in EnterDartFrame.
+ AddImmediate(SP, kWordSize);
}
void Assembler::EnterStubFrame() {
- EnterDartFrame(0);
+ set_constant_pool_allowed(false);
+ // Push 0 as saved PC for stub frames.
+ mov(IP, Operand(LR));
+ mov(LR, Operand(0));
+ RegList regs = (1 << PP) | (1 << FP) | (1 << IP) | (1 << LR);
+ EnterFrame(regs, 0);
+ // Setup pool pointer for this stub.
+ LoadPoolPointer();
}
« no previous file with comments | « runtime/vm/assembler_arm.h ('k') | runtime/vm/assembler_arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698