| Index: runtime/vm/simulator_dbc.cc
|
| diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
|
| index baafca844ed13c442ee0d7286b0eec59e7583fd2..499f6046d037a81f7f3495e7697d6b19a5370e58 100644
|
| --- a/runtime/vm/simulator_dbc.cc
|
| +++ b/runtime/vm/simulator_dbc.cc
|
| @@ -1829,6 +1829,15 @@ RawObject* Simulator::Call(const Code& code,
|
| }
|
|
|
| {
|
| + BYTECODE(CheckSmi, 0);
|
| + intptr_t obj = reinterpret_cast<intptr_t>(FP[rA]);
|
| + if ((obj & kSmiTagMask) == kSmiTag) {
|
| + pc++;
|
| + }
|
| + DISPATCH();
|
| + }
|
| +
|
| + {
|
| BYTECODE(IfEqStrictTOS, 0);
|
| SP -= 2;
|
| if (SP[1] != SP[2]) {
|
| @@ -1965,55 +1974,69 @@ RawObject* Simulator::Call(const Code& code,
|
|
|
| {
|
| BYTECODE(Deopt, A_D);
|
| - const uint16_t deopt_id = rD;
|
| - if (deopt_id == 0) { // Lazy deoptimization.
|
| - // Preserve result of the previous call.
|
| - // TODO(vegorov) we could have actually included result into the
|
| - // deoptimization environment because it is passed through the stack.
|
| - // If we do then we could remove special result handling from this code.
|
| - RawObject* result = SP[0];
|
| -
|
| - // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
|
| - // The code in this frame may not cause GC.
|
| - // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
|
| - EnterSyntheticFrame(&FP, &SP, pc - 1);
|
| - const intptr_t frame_size_in_bytes =
|
| - DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP),
|
| - /*is_lazy_deopt=*/1);
|
| - LeaveSyntheticFrame(&FP, &SP);
|
| -
|
| - SP = FP + (frame_size_in_bytes / kWordSize);
|
| - EnterSyntheticFrame(&FP, &SP, pc - 1);
|
| - DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
|
| -
|
| - // We are now inside a valid frame.
|
| - {
|
| + const bool is_lazy = rD == 0;
|
| +
|
| + // Preserve result of the previous call.
|
| + // TODO(vegorov) we could have actually included result into the
|
| + // deoptimization environment because it is passed through the stack.
|
| + // If we do then we could remove special result handling from this code.
|
| + RawObject* result = SP[0];
|
| +
|
| + // When not preserving the result, we still need to preserve SP[0] as it
|
| + // contains some temporary expression.
|
| + if (!is_lazy) {
|
| + SP++;
|
| + }
|
| +
|
| + // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
|
| + // The code in this frame may not cause GC.
|
| + // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
|
| + EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
|
| + const intptr_t frame_size_in_bytes =
|
| + DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), is_lazy ? 1 : 0);
|
| + LeaveSyntheticFrame(&FP, &SP);
|
| +
|
| + SP = FP + (frame_size_in_bytes / kWordSize);
|
| + EnterSyntheticFrame(&FP, &SP, pc - (is_lazy ? 1 : 0));
|
| + DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
|
| +
|
| + // We are now inside a valid frame.
|
| + {
|
| + if (is_lazy) {
|
| *++SP = result; // Preserve result (call below can cause GC).
|
| - *++SP = 0; // Space for the result: number of materialization args.
|
| - Exit(thread, FP, SP + 1, /*pc=*/0);
|
| - NativeArguments native_args(thread, 0, SP, SP);
|
| - INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
|
| }
|
| - const intptr_t materialization_arg_count =
|
| - Smi::Value(RAW_CAST(Smi, *SP--));
|
| - result = *SP--; // Reload the result. It might have been relocated by GC.
|
| -
|
| - // Restore caller PC.
|
| - pc = SavedCallerPC(FP);
|
| -
|
| - // Check if it is a fake PC marking the entry frame.
|
| - ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
|
| -
|
| - // Restore SP, FP and PP. Push result and dispatch.
|
| - // Note: unlike in a normal return sequence we don't need to drop
|
| - // arguments - those are not part of the innermost deoptimization
|
| - // environment they were dropped by FlowGraphCompiler::RecordAfterCall.
|
| - SP = FrameArguments(FP, materialization_arg_count);
|
| - FP = SavedCallerFP(FP);
|
| - pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
|
| - *SP = result;
|
| + *++SP = 0; // Space for the result: number of materialization args.
|
| + Exit(thread, FP, SP + 1, /*pc=*/0);
|
| + NativeArguments native_args(thread, 0, SP, SP);
|
| + INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
|
| + }
|
| + const intptr_t materialization_arg_count =
|
| + Smi::Value(RAW_CAST(Smi, *SP--));
|
| + if (is_lazy) {
|
| + // Reload the result. It might have been relocated by GC.
|
| + result = *SP--;
|
| + }
|
| +
|
| + // Restore caller PC.
|
| + pc = SavedCallerPC(FP);
|
| +
|
| + // Check if it is a fake PC marking the entry frame.
|
| + ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
|
| +
|
| + // Restore SP, FP and PP. Push result and dispatch.
|
| + // Note: unlike in a normal return sequence we don't need to drop
|
| + // arguments - those are not part of the innermost deoptimization
|
| + // environment they were dropped by FlowGraphCompiler::RecordAfterCall.
|
| +
|
| + // If the result is not preserved, the unoptimized frame ends at the
|
| + // next slot.
|
| + SP = FrameArguments(FP, materialization_arg_count);
|
| + FP = SavedCallerFP(FP);
|
| + pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
|
| + if (is_lazy) {
|
| + SP[0] = result; // Put the result on the stack.
|
| } else {
|
| - UNIMPLEMENTED();
|
| + SP--; // No result to push.
|
| }
|
| DISPATCH();
|
| }
|
|
|