| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 void Longjmp() { | 54 void Longjmp() { |
| 55 // "This" is now the last setjmp buffer. | 55 // "This" is now the last setjmp buffer. |
| 56 simulator_->set_last_setjmp_buffer(this); | 56 simulator_->set_last_setjmp_buffer(this); |
| 57 longjmp(buffer_, 1); | 57 longjmp(buffer_, 1); |
| 58 } | 58 } |
| 59 | 59 |
| 60 explicit SimulatorSetjmpBuffer(Simulator* sim) { | 60 explicit SimulatorSetjmpBuffer(Simulator* sim) { |
| 61 simulator_ = sim; | 61 simulator_ = sim; |
| 62 link_ = sim->last_setjmp_buffer(); | 62 link_ = sim->last_setjmp_buffer(); |
| 63 sim->set_last_setjmp_buffer(this); | 63 sim->set_last_setjmp_buffer(this); |
| 64 sp_ = sim->sp_; | |
| 65 fp_ = sim->fp_; | 64 fp_ = sim->fp_; |
| 66 } | 65 } |
| 67 | 66 |
| 68 ~SimulatorSetjmpBuffer() { | 67 ~SimulatorSetjmpBuffer() { |
| 69 ASSERT(simulator_->last_setjmp_buffer() == this); | 68 ASSERT(simulator_->last_setjmp_buffer() == this); |
| 70 simulator_->set_last_setjmp_buffer(link_); | 69 simulator_->set_last_setjmp_buffer(link_); |
| 71 } | 70 } |
| 72 | 71 |
| 73 SimulatorSetjmpBuffer* link() const { return link_; } | 72 SimulatorSetjmpBuffer* link() const { return link_; } |
| 74 | 73 |
| 75 uword sp() const { return reinterpret_cast<uword>(sp_); } | |
| 76 uword fp() const { return reinterpret_cast<uword>(fp_); } | 74 uword fp() const { return reinterpret_cast<uword>(fp_); } |
| 77 | 75 |
| 78 jmp_buf buffer_; | 76 jmp_buf buffer_; |
| 79 | 77 |
| 80 private: | 78 private: |
| 81 RawObject** sp_; | |
| 82 RawObject** fp_; | 79 RawObject** fp_; |
| 83 Simulator* simulator_; | 80 Simulator* simulator_; |
| 84 SimulatorSetjmpBuffer* link_; | 81 SimulatorSetjmpBuffer* link_; |
| 85 | 82 |
| 86 friend class Simulator; | 83 friend class Simulator; |
| 87 | 84 |
| 88 DISALLOW_ALLOCATION(); | 85 DISALLOW_ALLOCATION(); |
| 89 DISALLOW_COPY_AND_ASSIGN(SimulatorSetjmpBuffer); | 86 DISALLOW_COPY_AND_ASSIGN(SimulatorSetjmpBuffer); |
| 90 }; | 87 }; |
| 91 | 88 |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 SimulatorHelpers::Double_greaterThan; | 500 SimulatorHelpers::Double_greaterThan; |
| 504 intrinsics_[kDouble_greaterEqualThanIntrinsic] = | 501 intrinsics_[kDouble_greaterEqualThanIntrinsic] = |
| 505 SimulatorHelpers::Double_greaterEqualThan; | 502 SimulatorHelpers::Double_greaterEqualThan; |
| 506 intrinsics_[kDouble_lessThanIntrinsic] = SimulatorHelpers::Double_lessThan; | 503 intrinsics_[kDouble_lessThanIntrinsic] = SimulatorHelpers::Double_lessThan; |
| 507 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; | 504 intrinsics_[kDouble_equalIntrinsic] = SimulatorHelpers::Double_equal; |
| 508 intrinsics_[kDouble_lessEqualThanIntrinsic] = | 505 intrinsics_[kDouble_lessEqualThanIntrinsic] = |
| 509 SimulatorHelpers::Double_lessEqualThan; | 506 SimulatorHelpers::Double_lessEqualThan; |
| 510 } | 507 } |
| 511 | 508 |
| 512 | 509 |
| 513 Simulator::Simulator() : stack_(NULL), fp_(NULL), sp_(NULL) { | 510 Simulator::Simulator() : stack_(NULL), fp_(NULL) { |
| 514 // Setup simulator support first. Some of this information is needed to | 511 // Setup simulator support first. Some of this information is needed to |
| 515 // setup the architecture state. | 512 // setup the architecture state. |
| 516 // We allocate the stack here, the size is computed as the sum of | 513 // We allocate the stack here, the size is computed as the sum of |
| 517 // the size specified by the user and the buffer space needed for | 514 // the size specified by the user and the buffer space needed for |
| 518 // handling stack overflow exceptions. To be safe in potential | 515 // handling stack overflow exceptions. To be safe in potential |
| 519 // stack underflows we also add some underflow buffer space. | 516 // stack underflows we also add some underflow buffer space. |
| 520 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + | 517 stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + |
| 521 OSThread::kStackSizeBuffer + | 518 OSThread::kStackSizeBuffer + |
| 522 kSimulatorStackUnderflowSize) / | 519 kSimulatorStackUnderflowSize) / |
| 523 sizeof(uintptr_t)]; | 520 sizeof(uintptr_t)]; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 | 571 |
| 575 | 572 |
| 576 void Simulator::Exit(Thread* thread, | 573 void Simulator::Exit(Thread* thread, |
| 577 RawObject** base, | 574 RawObject** base, |
| 578 RawObject** frame, | 575 RawObject** frame, |
| 579 uint32_t* pc) { | 576 uint32_t* pc) { |
| 580 frame[0] = Function::null(); | 577 frame[0] = Function::null(); |
| 581 frame[1] = Code::null(); | 578 frame[1] = Code::null(); |
| 582 frame[2] = reinterpret_cast<RawObject*>(pc); | 579 frame[2] = reinterpret_cast<RawObject*>(pc); |
| 583 frame[3] = reinterpret_cast<RawObject*>(base); | 580 frame[3] = reinterpret_cast<RawObject*>(base); |
| 584 fp_ = sp_ = frame + kDartFrameFixedSize; | 581 fp_ = frame + kDartFrameFixedSize; |
| 585 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); | 582 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); |
| 586 } | 583 } |
| 587 | 584 |
| 588 // TODO(vegorov): Investigate advantages of using | 585 // TODO(vegorov): Investigate advantages of using |
| 589 // __builtin_s{add,sub,mul}_overflow() intrinsics here and below. | 586 // __builtin_s{add,sub,mul}_overflow() intrinsics here and below. |
| 590 // Note that they may clobber the output location even when there is overflow: | 587 // Note that they may clobber the output location even when there is overflow: |
| 591 // https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html | 588 // https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html |
| 592 DART_FORCE_INLINE static bool SignedAddWithOverflow(intptr_t lhs, | 589 DART_FORCE_INLINE static bool SignedAddWithOverflow(intptr_t lhs, |
| 593 intptr_t rhs, | 590 intptr_t rhs, |
| 594 intptr_t* out) { | 591 intptr_t* out) { |
| 595 intptr_t res = 1; | 592 intptr_t res = 1; |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 // Exception handling helper. Gets handler FP and PC from the Simulator where | 1050 // Exception handling helper. Gets handler FP and PC from the Simulator where |
| 1054 // they were stored by Simulator::Longjmp and proceeds to execute the handler. | 1051 // they were stored by Simulator::Longjmp and proceeds to execute the handler. |
| 1055 // Corner case: handler PC can be a fake marker that marks entry frame, which | 1052 // Corner case: handler PC can be a fake marker that marks entry frame, which |
| 1056 // means exception was not handled in the Dart code. In this case we return | 1053 // means exception was not handled in the Dart code. In this case we return |
| 1057 // caught exception from Simulator::Call. | 1054 // caught exception from Simulator::Call. |
| 1058 #define HANDLE_EXCEPTION \ | 1055 #define HANDLE_EXCEPTION \ |
| 1059 do { \ | 1056 do { \ |
| 1060 FP = reinterpret_cast<RawObject**>(fp_); \ | 1057 FP = reinterpret_cast<RawObject**>(fp_); \ |
| 1061 pc = reinterpret_cast<uint32_t*>(pc_); \ | 1058 pc = reinterpret_cast<uint32_t*>(pc_); \ |
| 1062 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ | 1059 if ((reinterpret_cast<uword>(pc) & 2) != 0) { /* Entry frame? */ \ |
| 1063 fp_ = sp_ = reinterpret_cast<RawObject**>(fp_[0]); \ | 1060 fp_ = reinterpret_cast<RawObject**>(fp_[0]); \ |
| 1064 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); \ | 1061 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); \ |
| 1065 thread->set_top_resource(top_resource); \ | 1062 thread->set_top_resource(top_resource); \ |
| 1066 thread->set_vm_tag(vm_tag); \ | 1063 thread->set_vm_tag(vm_tag); \ |
| 1067 return special_[kExceptionSpecialIndex]; \ | 1064 return special_[kExceptionSpecialIndex]; \ |
| 1068 } \ | 1065 } \ |
| 1069 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ | 1066 pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr(); \ |
| 1070 goto DispatchAfterException; \ | 1067 goto DispatchAfterException; \ |
| 1071 } while (0) | 1068 } while (0) |
| 1072 | 1069 |
| 1073 // Runtime call helpers: handle invocation and potential exception after return. | 1070 // Runtime call helpers: handle invocation and potential exception after return. |
| 1074 #define INVOKE_RUNTIME(Func, Args) \ | 1071 #define INVOKE_RUNTIME(Func, Args) \ |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1105 RawObjectPool* pp; // Pool Pointer. | 1102 RawObjectPool* pp; // Pool Pointer. |
| 1106 RawObject** FP; // Frame Pointer. | 1103 RawObject** FP; // Frame Pointer. |
| 1107 RawObject** SP; // Stack Pointer. | 1104 RawObject** SP; // Stack Pointer. |
| 1108 | 1105 |
| 1109 RawArray* argdesc; // Arguments Descriptor: used to pass information between | 1106 RawArray* argdesc; // Arguments Descriptor: used to pass information between |
| 1110 // call instruction and the function entry. | 1107 // call instruction and the function entry. |
| 1111 | 1108 |
| 1112 uint32_t op; // Currently executing op. | 1109 uint32_t op; // Currently executing op. |
| 1113 uint16_t rA; // A component of the currently executing op. | 1110 uint16_t rA; // A component of the currently executing op. |
| 1114 | 1111 |
| 1115 if (sp_ == NULL) { | 1112 if (fp_ == NULL) { |
| 1116 fp_ = sp_ = reinterpret_cast<RawObject**>(stack_); | 1113 fp_ = reinterpret_cast<RawObject**>(stack_); |
| 1117 } | 1114 } |
| 1118 | 1115 |
| 1119 // Save current VM tag and mark thread as executing Dart code. | 1116 // Save current VM tag and mark thread as executing Dart code. |
| 1120 const uword vm_tag = thread->vm_tag(); | 1117 const uword vm_tag = thread->vm_tag(); |
| 1121 thread->set_vm_tag(VMTag::kDartTagId); | 1118 thread->set_vm_tag(VMTag::kDartTagId); |
| 1122 | 1119 |
| 1123 // Save current top stack resource and reset the list. | 1120 // Save current top stack resource and reset the list. |
| 1124 StackResource* top_resource = thread->top_resource(); | 1121 StackResource* top_resource = thread->top_resource(); |
| 1125 thread->set_top_resource(NULL); | 1122 thread->set_top_resource(NULL); |
| 1126 | 1123 |
| (...skipping 1441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2568 // Fall through to the ReturnImpl. | 2565 // Fall through to the ReturnImpl. |
| 2569 | 2566 |
| 2570 ReturnImpl: | 2567 ReturnImpl: |
| 2571 // Restore caller PC. | 2568 // Restore caller PC. |
| 2572 pc = SavedCallerPC(FP); | 2569 pc = SavedCallerPC(FP); |
| 2573 pc_ = reinterpret_cast<uword>(pc); // For the profiler. | 2570 pc_ = reinterpret_cast<uword>(pc); // For the profiler. |
| 2574 | 2571 |
| 2575 // Check if it is a fake PC marking the entry frame. | 2572 // Check if it is a fake PC marking the entry frame. |
| 2576 if ((reinterpret_cast<uword>(pc) & 2) != 0) { | 2573 if ((reinterpret_cast<uword>(pc) & 2) != 0) { |
| 2577 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; | 2574 const intptr_t argc = reinterpret_cast<uword>(pc) >> 2; |
| 2578 fp_ = sp_ = | 2575 fp_ = reinterpret_cast<RawObject**>(FrameArguments(FP, argc + 1)[0]); |
| 2579 reinterpret_cast<RawObject**>(FrameArguments(FP, argc + 1)[0]); | 2576 thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_)); |
| 2580 thread->set_top_exit_frame_info(reinterpret_cast<uword>(sp_)); | |
| 2581 thread->set_top_resource(top_resource); | 2577 thread->set_top_resource(top_resource); |
| 2582 thread->set_vm_tag(vm_tag); | 2578 thread->set_vm_tag(vm_tag); |
| 2583 return result; | 2579 return result; |
| 2584 } | 2580 } |
| 2585 | 2581 |
| 2586 // Look at the caller to determine how many arguments to pop. | 2582 // Look at the caller to determine how many arguments to pop. |
| 2587 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); | 2583 const uint8_t argc = Bytecode::DecodeArgc(pc[-1]); |
| 2588 | 2584 |
| 2589 // Restore SP, FP and PP. Push result and dispatch. | 2585 // Restore SP, FP and PP. Push result and dispatch. |
| 2590 SP = FrameArguments(FP, argc); | 2586 SP = FrameArguments(FP, argc); |
| (...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3716 // The C++ caller has not cleaned up the stack memory of C++ frames. | 3712 // The C++ caller has not cleaned up the stack memory of C++ frames. |
| 3717 // Prepare for unwinding frames by destroying all the stack resources | 3713 // Prepare for unwinding frames by destroying all the stack resources |
| 3718 // in the previous C++ frames. | 3714 // in the previous C++ frames. |
| 3719 StackResource::Unwind(thread); | 3715 StackResource::Unwind(thread); |
| 3720 | 3716 |
| 3721 // Set the tag. | 3717 // Set the tag. |
| 3722 thread->set_vm_tag(VMTag::kDartTagId); | 3718 thread->set_vm_tag(VMTag::kDartTagId); |
| 3723 // Clear top exit frame. | 3719 // Clear top exit frame. |
| 3724 thread->set_top_exit_frame_info(0); | 3720 thread->set_top_exit_frame_info(0); |
| 3725 | 3721 |
| 3726 sp_ = reinterpret_cast<RawObject**>(sp); | |
| 3727 fp_ = reinterpret_cast<RawObject**>(fp); | 3722 fp_ = reinterpret_cast<RawObject**>(fp); |
| 3728 | 3723 |
| 3729 if (pc == StubCode::RunExceptionHandler_entry()->EntryPoint()) { | 3724 if (pc == StubCode::RunExceptionHandler_entry()->EntryPoint()) { |
| 3730 // The RunExceptionHandler stub is a placeholder. We implement | 3725 // The RunExceptionHandler stub is a placeholder. We implement |
| 3731 // its behavior here. | 3726 // its behavior here. |
| 3732 RawObject* raw_exception = thread->active_exception(); | 3727 RawObject* raw_exception = thread->active_exception(); |
| 3733 RawObject* raw_stacktrace = thread->active_stacktrace(); | 3728 RawObject* raw_stacktrace = thread->active_stacktrace(); |
| 3734 ASSERT(raw_exception != Object::null()); | 3729 ASSERT(raw_exception != Object::null()); |
| 3735 special_[kExceptionSpecialIndex] = raw_exception; | 3730 special_[kExceptionSpecialIndex] = raw_exception; |
| 3736 special_[kStackTraceSpecialIndex] = raw_stacktrace; | 3731 special_[kStackTraceSpecialIndex] = raw_stacktrace; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3750 pc_ = pc; | 3745 pc_ = pc; |
| 3751 } | 3746 } |
| 3752 | 3747 |
| 3753 buf->Longjmp(); | 3748 buf->Longjmp(); |
| 3754 UNREACHABLE(); | 3749 UNREACHABLE(); |
| 3755 } | 3750 } |
| 3756 | 3751 |
| 3757 } // namespace dart | 3752 } // namespace dart |
| 3758 | 3753 |
| 3759 #endif // defined TARGET_ARCH_DBC | 3754 #endif // defined TARGET_ARCH_DBC |
| OLD | NEW |