Chromium Code Reviews| Index: runtime/vm/simulator_dbc.cc |
| diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc |
| index baafca844ed13c442ee0d7286b0eec59e7583fd2..ab85d739aad9180f55f12bc9d16bf0a6861def2b 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]) { |
| @@ -1966,54 +1975,69 @@ RawObject* Simulator::Call(const Code& code, |
| { |
| BYTECODE(Deopt, A_D); |
| const uint16_t deopt_id = rD; |
|
Vyacheslav Egorov (Google)
2016/06/09 15:09:06
My original idea was to use this value to look up
zra
2016/06/09 16:42:23
Done.
|
| - 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 preserve_result = (deopt_id == 0); |
|
Vyacheslav Egorov (Google)
2016/06/09 15:09:06
I suggest removing preserve_result and use either
zra
2016/06/09 16:42:23
Done.
|
| + |
| + // 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 (!preserve_result) { |
| + 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 - 1); |
|
Vyacheslav Egorov (Google)
2016/06/09 15:09:06
I overlooked that this should say
pc - is_eager
zra
2016/06/09 16:42:23
Done.
|
| + const intptr_t frame_size_in_bytes = |
| + DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP), |
| + /*is_lazy_deopt=*/ (deopt_id == 0) ? 1 : 0); |
| + 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. |
| + { |
| + if (preserve_result) { |
| *++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 = 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 (preserve_result) { |
| + // 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 + (preserve_result ? 0 : 1)); |
|
Vyacheslav Egorov (Google)
2016/06/09 15:09:06
I thought about it and it might be more readable t
zra
2016/06/09 16:42:23
Done.
|
| + FP = SavedCallerFP(FP); |
| + pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); |
| + if (preserve_result) { |
| *SP = result; |
| - } else { |
| - UNIMPLEMENTED(); |
| } |
| DISPATCH(); |
| } |