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

Unified Diff: runtime/vm/stub_code_ia32.cc

Issue 10912146: Finish implementing lazy deoptimization (ia32, x64). Ran tests with --deoptimize-alot. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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/stub_code.h ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/stub_code_ia32.cc
===================================================================
--- runtime/vm/stub_code_ia32.cc (revision 12092)
+++ runtime/vm/stub_code_ia32.cc (working copy)
@@ -9,6 +9,7 @@
#include "vm/assembler_macros.h"
#include "vm/compiler.h"
#include "vm/flow_graph_compiler.h"
+#include "vm/instructions.h"
#include "vm/object_store.h"
#include "vm/pages.h"
#include "vm/resolver.h"
@@ -481,6 +482,8 @@
DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp);
+
+// Used by eager and lazy deoptimization. Preserve result in EAX if necessary.
// This stub translates optimized frame into unoptimized frame. The optimized
// frame can contain values in registers and on stack, the unoptimized
// frame contains all values on stack.
@@ -493,17 +496,22 @@
// GC can occur only after frame is fully rewritten.
// Stack:
// +------------------+
-// | 0 as PC marker | <- TOS
+// | Saved FP | <- TOS
// +------------------+
-// | Saved FP |
-// +------------------+
// | return-address | (deoptimization point)
// +------------------+
// | optimized frame |
// | ... |
//
-void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
+// Parts of the code cannot GC, part of the code can GC.
+static void GenerateDeoptimizationSequence(Assembler* assembler,
+ bool preserve_eax) {
__ EnterFrame(0);
+ // The code in this frame may not cause GC. kDeoptimizeCopyFrameRuntimeEntry
+ // and kDeoptimizeFillFrameRuntimeEntry are leaf runtime calls.
+ const intptr_t saved_eax_offset_from_ebp = -(kNumberOfCpuRegisters - EAX);
+ // Result in EAX is preserved as part of pushing all registers below.
+
// Push registers in their enumeration order: lowest register number at
// lowest address.
for (intptr_t i = kNumberOfCpuRegisters - 1; i >= 0; i--) {
@@ -523,6 +531,12 @@
__ movl(Address(ESP, 0), ECX); // Start of register block.
__ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
// Result (EAX) is stack-size (FP - SP) in bytes, incl. the return address.
+
+ if (preserve_eax) {
+ // Restore result into EBX temporarily.
+ __ movl(EBX, Address(EBP, saved_eax_offset_from_ebp * kWordSize));
+ }
+
__ LeaveFrame();
__ popl(EDX); // Preserve return address.
__ movl(ESP, EBP);
@@ -531,21 +545,52 @@
__ EnterFrame(0);
__ movl(ECX, ESP); // Get last FP address.
+ if (preserve_eax) {
+ __ pushl(EBX); // Preserve result.
+ }
__ ReserveAlignedFrameSpace(1 * kWordSize);
__ movl(Address(ESP, 0), ECX);
__ CallRuntime(kDeoptimizeFillFrameRuntimeEntry);
+
+ if (preserve_eax) {
+ // Restore result into EAX.
+ __ movl(EAX, Address(EBP, -1 * kWordSize));
+ }
+ // Code above cannot cause GC.
__ LeaveFrame();
// 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
// require allocation.
__ EnterFrame(0);
+ if (preserve_eax) {
+ __ pushl(EAX); // Preserve result, it will be GC-d here.
+ }
__ CallRuntime(kDeoptimizeMaterializeDoublesRuntimeEntry);
+ if (preserve_eax) {
+ __ popl(EAX); // Restore result.
+ }
__ LeaveFrame();
__ ret();
}
+// TOS: return address + call-instruction-size (5 bytes).
+// EAX: result, must be preserved
+void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
+ // Correct return address to point just after the call that is being
+ // deoptimized.
+ __ popl(EBX);
+ __ subl(EBX, Immediate(CallPattern::InstructionLength()));
+ __ pushl(EBX);
+ GenerateDeoptimizationSequence(assembler, true); // Preserve EAX.
+}
+
+void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
+ GenerateDeoptimizationSequence(assembler, false); // Don't preserve EAX.
+}
+
+
// Called for inline allocation of arrays.
// Input parameters:
// EDX : Array length as Smi.
« no previous file with comments | « runtime/vm/stub_code.h ('k') | runtime/vm/stub_code_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698