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 |