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_MIPS) | 10 #if defined(TARGET_ARCH_MIPS) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 void Longjmp() { | 44 void Longjmp() { |
45 // "This" is now the last setjmp buffer. | 45 // "This" is now the last setjmp buffer. |
46 simulator_->set_last_setjmp_buffer(this); | 46 simulator_->set_last_setjmp_buffer(this); |
47 longjmp(buffer_, 1); | 47 longjmp(buffer_, 1); |
48 } | 48 } |
49 | 49 |
50 explicit SimulatorSetjmpBuffer(Simulator* sim) { | 50 explicit SimulatorSetjmpBuffer(Simulator* sim) { |
51 simulator_ = sim; | 51 simulator_ = sim; |
52 link_ = sim->last_setjmp_buffer(); | 52 link_ = sim->last_setjmp_buffer(); |
53 sim->set_last_setjmp_buffer(this); | 53 sim->set_last_setjmp_buffer(this); |
54 sp_ = sim->get_register(SP); | 54 sp_ = static_cast<uword>(sim->get_register(SP)); |
| 55 native_sp_ = reinterpret_cast<uword>(&sim); // Current C++ stack pointer. |
55 } | 56 } |
56 | 57 |
57 ~SimulatorSetjmpBuffer() { | 58 ~SimulatorSetjmpBuffer() { |
58 ASSERT(simulator_->last_setjmp_buffer() == this); | 59 ASSERT(simulator_->last_setjmp_buffer() == this); |
59 simulator_->set_last_setjmp_buffer(link_); | 60 simulator_->set_last_setjmp_buffer(link_); |
60 } | 61 } |
61 | 62 |
62 SimulatorSetjmpBuffer* link() { return link_; } | 63 SimulatorSetjmpBuffer* link() { return link_; } |
63 | 64 |
64 int32_t sp() { return sp_; } | 65 uword sp() { return sp_; } |
| 66 uword native_sp() { return native_sp_; } |
65 | 67 |
66 private: | 68 private: |
67 int32_t sp_; | 69 uword sp_; |
| 70 uword native_sp_; |
68 Simulator* simulator_; | 71 Simulator* simulator_; |
69 SimulatorSetjmpBuffer* link_; | 72 SimulatorSetjmpBuffer* link_; |
70 jmp_buf buffer_; | 73 jmp_buf buffer_; |
71 | 74 |
72 friend class Simulator; | 75 friend class Simulator; |
73 }; | 76 }; |
74 | 77 |
75 | 78 |
76 // The SimulatorDebugger class is used by the simulator while debugging | 79 // The SimulatorDebugger class is used by the simulator while debugging |
77 // simulated MIPS code. | 80 // simulated MIPS code. |
(...skipping 1744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 set_register(R20, r20_val); | 1825 set_register(R20, r20_val); |
1823 set_register(R21, r21_val); | 1826 set_register(R21, r21_val); |
1824 set_register(R22, r22_val); | 1827 set_register(R22, r22_val); |
1825 set_register(R23, r23_val); | 1828 set_register(R23, r23_val); |
1826 | 1829 |
1827 // Restore the SP register and return R1:R0. | 1830 // Restore the SP register and return R1:R0. |
1828 set_register(SP, sp_before_call); | 1831 set_register(SP, sp_before_call); |
1829 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); | 1832 return Utils::LowHighTo64Bits(get_register(V0), get_register(V1)); |
1830 } | 1833 } |
1831 | 1834 |
| 1835 |
| 1836 void Simulator::Longjmp(uword pc, |
| 1837 uword sp, |
| 1838 uword fp, |
| 1839 RawObject* raw_exception, |
| 1840 RawObject* raw_stacktrace) { |
| 1841 // Walk over all setjmp buffers (simulated --> C++ transitions) |
| 1842 // and try to find the setjmp associated with the simulated stack pointer. |
| 1843 SimulatorSetjmpBuffer* buf = last_setjmp_buffer(); |
| 1844 while (buf->link() != NULL && buf->link()->sp() <= sp) { |
| 1845 buf = buf->link(); |
| 1846 } |
| 1847 ASSERT(buf != NULL); |
| 1848 |
| 1849 // The C++ caller has not cleaned up the stack memory of C++ frames. |
| 1850 // Prepare for unwinding frames by destroying all the stack resources |
| 1851 // in the previous C++ frames. |
| 1852 uword native_sp = buf->native_sp(); |
| 1853 Isolate* isolate = Isolate::Current(); |
| 1854 while (isolate->top_resource() != NULL && |
| 1855 (reinterpret_cast<uword>(isolate->top_resource()) < native_sp)) { |
| 1856 isolate->top_resource()->~StackResource(); |
| 1857 } |
| 1858 |
| 1859 // Unwind the C++ stack and continue simulation in the target frame. |
| 1860 set_pc(static_cast<int32_t>(pc)); |
| 1861 set_register(SP, static_cast<int32_t>(sp)); |
| 1862 set_register(FP, static_cast<int32_t>(fp)); |
| 1863 ASSERT(raw_exception != NULL); |
| 1864 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 1865 if (raw_stacktrace != NULL) { |
| 1866 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 1867 } |
| 1868 buf->Longjmp(); |
| 1869 } |
| 1870 |
1832 } // namespace dart | 1871 } // namespace dart |
1833 | 1872 |
1834 #endif // !defined(HOST_ARCH_MIPS) | 1873 #endif // !defined(HOST_ARCH_MIPS) |
1835 | 1874 |
1836 #endif // defined TARGET_ARCH_MIPS | 1875 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |