| Index: runtime/vm/stub_code_ia32.cc
|
| ===================================================================
|
| --- runtime/vm/stub_code_ia32.cc (revision 22714)
|
| +++ runtime/vm/stub_code_ia32.cc (working copy)
|
| @@ -323,22 +323,25 @@
|
| // - Fill the unoptimized frame.
|
| // - Materialize objects that require allocation (e.g. Double instances).
|
| // GC can occur only after frame is fully rewritten.
|
| -// Stack after EnterFrame(0) below:
|
| +// Stack after EnterDartFrame(0) below:
|
| // +------------------+
|
| -// | Saved FP | <- TOS
|
| +// | PC marker | <- TOS
|
| // +------------------+
|
| +// | Saved FP | <- FP of stub
|
| +// +------------------+
|
| // | return-address | (deoptimization point)
|
| // +------------------+
|
| -// | optimized frame |
|
| -// | ... |
|
| +// | ... | <- SP of optimized frame
|
| //
|
| // Parts of the code cannot GC, part of the code can GC.
|
| static void GenerateDeoptimizationSequence(Assembler* assembler,
|
| - bool preserve_eax) {
|
| - __ EnterFrame(0);
|
| + bool preserve_result) {
|
| + // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
|
| + __ EnterDartFrame(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);
|
| + const intptr_t saved_result_slot_from_fp =
|
| + kFirstLocalSlotFromFp + 1 - (kNumberOfCpuRegisters - EAX);
|
| // Result in EAX is preserved as part of pushing all registers below.
|
|
|
| // Push registers in their enumeration order: lowest register number at
|
| @@ -358,41 +361,39 @@
|
| __ ReserveAlignedFrameSpace(1 * kWordSize);
|
| __ movl(Address(ESP, 0), ECX); // Start of register block.
|
| __ CallRuntime(kDeoptimizeCopyFrameRuntimeEntry);
|
| - // Result (EAX) is stack-size (FP - SP) in bytes, incl. the return address.
|
| + // Result (EAX) is stack-size (FP - SP) in bytes.
|
|
|
| - if (preserve_eax) {
|
| + if (preserve_result) {
|
| // Restore result into EBX temporarily.
|
| - __ movl(EBX, Address(EBP, saved_eax_offset_from_ebp * kWordSize));
|
| + __ movl(EBX, Address(EBP, saved_result_slot_from_fp * kWordSize));
|
| }
|
|
|
| __ LeaveFrame();
|
| __ popl(EDX); // Preserve return address.
|
| - __ movl(ESP, EBP);
|
| - __ subl(ESP, EAX);
|
| - __ movl(Address(ESP, 0), EDX);
|
| + __ movl(ESP, EBP); // Discard optimized frame.
|
| + __ subl(ESP, EAX); // Reserve space for deoptimized frame.
|
| + __ pushl(EDX); // Restore return address.
|
|
|
| - __ EnterFrame(0);
|
| - __ movl(ECX, ESP); // Get last FP address.
|
| - if (preserve_eax) {
|
| - __ pushl(EBX); // Preserve result.
|
| + // Leaf runtime function DeoptimizeFillFrame expects a Dart frame.
|
| + __ EnterDartFrame(0);
|
| + if (preserve_result) {
|
| + __ pushl(EBX); // Preserve result as first local.
|
| }
|
| __ ReserveAlignedFrameSpace(1 * kWordSize);
|
| - __ movl(Address(ESP, 0), ECX);
|
| + __ movl(Address(ESP, 0), EBP); // Pass last FP as parameter on stack.
|
| __ CallRuntime(kDeoptimizeFillFrameRuntimeEntry);
|
| - // Result (EAX) is our FP.
|
| - if (preserve_eax) {
|
| + if (preserve_result) {
|
| // Restore result into EBX.
|
| - __ movl(EBX, Address(EBP, -1 * kWordSize));
|
| + __ movl(EBX, Address(EBP, kFirstLocalSlotFromFp * kWordSize));
|
| }
|
| // Code above cannot cause GC.
|
| __ LeaveFrame();
|
| - __ movl(EBP, EAX);
|
|
|
| // 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.
|
| __ EnterStubFrame();
|
| - if (preserve_eax) {
|
| + if (preserve_result) {
|
| __ pushl(EBX); // Preserve result, it will be GC-d here.
|
| }
|
| __ pushl(Immediate(Smi::RawValue(0))); // Space for the result.
|
| @@ -401,7 +402,7 @@
|
| // of the bottom-most frame. They were used as materialization arguments.
|
| __ popl(EBX);
|
| __ SmiUntag(EBX);
|
| - if (preserve_eax) {
|
| + if (preserve_result) {
|
| __ popl(EAX); // Restore result.
|
| }
|
| __ LeaveFrame();
|
|
|