| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |