Index: runtime/vm/cpu_x64.cc |
=================================================================== |
--- runtime/vm/cpu_x64.cc (revision 3170) |
+++ runtime/vm/cpu_x64.cc (working copy) |
@@ -8,6 +8,11 @@ |
#include "vm/cpu.h" |
+#include "vm/constants_x64.h" |
+#include "vm/heap.h" |
+#include "vm/isolate.h" |
+#include "vm/object.h" |
+ |
namespace dart { |
void CPU::FlushICache(uword start, uword size) { |
@@ -15,21 +20,101 @@ |
} |
-void CPU::JumpToExceptionHandler(uword pc, |
- uword sp, |
- uword fp, |
+void CPU::JumpToExceptionHandler(uword program_counter, |
+ uword stack_pointer, |
+ uword frame_pointer, |
const Instance& exception_object, |
const Instance& stacktrace_object) { |
- UNIMPLEMENTED(); |
+ NoGCScope no_gc; |
+ RawInstance* exception = exception_object.raw(); |
+ RawInstance* stacktrace = stacktrace_object.raw(); |
+ |
+ // Prepare for unwinding frames by destroying all the stack resources |
+ // in the previous frames. |
+ Isolate* isolate = Isolate::Current(); |
+ while (isolate->top_resource() != NULL && |
+ (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) { |
+ isolate->top_resource()->~StackResource(); |
+ } |
+ |
+ // Set up the appropriate register state and jump to the handler. |
+ ASSERT(kExceptionObjectReg == RAX); |
+ ASSERT(kStackTraceObjectReg == RDX); |
+#if defined(TARGET_OS_WINDOWS) |
+ __asm { |
Ivan Posva
2012/01/11 00:49:18
Please do not put code into the repository that ha
regis
2012/01/11 01:51:12
Done. I guess we should use stubs instead of inlin
|
+ mov rax, exception |
+ mov rdx, stacktrace |
+ mov rbx, program_counter |
+ mov rcx, frame_pointer |
+ mov rdi, stack_pointer |
+ mov rbp, rcx |
+ mov rsp, rdi |
+ jmp rbx |
+ } |
+#else |
+ asm volatile("mov %[exception], %%rax;" |
+ "mov %[stacktrace], %%rdx;" |
+ "mov %[pc], %%rbx;" |
+ "mov %[fp], %%rcx;" |
+ "mov %[sp], %%rdi;" |
+ "mov %%rcx, %%rbp;" |
+ "mov %%rdi, %%rsp;" |
+ "jmp *%%rbx;" |
+ : |
+ : [exception] "m" (exception), |
+ [stacktrace] "m" (stacktrace), |
+ [pc] "m" (program_counter), |
+ [sp] "m" (stack_pointer), |
+ [fp] "m" (frame_pointer)); |
+#endif |
+ UNREACHABLE(); |
} |
void CPU::JumpToUnhandledExceptionHandler( |
- uword pc, |
- uword sp, |
- uword fp, |
- const UnhandledException& unhandled_exception) { |
- UNIMPLEMENTED(); |
+ uword program_counter, |
+ uword stack_pointer, |
+ uword frame_pointer, |
+ const UnhandledException& unhandled_exception_object) { |
+ NoGCScope no_gc; |
+ ASSERT(!unhandled_exception_object.IsNull()); |
+ RawUnhandledException* unhandled_exception = unhandled_exception_object.raw(); |
+ |
+ // Prepare for unwinding frames by destroying all the stack resources |
+ // in the previous frames. |
+ Isolate* isolate = Isolate::Current(); |
+ while (isolate->top_resource() != NULL && |
+ (reinterpret_cast<uword>(isolate->top_resource()) < stack_pointer)) { |
+ isolate->top_resource()->~StackResource(); |
+ } |
+ |
+ // Set up the unhandled exception object as the return value in EAX |
+ // and continue from the invocation stub. |
+#if defined(TARGET_OS_WINDOWS) |
+ __asm { |
Ivan Posva
2012/01/11 00:49:18
ditto.
regis
2012/01/11 01:51:12
Done.
|
+ mov rax, unhandled_exception |
+ mov rbx, program_counter |
+ mov rcx, frame_pointer |
+ mov rdi, stack_pointer |
+ mov rbp, rcx |
+ mov rsp, rdi |
+ jmp rbx |
+ } |
+#else |
+ asm volatile("mov %[unhandled_exception], %%rax;" |
+ "mov %[pc], %%rbx;" |
+ "mov %[fp], %%rcx;" |
+ "mov %[sp], %%rdi;" |
+ "mov %%rcx, %%rbp;" |
+ "mov %%rdi, %%rsp;" |
+ "jmp *%%rbx;" |
+ : |
+ : [unhandled_exception] "m" (unhandled_exception), |
+ [pc] "m" (program_counter), |
+ [sp] "m" (stack_pointer), |
+ [fp] "m" (frame_pointer)); |
+#endif |
+ UNREACHABLE(); |
} |