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

Unified Diff: runtime/vm/stub_code_mips.cc

Issue 16022011: Enables optimization on MIPS (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 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/simulator_mips.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/stub_code_mips.cc
===================================================================
--- runtime/vm/stub_code_mips.cc (revision 23188)
+++ runtime/vm/stub_code_mips.cc (working copy)
@@ -111,8 +111,22 @@
}
+// Print the stop message.
+DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, const char* message) {
+ OS::Print("Stop message: %s\n", message);
+}
+END_LEAF_RUNTIME_ENTRY
+
+
+// Input parameters:
+// A0 : stop message (const char*).
+// Must preserve all registers.
void StubCode::GeneratePrintStopMessageStub(Assembler* assembler) {
- __ Unimplemented("PrintStopMessage stub");
+ __ EnterCallRuntimeFrame(0);
+ // Call the runtime leaf function. A0 already contains the parameter.
+ __ CallRuntime(kPrintStopMessageRuntimeEntry);
+ __ LeaveCallRuntimeFrame();
+ __ Ret();
}
@@ -239,6 +253,7 @@
void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
+ __ TraceSimMsg("FixCallersTarget");
__ EnterStubFrame();
// Setup space on stack for return value and preserve arguments descriptor.
__ addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -324,17 +339,6 @@
PushArgumentsArray(assembler);
__ TraceSimMsg("InstanceFunctionLookupStub return");
- // Stack:
- // TOS + 0: argument array.
- // TOS + 1: arguments descriptor array.
- // TOS + 2: IC data object.
- // TOS + 3: Receiver.
- // TOS + 4: place for result from the call.
- // TOS + 5: saved FP of previous frame.
- // TOS + 6: dart code return address
- // TOS + 7: pc marker (0 for stub).
- // TOS + 8: last argument of caller.
- // ....
__ CallRuntime(kInstanceFunctionLookupRuntimeEntry);
__ lw(V0, Address(SP, 4 * kWordSize)); // Get result into V0.
@@ -351,6 +355,8 @@
DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
+
+
// Used by eager and lazy deoptimization. Preserve result in V0 if necessary.
// This stub translates optimized frame into unoptimized frame. The optimized
// frame can contain values in registers and on stack, the unoptimized
@@ -364,42 +370,53 @@
// GC can occur only after frame is fully rewritten.
// Stack after EnterFrame(...) below:
// +------------------+
-// | Saved FP | <- TOS
+// | Saved PP | <- TOS
// +------------------+
-// | return-address | (deoptimization point)
+// | Saved FP | <- FP of stub
// +------------------+
-// | optimized frame |
-// | ... |
+// | Saved LR | (deoptimization point)
+// +------------------+
+// | PC marker |
+// +------------------+
+// | ... | <- SP of optimized frame
//
// Parts of the code cannot GC, part of the code can GC.
static void GenerateDeoptimizationSequence(Assembler* assembler,
bool preserve_result) {
+ __ TraceSimMsg("GenerateDeoptimizationSequence");
const intptr_t kPushedRegistersSize =
kNumberOfCpuRegisters * kWordSize +
- 2 * kWordSize + // FP and RA.
+ 4 * kWordSize + // PP, FP, RA, PC marker.
kNumberOfFRegisters * kWordSize;
+ // DeoptimizeCopyFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+ // is no need to set the correct PC marker or load PP, since they get patched.
__ addiu(SP, SP, Immediate(-kPushedRegistersSize * kWordSize));
- __ sw(RA, Address(SP, kPushedRegistersSize - 1 * kWordSize));
- __ sw(FP, Address(SP, kPushedRegistersSize - 2 * kWordSize));
- __ addiu(FP, SP, Immediate(kPushedRegistersSize - 2 * kWordSize));
+ __ sw(ZR, Address(SP, kPushedRegistersSize - 1 * kWordSize));
+ __ sw(RA, Address(SP, kPushedRegistersSize - 2 * kWordSize));
+ __ sw(FP, Address(SP, kPushedRegistersSize - 3 * kWordSize));
+ __ sw(PP, Address(SP, kPushedRegistersSize - 4 * kWordSize));
+ __ addiu(FP, SP, Immediate(kPushedRegistersSize - 3 * kWordSize));
-
// The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
// and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
- const intptr_t saved_v0_offset_from_fp = -(kNumberOfCpuRegisters - V0);
+ const intptr_t saved_result_slot_from_fp =
+ kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - V0);
// Result in V0 is preserved as part of pushing all registers below.
+ // TODO(regis): Should we align the stack before pushing the fpu registers?
+ // If we do, saved_result_slot_from_fp is not constant anymore.
+
// Push registers in their enumeration order: lowest register number at
// lowest address.
for (int i = 0; i < kNumberOfCpuRegisters; i++) {
- const int slot = 2 + kNumberOfCpuRegisters - i;
+ const int slot = 4 + kNumberOfCpuRegisters - i;
Register reg = static_cast<Register>(i);
__ sw(reg, Address(SP, kPushedRegistersSize - slot * kWordSize));
}
for (int i = 0; i < kNumberOfFRegisters; i++) {
// These go below the CPU registers.
- const int slot = 2 + kNumberOfCpuRegisters + kNumberOfFRegisters - i;
+ const int slot = 4 + kNumberOfCpuRegisters + kNumberOfFRegisters - i;
FRegister reg = static_cast<FRegister>(i);
__ swc1(reg, Address(SP, kPushedRegistersSize - slot * kWordSize));
}
@@ -411,38 +428,40 @@
if (preserve_result) {
// Restore result into T1 temporarily.
- __ lw(T1, Address(FP, saved_v0_offset_from_fp * kWordSize));
+ __ lw(T1, Address(FP, saved_result_slot_from_fp * kWordSize));
}
- __ mov(SP, FP);
- __ lw(FP, Address(SP, 0 * kWordSize));
- __ lw(RA, Address(SP, 1 * kWordSize));
- __ addiu(SP, SP, Immediate(2 * kWordSize));
-
+ __ addiu(SP, FP, Immediate(-kWordSize));
+ __ lw(RA, Address(SP, 2 * kWordSize));
+ __ lw(FP, Address(SP, 1 * kWordSize));
+ __ lw(PP, Address(SP, 0 * kWordSize));
__ subu(SP, FP, V0);
- __ addiu(SP, SP, Immediate(-2 * kWordSize));
- __ sw(RA, Address(SP, 1 * kWordSize));
- __ sw(FP, Address(SP, 0 * kWordSize));
- __ mov(FP, SP);
+ // DeoptimizeFillFrame expects a Dart frame, i.e. EnterDartFrame(0), but there
+ // is no need to set the correct PC marker or load PP, since they get patched.
+ __ addiu(SP, SP, Immediate(-4 * kWordSize));
+ __ sw(ZR, Address(SP, 3 * kWordSize));
+ __ sw(RA, Address(SP, 2 * kWordSize));
+ __ sw(FP, Address(SP, 1 * kWordSize));
+ __ sw(PP, Address(SP, 0 * kWordSize));
+ __ addiu(FP, SP, Immediate(kWordSize));
- __ mov(A0, SP); // Get last FP address.
+ __ mov(A0, FP); // Get last FP address.
if (preserve_result) {
- __ Push(T1); // Preserve result.
+ __ Push(T1); // Preserve result as first local.
}
__ ReserveAlignedFrameSpace(0);
__ CallRuntime(kDeoptimizeFillFrameRuntimeEntry); // Pass last FP in A0.
- // Result (V0) is our FP.
if (preserve_result) {
// Restore result into T1.
- __ lw(T1, Address(FP, -1 * kWordSize));
+ __ lw(T1, Address(FP, kFirstLocalSlotFromFp * kWordSize));
}
// Code above cannot cause GC.
- __ mov(SP, FP);
- __ lw(FP, Address(SP, 0 * kWordSize));
- __ lw(RA, Address(SP, 1 * kWordSize));
- __ addiu(SP, SP, Immediate(2 * kWordSize));
- __ mov(FP, V0);
+ __ addiu(SP, FP, Immediate(-kWordSize));
+ __ lw(RA, Address(SP, 2 * kWordSize));
+ __ lw(FP, Address(SP, 1 * kWordSize));
+ __ lw(PP, Address(SP, 0 * kWordSize));
+ __ addiu(SP, SP, Immediate(4 * kWordSize));
// Frame is fully rewritten at this point and it is safe to perform a GC.
// Materialize any objects that were deferred by FillFrame because they
@@ -456,20 +475,22 @@
// Result tells stub how many bytes to remove from the expression stack
// of the bottom-most frame. They were used as materialization arguments.
__ Pop(T1);
- __ SmiUntag(T1);
if (preserve_result) {
__ Pop(V0); // Restore result.
}
__ LeaveStubFrame();
-
- // Return.
- __ jr(RA);
- __ delay_slot()->addu(SP, SP, T1); // Remove materialization arguments.
+ // Remove materialization arguments.
+ __ SmiUntag(T1);
+ __ addu(SP, SP, T1);
+ __ Ret();
}
void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
- __ Unimplemented("DeoptimizeLazy stub");
+ // Correct return address to point just after the call that is being
+ // deoptimized.
+ __ AddImmediate(RA, -CallPattern::kFixedLengthInBytes);
+ GenerateDeoptimizationSequence(assembler, true); // Preserve V0.
}
@@ -480,6 +501,7 @@
void StubCode::GenerateMegamorphicMissStub(Assembler* assembler) {
__ Unimplemented("MegamorphicMiss stub");
+ return;
}
@@ -866,6 +888,7 @@
// Output:
// V0: new allocated RawContext object.
void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
+ __ TraceSimMsg("AllocateContext");
if (FLAG_inline_alloc) {
const Class& context_class = Class::ZoneHandle(Object::context_class());
Label slow_case;
@@ -1757,6 +1780,7 @@
void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) {
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
+ __ TraceSimMsg("BreakpointDynamicStub");
__ EnterStubFrame();
__ addiu(SP, SP, Immediate(-2 * kWordSize));
__ sw(S5, Address(SP, 1 * kWordSize));
@@ -2137,6 +2161,8 @@
__ Bind(&reference_compare);
__ subu(ret, left, right);
__ Bind(&done);
+ // A branch or test after this comparison will check CMPRES == TMP1.
+ __ mov(TMP1, ZR);
__ lw(T0, Address(SP, 0 * kWordSize));
__ lw(T1, Address(SP, 1 * kWordSize));
__ Ret();
« no previous file with comments | « runtime/vm/simulator_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698