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

Side by Side Diff: runtime/vm/simulator_dbc.cc

Issue 2587133002: VM: [DBC] Fix lazy deoptimization after calls that return no values. (Closed)
Patch Set: Add test Created 4 years 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include <setjmp.h> // NOLINT 5 #include <setjmp.h> // NOLINT
6 #include <stdlib.h> 6 #include <stdlib.h>
7 7
8 #include "vm/globals.h" 8 #include "vm/globals.h"
9 #if defined(TARGET_ARCH_DBC) 9 #if defined(TARGET_ARCH_DBC)
10 10
(...skipping 3536 matching lines...) Expand 10 before | Expand all | Expand 10 after
3547 BYTECODE(LoadIndexedTwoByteString, A_B_C); 3547 BYTECODE(LoadIndexedTwoByteString, A_B_C);
3548 RawTwoByteString* array = RAW_CAST(TwoByteString, FP[rB]); 3548 RawTwoByteString* array = RAW_CAST(TwoByteString, FP[rB]);
3549 RawSmi* index = RAW_CAST(Smi, FP[rC]); 3549 RawSmi* index = RAW_CAST(Smi, FP[rC]);
3550 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_)); 3550 ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
3551 FP[rA] = Smi::New(array->ptr()->data()[Smi::Value(index)]); 3551 FP[rA] = Smi::New(array->ptr()->data()[Smi::Value(index)]);
3552 DISPATCH(); 3552 DISPATCH();
3553 } 3553 }
3554 3554
3555 { 3555 {
3556 BYTECODE(Deopt, A_D); 3556 BYTECODE(Deopt, A_D);
3557
3558 // Note: frame translation will take care of preserving result at the
3559 // top of the stack. See CompilerDeoptInfo::CreateDeoptInfo.
3557 const bool is_lazy = rD == 0; 3560 const bool is_lazy = rD == 0;
3558 3561
3559 // Preserve result of the previous call. 3562 // Make sure we preserve SP[0] when entering synthetic frame below.
3560 // TODO(vegorov) we could have actually included result into the 3563 SP++;
3561 // deoptimization environment because it is passed through the stack.
3562 // If we do then we could remove special result handling from this code.
3563 RawObject* result = SP[0];
3564
3565 // When not preserving the result, we still need to preserve SP[0] as it
3566 // contains some temporary expression.
3567 if (!is_lazy) {
3568 SP++;
3569 }
3570 3564
3571 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame. 3565 // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
3572 // The code in this frame may not cause GC. 3566 // The code in this frame may not cause GC.
3573 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls. 3567 // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
3574 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0)); 3568 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
3575 const intptr_t frame_size_in_bytes = 3569 const intptr_t frame_size_in_bytes =
3576 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0); 3570 DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0);
3577 LeaveSyntheticFrame(&FP, &SP); 3571 LeaveSyntheticFrame(&FP, &SP);
3578 3572
3579 SP = FP + (frame_size_in_bytes / kWordSize); 3573 SP = FP + (frame_size_in_bytes / kWordSize);
3580 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0)); 3574 EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
3581 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP)); 3575 DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
3582 3576
3583 // We are now inside a valid frame. 3577 // We are now inside a valid frame.
3584 { 3578 {
3585 if (is_lazy) {
3586 *++SP = result; // Preserve result (call below can cause GC).
3587 }
3588 *++SP = 0; // Space for the result: number of materialization args. 3579 *++SP = 0; // Space for the result: number of materialization args.
3589 Exit(thread, FP, SP + 1, /*pc=*/0); 3580 Exit(thread, FP, SP + 1, /*pc=*/0);
3590 NativeArguments native_args(thread, 0, SP, SP); 3581 NativeArguments native_args(thread, 0, SP, SP);
3591 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args); 3582 INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
3592 } 3583 }
3593 const intptr_t materialization_arg_count = 3584 const intptr_t materialization_arg_count =
3594 Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize; 3585 Smi::Value(RAW_CAST(Smi, *SP--)) / kWordSize;
3595 if (is_lazy) {
3596 // Reload the result. It might have been relocated by GC.
3597 result = *SP--;
3598 }
3599 3586
3600 // Restore caller PC. 3587 // Restore caller PC.
3601 pc = SavedCallerPC(FP); 3588 pc = SavedCallerPC(FP);
3602 pc_ = reinterpret_cast<uword>(pc); // For the profiler. 3589 pc_ = reinterpret_cast<uword>(pc); // For the profiler.
3603 3590
3604 // Check if it is a fake PC marking the entry frame. 3591 // Check if it is a fake PC marking the entry frame.
3605 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0); 3592 ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
3606 3593
3607 // Restore SP, FP and PP. Push result and dispatch. 3594 // Restore SP, FP and PP.
3608 // Note: unlike in a normal return sequence we don't need to drop 3595 // Unoptimized frame SP is one below FrameArguments(...) because
3609 // arguments - those are not part of the innermost deoptimization 3596 // FrameArguments(...) returns a pointer to the first argument.
3610 // environment they were dropped by FlowGraphCompiler::RecordAfterCall. 3597 SP = FrameArguments(FP, materialization_arg_count) - 1;
3611
3612 // If the result is not preserved, the unoptimized frame ends at the
3613 // next slot.
3614 SP = FrameArguments(FP, materialization_arg_count);
3615 FP = SavedCallerFP(FP); 3598 FP = SavedCallerFP(FP);
3616 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); 3599 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
3617 if (is_lazy) { 3600
3618 SP[0] = result; // Put the result on the stack.
3619 } else {
3620 SP--; // No result to push.
3621 }
3622 DISPATCH(); 3601 DISPATCH();
3623 } 3602 }
3624 3603
3625 { 3604 {
3626 BYTECODE(Nop, 0); 3605 BYTECODE(Nop, 0);
3627 DISPATCH(); 3606 DISPATCH();
3628 } 3607 }
3629 3608
3630 { 3609 {
3631 BYTECODE(Trap, 0); 3610 BYTECODE(Trap, 0);
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
3745 pc_ = pc; 3724 pc_ = pc;
3746 } 3725 }
3747 3726
3748 buf->Longjmp(); 3727 buf->Longjmp();
3749 UNREACHABLE(); 3728 UNREACHABLE();
3750 } 3729 }
3751 3730
3752 } // namespace dart 3731 } // namespace dart
3753 3732
3754 #endif // defined TARGET_ARCH_DBC 3733 #endif // defined TARGET_ARCH_DBC
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698