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

Unified Diff: runtime/vm/assembler_mips.cc

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed comments 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_mips.h ('k') | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/assembler_mips.cc
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index b9227a48624df7cc8b1dd63e756e66c2796adec7..954978ff291aca9785291962dc40a2549014e6c2 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -355,22 +355,24 @@ void Assembler::Bind(Label* label) {
}
-void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) {
- ASSERT(constant_pool_allowed());
+void Assembler::LoadWordFromPoolOffset(Register rd,
+ int32_t offset,
+ Register pp) {
+ ASSERT((pp != PP) || constant_pool_allowed());
ASSERT(!in_delay_slot_);
- ASSERT(rd != PP);
+ ASSERT(rd != pp);
if (Address::CanHoldOffset(offset)) {
- lw(rd, Address(PP, offset));
+ lw(rd, Address(pp, offset));
} else {
const int16_t offset_low = Utils::Low16Bits(offset); // Signed.
offset -= offset_low;
const uint16_t offset_high = Utils::High16Bits(offset); // Unsigned.
if (offset_high != 0) {
lui(rd, Immediate(offset_high));
- addu(rd, rd, PP);
+ addu(rd, rd, pp);
lw(rd, Address(rd, offset_low));
} else {
- lw(rd, Address(PP, offset_low));
+ lw(rd, Address(pp, offset_low));
}
}
}
@@ -457,22 +459,43 @@ void Assembler::SubuDetectOverflow(Register rd, Register rs, Register rt,
}
-void Assembler::Branch(const StubEntry& stub_entry) {
- ASSERT(!in_delay_slot_);
- LoadImmediate(TMP, stub_entry.label().address());
- jr(TMP);
+void Assembler::CheckCodePointer() {
+#ifdef DEBUG
+ Label cid_ok, instructions_ok;
+ Push(CMPRES1);
+ Push(CMPRES2);
+ LoadClassId(CMPRES1, CODE_REG);
+ BranchEqual(CMPRES1, Immediate(kCodeCid), &cid_ok);
+ break_(0);
+ Bind(&cid_ok);
+ GetNextPC(CMPRES1, TMP);
+ const intptr_t entry_offset = CodeSize() - Instr::kInstrSize +
+ Instructions::HeaderSize() - kHeapObjectTag;
+ AddImmediate(CMPRES1, CMPRES1, -entry_offset);
+ lw(CMPRES2, FieldAddress(CODE_REG, Code::saved_instructions_offset()));
+ BranchEqual(CMPRES1, CMPRES2, &instructions_ok);
+ break_(1);
+ Bind(&instructions_ok);
+ Pop(CMPRES2);
+ Pop(CMPRES1);
+#endif
}
-void Assembler::BranchPatchable(const StubEntry& stub_entry) {
+void Assembler::RestoreCodePointer() {
+ lw(CODE_REG, Address(FP, kPcMarkerSlotFromFp * kWordSize));
+ CheckCodePointer();
+}
+
+
+void Assembler::Branch(const StubEntry& stub_entry, Register pp) {
ASSERT(!in_delay_slot_);
- const ExternalLabel& label = stub_entry.label();
- const uint16_t low = Utils::Low16Bits(label.address());
- const uint16_t high = Utils::High16Bits(label.address());
- lui(T9, Immediate(high));
- ori(T9, T9, Immediate(low));
- jr(T9);
- delay_slot_available_ = false; // CodePatcher expects a nop.
+ const Code& target_code = Code::Handle(stub_entry.code());
+ const int32_t offset = ObjectPool::element_offset(
+ object_pool_wrapper_.FindObject(target_code, kPatchable));
+ LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp);
+ lw(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ jr(TMP);
}
@@ -487,7 +510,21 @@ void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) {
ASSERT(!in_delay_slot_);
const int32_t offset = ObjectPool::element_offset(
object_pool_wrapper_.FindExternalLabel(label, patchable));
- LoadWordFromPoolOffset(T9, offset - kHeapObjectTag);
+ LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
+ lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ jalr(T9);
+ if (patchable == kPatchable) {
+ delay_slot_available_ = false; // CodePatcher expects a nop.
+ }
+}
+
+
+void Assembler::BranchLink(const Code& target, Patchability patchable) {
+ ASSERT(!in_delay_slot_);
+ const int32_t offset = ObjectPool::element_offset(
+ object_pool_wrapper_.FindObject(target, patchable));
+ LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
+ lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset()));
jalr(T9);
if (patchable == kPatchable) {
delay_slot_available_ = false; // CodePatcher expects a nop.
@@ -497,12 +534,12 @@ void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) {
void Assembler::BranchLink(const StubEntry& stub_entry,
Patchability patchable) {
- BranchLink(&stub_entry.label(), patchable);
+ BranchLink(Code::Handle(stub_entry.code()), patchable);
}
void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
- BranchLink(&stub_entry.label(), kPatchable);
+ BranchLink(Code::Handle(stub_entry.code()), kPatchable);
}
@@ -568,6 +605,15 @@ void Assembler::LoadExternalLabel(Register rd,
}
+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);
+}
+
+
void Assembler::LoadNativeEntry(Register rd,
const ExternalLabel* label,
Patchability patchable) {
@@ -645,6 +691,7 @@ void Assembler::StoreIntoObject(Register object,
if (object != T0) {
mov(T0, object);
}
+ lw(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
lw(T9, Address(THR, Thread::update_store_buffer_entry_point_offset()));
jalr(T9);
lw(RA, Address(SP, 0 * kWordSize));
@@ -839,17 +886,8 @@ void Assembler::LeaveFrameAndReturn() {
}
-void Assembler::EnterStubFrame() {
- ASSERT(!in_delay_slot_);
- SetPrologueOffset();
- addiu(SP, SP, Immediate(-4 * kWordSize));
- sw(ZR, Address(SP, 3 * kWordSize)); // PC marker is 0 in stubs.
- sw(RA, Address(SP, 2 * kWordSize));
- sw(FP, Address(SP, 1 * kWordSize));
- sw(PP, Address(SP, 0 * kWordSize));
- addiu(FP, SP, Immediate(1 * kWordSize));
- // Setup pool pointer for this stub.
- LoadPoolPointer();
+void Assembler::EnterStubFrame(intptr_t frame_size) {
+ EnterDartFrame(frame_size);
}
@@ -859,13 +897,7 @@ void Assembler::LeaveStubFrame() {
void Assembler::LeaveStubFrameAndReturn(Register ra) {
- ASSERT(!in_delay_slot_);
- addiu(SP, FP, Immediate(-1 * kWordSize));
- lw(RA, Address(SP, 2 * kWordSize));
- lw(FP, Address(SP, 1 * kWordSize));
- lw(PP, Address(SP, 0 * kWordSize));
- jr(ra);
- delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
+ LeaveDartFrameAndReturn(ra);
}
@@ -1085,31 +1117,19 @@ void Assembler::CallRuntime(const RuntimeEntry& entry,
void Assembler::EnterDartFrame(intptr_t frame_size) {
ASSERT(!in_delay_slot_);
- const intptr_t offset = CodeSize();
SetPrologueOffset();
addiu(SP, SP, Immediate(-4 * kWordSize));
- sw(RA, Address(SP, 2 * kWordSize));
- sw(FP, Address(SP, 1 * kWordSize));
+ sw(RA, Address(SP, 3 * kWordSize));
+ sw(FP, Address(SP, 2 * kWordSize));
+ sw(CODE_REG, Address(SP, 1 * kWordSize));
sw(PP, Address(SP, 0 * kWordSize));
- GetNextPC(TMP); // TMP gets the address of the next instruction.
-
- // Calculate the offset of the pool pointer from the PC.
- const intptr_t object_pool_pc_dist =
- Instructions::HeaderSize() - Instructions::object_pool_offset() +
- CodeSize();
-
- // Save PC in frame for fast identification of corresponding code.
- AddImmediate(TMP, -offset);
- sw(TMP, Address(SP, 3 * kWordSize));
-
// Set FP to the saved previous FP.
- addiu(FP, SP, Immediate(kWordSize));
+ addiu(FP, SP, Immediate(2 * kWordSize));
- // Load the pool pointer. offset has already been subtracted from TMP.
- lw(PP, Address(TMP, -object_pool_pc_dist + offset));
+ LoadPoolPointer();
// Reserve space for locals.
AddImmediate(SP, -frame_size);
@@ -1125,55 +1145,43 @@ void Assembler::EnterOsrFrame(intptr_t extra_size) {
ASSERT(!in_delay_slot_);
Comment("EnterOsrFrame");
- GetNextPC(TMP); // TMP gets the address of the next instruction.
-
- // The runtime system assumes that the code marker address is
- // kEntryPointToPcMarkerOffset bytes from the entry. Since there is no
- // code to set up the frame pointer, etc., the address needs to be adjusted.
- const intptr_t offset = EntryPointToPcMarkerOffset() - CodeSize();
- // Calculate the offset of the pool pointer from the PC.
- const intptr_t object_pool_pc_dist =
- Instructions::HeaderSize() - Instructions::object_pool_offset() +
- CodeSize();
-
- // Adjust PC by the offset, and store it in the stack frame.
- AddImmediate(TMP, TMP, offset);
- sw(TMP, Address(FP, kPcMarkerSlotFromFp * kWordSize));
-
// Restore return address.
lw(RA, Address(FP, 1 * kWordSize));
// Load the pool pointer. offset has already been subtracted from temp.
- lw(PP, Address(TMP, -object_pool_pc_dist - offset));
+ RestoreCodePointer();
+ LoadPoolPointer();
// Reserve space for locals.
AddImmediate(SP, -extra_size);
}
-void Assembler::LeaveDartFrame() {
+void Assembler::LeaveDartFrame(RestorePP restore_pp) {
ASSERT(!in_delay_slot_);
- addiu(SP, FP, Immediate(-kWordSize));
+ addiu(SP, FP, Immediate(-2 * kWordSize));
- lw(RA, Address(SP, 2 * kWordSize));
- lw(FP, Address(SP, 1 * kWordSize));
- lw(PP, Address(SP, 0 * kWordSize));
+ lw(RA, Address(SP, 3 * kWordSize));
+ lw(FP, Address(SP, 2 * kWordSize));
+ if (restore_pp == kRestoreCallerPP) {
+ lw(PP, Address(SP, 0 * kWordSize));
+ }
// Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame.
addiu(SP, SP, Immediate(4 * kWordSize));
}
-void Assembler::LeaveDartFrameAndReturn() {
+void Assembler::LeaveDartFrameAndReturn(Register ra) {
ASSERT(!in_delay_slot_);
- addiu(SP, FP, Immediate(-kWordSize));
+ addiu(SP, FP, Immediate(-2 * kWordSize));
- lw(RA, Address(SP, 2 * kWordSize));
- lw(FP, Address(SP, 1 * kWordSize));
+ lw(RA, Address(SP, 3 * kWordSize));
+ lw(FP, Address(SP, 2 * kWordSize));
lw(PP, Address(SP, 0 * kWordSize));
// Adjust SP for PC, RA, FP, PP pushed in EnterDartFrame, and return.
- Ret();
+ jr(ra);
delay_slot()->addiu(SP, SP, Immediate(4 * kWordSize));
}
« no previous file with comments | « runtime/vm/assembler_mips.h ('k') | runtime/vm/assembler_mips_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698