| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_ARM) | 10 #if defined(TARGET_ARCH_ARM) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 void Longjmp() { | 57 void Longjmp() { |
| 58 // "This" is now the last setjmp buffer. | 58 // "This" is now the last setjmp buffer. |
| 59 simulator_->set_last_setjmp_buffer(this); | 59 simulator_->set_last_setjmp_buffer(this); |
| 60 longjmp(buffer_, 1); | 60 longjmp(buffer_, 1); |
| 61 } | 61 } |
| 62 | 62 |
| 63 explicit SimulatorSetjmpBuffer(Simulator* sim) { | 63 explicit SimulatorSetjmpBuffer(Simulator* sim) { |
| 64 simulator_ = sim; | 64 simulator_ = sim; |
| 65 link_ = sim->last_setjmp_buffer(); | 65 link_ = sim->last_setjmp_buffer(); |
| 66 sim->set_last_setjmp_buffer(this); | 66 sim->set_last_setjmp_buffer(this); |
| 67 sp_ = sim->get_register(SP); | 67 sp_ = static_cast<uword>(sim->get_register(SP)); |
| 68 native_sp_ = reinterpret_cast<uword>(&sim); // Current C++ stack pointer. |
| 68 } | 69 } |
| 69 | 70 |
| 70 ~SimulatorSetjmpBuffer() { | 71 ~SimulatorSetjmpBuffer() { |
| 71 ASSERT(simulator_->last_setjmp_buffer() == this); | 72 ASSERT(simulator_->last_setjmp_buffer() == this); |
| 72 simulator_->set_last_setjmp_buffer(link_); | 73 simulator_->set_last_setjmp_buffer(link_); |
| 73 } | 74 } |
| 74 | 75 |
| 75 SimulatorSetjmpBuffer* link() { return link_; } | 76 SimulatorSetjmpBuffer* link() { return link_; } |
| 76 | 77 |
| 77 int32_t sp() { return sp_; } | 78 uword sp() { return sp_; } |
| 79 uword native_sp() { return native_sp_; } |
| 78 | 80 |
| 79 private: | 81 private: |
| 80 int32_t sp_; | 82 uword sp_; |
| 83 uword native_sp_; |
| 81 Simulator* simulator_; | 84 Simulator* simulator_; |
| 82 SimulatorSetjmpBuffer* link_; | 85 SimulatorSetjmpBuffer* link_; |
| 83 jmp_buf buffer_; | 86 jmp_buf buffer_; |
| 84 | 87 |
| 85 friend class Simulator; | 88 friend class Simulator; |
| 86 }; | 89 }; |
| 87 | 90 |
| 88 | 91 |
| 89 // The SimulatorDebugger class is used by the simulator while debugging | 92 // The SimulatorDebugger class is used by the simulator while debugging |
| 90 // simulated ARM code. | 93 // simulated ARM code. |
| (...skipping 2765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2856 set_register(R9, r9_val); | 2859 set_register(R9, r9_val); |
| 2857 set_register(R10, r10_val); | 2860 set_register(R10, r10_val); |
| 2858 set_register(R11, r11_val); | 2861 set_register(R11, r11_val); |
| 2859 | 2862 |
| 2860 // Restore the SP register and return R1:R0. | 2863 // Restore the SP register and return R1:R0. |
| 2861 set_register(SP, sp_before_call); | 2864 set_register(SP, sp_before_call); |
| 2862 return Utils::LowHighTo64Bits(get_register(R0), get_register(R1)); | 2865 return Utils::LowHighTo64Bits(get_register(R0), get_register(R1)); |
| 2863 } | 2866 } |
| 2864 | 2867 |
| 2865 | 2868 |
| 2866 void Simulator::Longjmp( | 2869 void Simulator::Longjmp(uword pc, |
| 2867 int32_t pc, int32_t sp, int32_t fp, const Instance& object) { | 2870 uword sp, |
| 2868 set_register(SP, sp); | 2871 uword fp, |
| 2869 set_register(FP, fp); | 2872 RawObject* raw_exception, |
| 2870 set_register(PC, pc); | 2873 RawObject* raw_stacktrace) { |
| 2874 // Walk over all setjmp buffers (simulated --> C++ transitions) |
| 2875 // and try to find the setjmp associated with the simulated stack pointer. |
| 2871 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); | 2876 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); |
| 2872 | |
| 2873 // Walk over all setjmp buffers (simulated --> C++ transitions) | |
| 2874 // and try to find the setjmp associated with the stack pointer. | |
| 2875 while (buf->link() != NULL && buf->link()->sp() <= sp) { | 2877 while (buf->link() != NULL && buf->link()->sp() <= sp) { |
| 2876 buf = buf->link(); | 2878 buf = buf->link(); |
| 2877 } | 2879 } |
| 2878 ASSERT(buf != NULL); | 2880 ASSERT(buf != NULL); |
| 2879 | 2881 |
| 2880 // The caller has already cleaned up the stack memory of C++ frames. | 2882 // The C++ caller has not cleaned up the stack memory of C++ frames. |
| 2881 set_register(kExceptionObjectReg, bit_cast<int32_t>(object.raw())); | 2883 // Prepare for unwinding frames by destroying all the stack resources |
| 2884 // in the previous C++ frames. |
| 2885 uword native_sp = buf->native_sp(); |
| 2886 Isolate* isolate = Isolate::Current(); |
| 2887 while (isolate->top_resource() != NULL && |
| 2888 (reinterpret_cast<uword>(isolate->top_resource()) < native_sp)) { |
| 2889 isolate->top_resource()->~StackResource(); |
| 2890 } |
| 2891 |
| 2892 // Unwind the C++ stack and continue simulation in the target frame. |
| 2893 set_register(PC, static_cast<int32_t>(pc)); |
| 2894 set_register(SP, static_cast<int32_t>(sp)); |
| 2895 set_register(FP, static_cast<int32_t>(fp)); |
| 2896 ASSERT(raw_exception != NULL); |
| 2897 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 2898 if (raw_stacktrace != NULL) { |
| 2899 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 2900 } |
| 2882 buf->Longjmp(); | 2901 buf->Longjmp(); |
| 2883 } | 2902 } |
| 2884 | 2903 |
| 2885 } // namespace dart | 2904 } // namespace dart |
| 2886 | 2905 |
| 2887 #endif // !defined(HOST_ARCH_ARM) | 2906 #endif // !defined(HOST_ARCH_ARM) |
| 2888 | 2907 |
| 2889 #endif // defined TARGET_ARCH_ARM | 2908 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |