Chromium Code Reviews| 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(); |
| } |