Return-Path: Delivered-To: apmail-harmony-commits-archive@www.apache.org Received: (qmail 18356 invoked from network); 27 Feb 2007 12:30:54 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 27 Feb 2007 12:30:54 -0000 Received: (qmail 71370 invoked by uid 500); 27 Feb 2007 12:31:03 -0000 Delivered-To: apmail-harmony-commits-archive@harmony.apache.org Received: (qmail 71354 invoked by uid 500); 27 Feb 2007 12:31:03 -0000 Mailing-List: contact commits-help@harmony.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@harmony.apache.org Delivered-To: mailing list commits@harmony.apache.org Received: (qmail 71345 invoked by uid 99); 27 Feb 2007 12:31:03 -0000 Received: from herse.apache.org (HELO herse.apache.org) (140.211.11.133) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 27 Feb 2007 04:31:03 -0800 X-ASF-Spam-Status: No, hits=-99.5 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 27 Feb 2007 04:30:53 -0800 Received: by eris.apache.org (Postfix, from userid 65534) id DCD4F1A981A; Tue, 27 Feb 2007 04:30:32 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r512230 - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ vm/vmcore/include/ vm/vmcore/src/util/win/em64t/ vm/vmcore/src/util/win/ia32/ vm/vmcore/src/util/win/include/ Date: Tue, 27 Feb 2007 12:30:32 -0000 To: commits@harmony.apache.org From: gshimansky@apache.org X-Mailer: svnmailer-1.1.0 Message-Id: <20070227123032.DCD4F1A981A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: gshimansky Date: Tue Feb 27 04:30:31 2007 New Revision: 512230 URL: http://svn.apache.org/viewvc?view=rev&rev=512230 Log: Applied HARMONY-3233 [drlvm][winx64] Vectored exception handling for Windows x86_64 platform Tests passed on Ubuntu6 x86, Windows 2003 server x86 and SuSE9 x86_64. On windows x86_64 build passes, interpreter works. Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions_jit.h harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/include/exception_filter.h Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml?view=diff&rev=512230&r1=512229&r2=512230 ============================================================================== --- harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml (original) +++ harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml Tue Feb 27 04:30:31 2007 @@ -125,10 +125,12 @@ + + Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions_jit.h URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions_jit.h?view=diff&rev=512230&r1=512229&r2=512230 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions_jit.h (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/exceptions_jit.h Tue Feb 27 04:30:31 2007 @@ -94,6 +94,6 @@ Class_Handle exn_get_class_cast_exception_type(); // Exception catch callback for jvm ti support implementation -void asm_jvmti_exception_catch_callback(); +extern "C" void asm_jvmti_exception_catch_callback(); #endif // _EXCEPTIONS_JIT_H_ Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h?view=diff&rev=512230&r1=512229&r2=512230 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/vm_core_types.h Tue Feb 27 04:30:31 2007 @@ -99,6 +99,8 @@ uint64 r10; uint64 r11; + uint32 eflags; + void reset_ip() { rip = 0; } void* get_ip() { return (void*)rip; } void set_ip(void* src_ip) { rip = (uint64)src_ip; } Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp?view=diff&rev=512230&r1=512229&r2=512230 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/em64t/nt_exception_filter.cpp Tue Feb 27 04:30:31 2007 @@ -19,160 +19,95 @@ * @version $Revision: 1.1.2.1.4.5 $ */ -#undef LOG_DOMAIN -#define LOG_DOMAIN "nt_exception_filter" - +#include #include "platform_lowlevel.h" -#include "Class.h" -#include "Environment.h" -#include "exceptions.h" -#include "exceptions_jit.h" -#include "method_lookup.h" -#include "vm_strings.h" -#include "vm_threads.h" -#include "compile.h" -#include "ini.h" -#include "cxxlog.h" - -#include "exception_filter.h" - -#include "thread_generic.h" - - +#include "vm_core_types.h" -// Afremov Pavel 20050117 -#include "../m2n_em64t_internal.h" void nt_to_vm_context(PCONTEXT pcontext, Registers* regs) { + regs->rsp = pcontext->Rsp; + regs->rbp = pcontext->Rbp; + regs->rip = pcontext->Rip; + + regs->rbx = pcontext->Rbx; + regs->r12 = pcontext->R12; + regs->r13 = pcontext->R13; + regs->r14 = pcontext->R14; + regs->r15 = pcontext->R15; + regs->rax = pcontext->Rax; regs->rcx = pcontext->Rcx; regs->rdx = pcontext->Rdx; - regs->rdi = pcontext->Rdi; regs->rsi = pcontext->Rsi; - regs->rbx = pcontext->Rbx; - regs->rbp = pcontext->Rbp; - regs->rip = pcontext->Rip; - regs->rsp = pcontext->Rsp; + regs->rdi = pcontext->Rdi; + regs->r8 = pcontext->R8; + regs->r9 = pcontext->R9; + regs->r10 = pcontext->R10; + regs->r11 = pcontext->R11; + + regs->eflags = pcontext->EFlags; } void vm_to_nt_context(Registers* regs, PCONTEXT pcontext) { pcontext->Rsp = regs->rsp; - pcontext->Rip = regs->rip; pcontext->Rbp = regs->rbp; + pcontext->Rip = regs->rip; + pcontext->Rbx = regs->rbx; - pcontext->Rsi = regs->rsi; - pcontext->Rdi = regs->rdi; + pcontext->R12 = regs->r12; + pcontext->R13 = regs->r13; + pcontext->R14 = regs->r14; + pcontext->R15 = regs->r15; + pcontext->Rax = regs->rax; pcontext->Rcx = regs->rcx; pcontext->Rdx = regs->rdx; -} - -int NT_exception_filter(LPEXCEPTION_POINTERS p_NT_exception) -{ - - // this filter catches _all_ null ptr exceptions including those caused by - // VM internal code. To elimate confusion over what caused the null ptr - // exception, we first make sure the exception was thrown inside a Java - // method else assert(0); <--- means it was thrown by VM C/C++ code. - - Global_Env *env = VM_Global_State::loader_env; - - VM_Code_Type vmct = - vm_identify_eip((void *)p_NT_exception->ContextRecord->Rip); - if(vmct != VM_TYPE_JAVA) { - if (!get_boolean_property("vm.assert_dialog", TRUE, VM_PROPERTIES)) { - LWARN(43, "Fatal exception, terminating"); - return EXCEPTION_EXECUTE_HANDLER; - } - return EXCEPTION_CONTINUE_SEARCH; - } - - // since we are now sure NPE occured in java code, gc should also have been disabled - assert(!hythread_is_suspend_enabled()); - - - volatile ManagedObject *exc = 0; - Class *exc_clss = 0; - switch(p_NT_exception->ExceptionRecord->ExceptionCode) { - case STATUS_ACCESS_VIOLATION: - // null pointer exception -- see ...\vc\include\winnt.h - { - // Lazy exception object creation - exc_clss = env->java_lang_NullPointerException_Class; - } - break; - - case STATUS_INTEGER_DIVIDE_BY_ZERO: - // divide by zero exception -- see ...\vc\include\winnt.h - { - // Lazy exception object creation - exc_clss = env->java_lang_ArithmeticException_Class; - } - break; - - case STATUS_PRIVILEGED_INSTRUCTION: - { - LDIE(36, "Unexpected exception code"); - } - break; - - default: - return EXCEPTION_CONTINUE_SEARCH; - } - - Registers regs; - - nt_to_vm_context(p_NT_exception->ContextRecord, ®s); - - bool java_code = (vm_identify_eip((void *)regs.rip) == VM_TYPE_JAVA); - exn_athrow_regs(®s, exc_clss, java_code); - - vm_to_nt_context(®s, p_NT_exception->ContextRecord); - - return EXCEPTION_CONTINUE_EXECUTION; -} //NT_exception_filter - -int call_the_run_method3( void * p_xx ){ - LPEXCEPTION_POINTERS p_NT_exception; - int NT_exception_filter(LPEXCEPTION_POINTERS p_NT_exception); - - // NT null pointer exception support - __try { - // TODO: couldn't find where call_the_run_method() body is - //call_the_run_method(p_xx); - assert(0); - return 0; - } - __except ( p_NT_exception = GetExceptionInformation(), - NT_exception_filter(p_NT_exception) ) { - - ABORT("Uncaught exception"); // get here only if NT_null_ptr_filter() screws up - - return 0; - } // NT null pointer exception support - -} - -// TODO: the functions below need an implementation -static void asm_exception_catch_callback() { -assert(0); -} + pcontext->Rsi = regs->rsi; + pcontext->Rdi = regs->rdi; + pcontext->R8 = regs->r8; + pcontext->R9 = regs->r9; + pcontext->R10 = regs->r10; + pcontext->R11 = regs->r11; -void asm_jvmti_exception_catch_callback() { -assert(0); + pcontext->EFlags = regs->eflags; } -LONG NTAPI vectored_exception_handler(LPEXCEPTION_POINTERS nt_exception) +void print_state(LPEXCEPTION_POINTERS nt_exception, const char *msg) { - return EXCEPTION_CONTINUE_SEARCH; + fprintf(stderr, "...VM Crashed!\n"); + if (msg != 0) + fprintf(stderr, "Windows reported exception: %s\n", msg); + else + fprintf(stderr, "Windows reported exception: 0x%x\n", nt_exception->ExceptionRecord->ExceptionCode); + + fprintf(stderr, "Registers:\n"); + fprintf(stderr, " RAX: 0x%16lx, RBX: 0x%16lx\n", + nt_exception->ContextRecord->Rax, nt_exception->ContextRecord->Rbx); + fprintf(stderr, " RCX: 0x%16lx, RDX: 0x%16lx\n", + nt_exception->ContextRecord->Rcx, nt_exception->ContextRecord->Rdx); + fprintf(stderr, " RSI: 0x%16lx, RDI: 0x%16lx\n", + nt_exception->ContextRecord->Rsi, nt_exception->ContextRecord->Rdi); + fprintf(stderr, " RSP: 0x%16lx, RBP: 0x%16lx\n", + nt_exception->ContextRecord->Rsp, nt_exception->ContextRecord->Rbp); + fprintf(stderr, " R8: 0x%16lx, R9: 0x%16lx\n", + nt_exception->ContextRecord->R8, nt_exception->ContextRecord->R9); + fprintf(stderr, " R10: 0x%16lx, R11P: 0x%16lx\n", + nt_exception->ContextRecord->R10, nt_exception->ContextRecord->R11); + fprintf(stderr, " RS12: 0x%16lx, R13: 0x%16lx\n", + nt_exception->ContextRecord->R12, nt_exception->ContextRecord->R13); + fprintf(stderr, " RS14: 0x%16lx, R15: 0x%16lx\n", + nt_exception->ContextRecord->R14, nt_exception->ContextRecord->R15); } -void init_stack_info() { +void* regs_get_sp(Registers* pregs) +{ + return (void*)pregs->rsp; } -size_t get_available_stack_size() { - return 1000000; +void regs_push_param_onto_stack(Registers* pregs, POINTER_SIZE_INT param) +{ + pregs->rsp = pregs->rsp - 8; + *((uint64*)pregs->rsp) = param; } - Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp?view=diff&rev=512230&r1=512229&r2=512230 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/ia32/nt_exception_filter.cpp Tue Feb 27 04:30:31 2007 @@ -19,28 +19,12 @@ * @version $Revision: 1.1.2.1.4.4 $ */ -#include "clog.h" -#include "method_lookup.h" -#include "Environment.h" -#include "exceptions.h" +#include +#include "platform_lowlevel.h" +#include "vm_core_types.h" #include "exceptions_jit.h" -#include "interpreter_exports.h" -#include "stack_iterator.h" -#include "stack_dump.h" -#include "jvmti_break_intf.h" -#include "m2n.h" - -// Windows specific -#include -#include - -#if INSTRUMENTATION_BYTE == INSTRUMENTATION_BYTE_INT3 -#define JVMTI_EXCEPTION_STATUS STATUS_BREAKPOINT -#elif INSTRUMENTATION_BYTE == INSTRUMENTATION_BYTE_HLT || INSTRUMENTATION_BYTE == INSTRUMENTATION_BYTE_CLI -#define JVMTI_EXCEPTION_STATUS STATUS_PRIVILEGED_INSTRUCTION -#else -#error Unknown value of INSTRUMENTATION_BYTE -#endif +#include "exception_filter.h" + void nt_to_vm_context(PCONTEXT context, Registers* regs) { @@ -70,168 +54,26 @@ context->EFlags = regs->eflags; } -static void print_state(LPEXCEPTION_POINTERS nt_exception, const char *msg) +void print_state(LPEXCEPTION_POINTERS nt_exception, const char *msg) { fprintf(stderr, "...VM Crashed!\n"); - if (msg != 0) - { + + if (msg != 0) fprintf(stderr, "Windows reported exception: %s\n", msg); - } - else - { + else fprintf(stderr, "Windows reported exception: 0x%x\n", nt_exception->ExceptionRecord->ExceptionCode); - } fprintf(stderr, "Registers:\n"); - fprintf(stderr, " EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX=0x%08x\n", - nt_exception->ContextRecord->Eax, - nt_exception->ContextRecord->Ebx, - nt_exception->ContextRecord->Ecx, - nt_exception->ContextRecord->Edx); - fprintf(stderr, " ESI: 0x%08x, EDI: 0x%08x, ESP: 0x%08x, EBP=0x%08x\n", - nt_exception->ContextRecord->Esi, - nt_exception->ContextRecord->Edi, - nt_exception->ContextRecord->Esp, - nt_exception->ContextRecord->Ebp); + fprintf(stderr, " EAX: 0x%08x, EBX: 0x%08x, ECX: 0x%08x, EDX: 0x%08x\n", + nt_exception->ContextRecord->Eax, nt_exception->ContextRecord->Ebx, + nt_exception->ContextRecord->Ecx, nt_exception->ContextRecord->Edx); + fprintf(stderr, " ESI: 0x%08x, EDI: 0x%08x, ESP: 0x%08x, EBP: 0x%08x\n", + nt_exception->ContextRecord->Esi, nt_exception->ContextRecord->Edi, + nt_exception->ContextRecord->Esp, nt_exception->ContextRecord->Ebp); fprintf(stderr, " EIP: 0x%08x\n", nt_exception->ContextRecord->Eip); } - -static void print_callstack(LPEXCEPTION_POINTERS nt_exception) { - PCONTEXT context = nt_exception->ContextRecord; - Registers regs; - nt_to_vm_context(context, ®s); - st_print_stack(®s); - fflush(stderr); -} - -/* - * Information about stack - */ -inline void* find_stack_addr() { - void* stack_addr; - size_t reg_size; - MEMORY_BASIC_INFORMATION memory_information; - - VirtualQuery(&memory_information, &memory_information, sizeof(memory_information)); - reg_size = memory_information.RegionSize; - stack_addr =((char*) memory_information.BaseAddress) + reg_size; - - return stack_addr; -} - -inline size_t find_stack_size() { - void* stack_addr; - size_t stack_size; - size_t reg_size; - MEMORY_BASIC_INFORMATION memory_information; - - VirtualQuery(&memory_information, &memory_information, sizeof(memory_information)); - reg_size = memory_information.RegionSize; - stack_addr = ((char*) memory_information.BaseAddress) + reg_size; - stack_size = ((char*) stack_addr) - ((char*) memory_information.AllocationBase); - - return stack_size; -} - -inline size_t find_guard_page_size() { - size_t guard_size; - SYSTEM_INFO system_info; - - GetSystemInfo(&system_info); - guard_size = system_info.dwPageSize; - - return guard_size; -} - -inline size_t find_guard_stack_size() { - // guaerded stack size on windows can be equals one page size only :( - return find_guard_page_size(); -} - -static size_t common_stack_size; -static size_t common_guard_stack_size; -static size_t common_guard_page_size; - -inline void* get_stack_addr() { - return p_TLS_vmthread->stack_addr; -} - -inline size_t get_stack_size() { - return common_stack_size; -} - -inline size_t get_guard_stack_size() { - return common_guard_stack_size; -} - -inline size_t get_guard_page_size() { - return common_guard_page_size; -} - - -void init_stack_info() { - p_TLS_vmthread->stack_addr = find_stack_addr(); - common_stack_size = find_stack_size(); - common_guard_stack_size = find_guard_stack_size(); - common_guard_page_size =find_guard_page_size(); -} - -void set_guard_stack() { - void* stack_addr = get_stack_addr(); - size_t stack_size = get_stack_size(); - size_t page_size = get_guard_page_size(); - - if (!VirtualFree((char*)stack_addr - stack_size + page_size, - page_size, MEM_DECOMMIT)) { - // should be successful always - assert(0); - } - - DWORD oldProtect; - - if (!VirtualProtect((char*)stack_addr - stack_size + page_size + page_size, - page_size, PAGE_GUARD | PAGE_READWRITE, &oldProtect)) { - // should be successful always - assert(0); - } - - p_TLS_vmthread->restore_guard_page = false; -} - -size_t get_available_stack_size() { - char* stack_adrr = (char*) get_stack_addr(); - size_t used_stack_size = ((size_t)stack_adrr) - ((size_t)(&stack_adrr)); - size_t available_stack_size = - get_stack_size() - used_stack_size - - get_guard_page_size() - get_guard_stack_size(); - return available_stack_size; -} -size_t get_default_stack_size() { - size_t default_stack_size = get_stack_size(); - return default_stack_size; -} -bool check_available_stack_size(size_t required_size) { - if (get_available_stack_size() < required_size) { - Global_Env *env = VM_Global_State::loader_env; - exn_raise_by_class(env->java_lang_StackOverflowError_Class); - return false; - } else { - return true; - } -} - -// exception catch callback to restore stack after Stack Overflow Error -static void __cdecl exception_catch_callback_wrapper(){ - exception_catch_callback(); -} - -// exception catch support for JVMTI -static void __cdecl jvmti_exception_catch_callback_wrapper(Registers regs){ - jvmti_exception_catch_callback(®s); -} - -static void __declspec(naked) asm_exception_catch_callback() { +void __declspec(naked) asm_exception_catch_callback() { __asm { push ebp mov ebp, esp @@ -239,7 +81,10 @@ push ebx push ecx push edx + pushfd + cld call exception_catch_callback_wrapper + popfd pop edx pop ecx pop ebx @@ -253,34 +98,23 @@ __asm { push ebp mov ebp, esp - add esp, -36 - mov [ebp-36], eax - mov [ebp-32], ebx - mov [ebp-28], ecx - mov [ebp-24], edx - mov eax, esp - mov ebx, [ebp] - mov ecx, [ebp+4] - add eax, 44 - mov [ebp-20], edi - mov [ebp-16], esi - mov [ebp-12], ebx - mov [ebp-8], eax - mov [ebp-4], ecx + push eax + push ebx + push ecx + push edx + pushfd + cld call jvmti_exception_catch_callback_wrapper - mov eax, [ebp-36] - mov ebx, [ebp-32] - mov ecx, [ebp-28] - mov edx, [ebp-24] - add esp, 36 + popfd + pop edx + pop ecx + pop ebx + pop eax leave ret } } -static LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception); -void __cdecl asm_c_exception_handler(Class *exn_class, bool in_java); - LONG __declspec(naked) NTAPI vectored_exception_handler(LPEXCEPTION_POINTERS nt_exception) { __asm { @@ -293,167 +127,11 @@ call vectored_exception_handler_internal popfd pop ebp - ret 4 + ret 4 } } -static LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception) -{ - DWORD code = nt_exception->ExceptionRecord->ExceptionCode; - PCONTEXT context = nt_exception->ContextRecord; - bool flag_replaced = false; - uint32 saved_eip = context->Eip; - - // If exception is occured in processor instruction previously - // instrumented by breakpoint, the actual exception address will reside - // in jvmti_jit_breakpoints_handling_buffer - // We should replace exception address with saved address of instruction - uint32 break_buf = (uint32)p_TLS_vmthread->jvmti_jit_breakpoints_handling_buffer; - if (saved_eip >= break_buf && - saved_eip < break_buf + 50) - { - flag_replaced = true; - context->Eip = (uint32)p_TLS_vmthread->jvmti_saved_exception_registers.eip; - } - - TRACE2("signals", ("VEH received an exception: code = %x, eip = %p, esp = %p", - nt_exception->ExceptionRecord->ExceptionCode, - context->Eip, context->Esp)); - - // the possible reasons for hardware exception are - // - segfault or division by zero in java code - // => NullPointerException or ArithmeticException - // - // - breakpoint or privileged instruction in java code - // => send jvmti breakpoint event - // - // - stack overflow, either in java or in native - // => StackOverflowError - // - // - other (internal VM error or debugger breakpoint) - // => delegate to default handler - - bool in_java = (vm_identify_eip((void*)context->Eip) == VM_TYPE_JAVA); - - // delegate "other" cases to default handler - if (!in_java && code != STATUS_STACK_OVERFLOW) - { - context->Eip = saved_eip; - return EXCEPTION_CONTINUE_SEARCH; - } - - // if HWE occured in java code, suspension should also have been disabled - assert(!in_java || !hythread_is_suspend_enabled()); - - Global_Env *env = VM_Global_State::loader_env; - // the actual exception object will be created lazily, - // we determine only exception class here - Class *exn_class = 0; - - switch(nt_exception->ExceptionRecord->ExceptionCode) - { - case STATUS_STACK_OVERFLOW: - { - TRACE2("signals", - ("StackOverflowError detected at eip = %p, esp = %p", - context->Eip,context->Esp)); - - p_TLS_vmthread->restore_guard_page = true; - exn_class = env->java_lang_StackOverflowError_Class; - if (in_java) { - // stack overflow occured in java code: - // nothing special to do - } else if (is_unwindable()) { - // stack overflow occured in native code that can be unwound - // safely. - // Throwing exception requires suspend disabled status - if (hythread_is_suspend_enabled()) - hythread_suspend_disable(); - } else { - // stack overflow occured in native code that - // cannot be unwound. - // Mark raised exception in TLS and resume execution - exn_raise_by_class(env->java_lang_StackOverflowError_Class); - context->Eip = saved_eip; - return EXCEPTION_CONTINUE_EXECUTION; - } - } - break; - case STATUS_ACCESS_VIOLATION: - { - TRACE2("signals", - ("NullPointerException detected at eip = %p", context->Eip)); - exn_class = env->java_lang_NullPointerException_Class; - } - break; - - case STATUS_INTEGER_DIVIDE_BY_ZERO: - { - TRACE2("signals", - ("ArithmeticException detected at eip = %p", context->Eip)); - exn_class = env->java_lang_ArithmeticException_Class; - } - break; - case JVMTI_EXCEPTION_STATUS: - // JVMTI breakpoint in JITted code - { - // Breakpoints should not occur in breakpoint buffer - assert(!flag_replaced); - - Registers regs; - nt_to_vm_context(context, ®s); - TRACE2("signals", - ("JVMTI breakpoint detected at eip = %p", regs.eip)); - bool handled = jvmti_jit_breakpoint_handler(®s); - if (handled) - { - vm_to_nt_context(®s, context); - return EXCEPTION_CONTINUE_EXECUTION; - } - else - return EXCEPTION_CONTINUE_SEARCH; - } - default: - // unexpected hardware exception occured in java code - context->Eip = saved_eip; - return EXCEPTION_CONTINUE_SEARCH; - } - - // we must not call potentially blocking or suspendable code - // (i.e. java code of exception constructor) from exception - // handler, because this handler may hold a system-wide lock, - // and this may result in a deadlock. - - // it was reported that exception handler grabs a system - // lock on Windows XPsp2 and 2003sp0, but not on a 2003sp1 - - // save register context of hardware exception site - // into thread-local registers snapshot - assert(p_TLS_vmthread); - nt_to_vm_context(context, &p_TLS_vmthread->regs); - - // __cdecl <=> push parameters in the reversed order - // push in_java argument onto stack - context->Esp -= 4; - *((uint32*) context->Esp) = (uint32)in_java; - // push the exn_class argument onto stack - context->Esp -= 4; - assert(exn_class); - *((uint32*) context->Esp) = (uint32)exn_class; - // imitate return IP on stack - context->Esp -= 4; - - // set up the real exception handler address - context->Eip = (uint32)asm_c_exception_handler; - - // exit NT exception handler and transfer - // control to VM exception handler - return EXCEPTION_CONTINUE_EXECUTION; -} - -static void __cdecl c_exception_handler(Class*, bool); - -void __declspec(naked) __cdecl asm_c_exception_handler(Class *exn_class, bool in_java) +void __declspec(naked) asm_c_exception_handler(Class *exn_class, bool in_java) { __asm { push ebp @@ -472,37 +150,13 @@ } } - -static void __cdecl c_exception_handler(Class *exn_class, bool in_java) +void* regs_get_sp(Registers* pregs) { - // this exception handler is executed *after* NT exception handler returned - DebugUtilsTI* ti = VM_Global_State::loader_env->TI; - // Create local copy for registers because registers in TLS can be changed - Registers regs = p_TLS_vmthread->regs; - - M2nFrame* prev_m2n = m2n_get_last_frame(); - M2nFrame* m2n = NULL; - if (in_java) - m2n = m2n_push_suspended_frame(®s); - - TRACE2("signals", ("should throw exception %p at EIP=%p, ESP=%p", - exn_class, regs.eip, regs.esp)); - exn_athrow_regs(®s, exn_class, false); - - if (ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_EXCEPTION_EVENT)) { - regs.esp = regs.esp - 4; - *((uint32*) regs.esp) = regs.eip; - regs.eip = ((uint32)asm_jvmti_exception_catch_callback); - } else if (p_TLS_vmthread->restore_guard_page) { - regs.esp = regs.esp - 4; - *((uint32*) regs.esp) = regs.eip; - regs.eip = ((uint32)asm_exception_catch_callback); - } + return (void*)pregs->esp; +} - StackIterator *si = - si_create_from_registers(®s, false, prev_m2n); - if (m2n) - STD_FREE(m2n); - si_transfer_control(si); - assert(!"si_transfer_control should not return"); +void regs_push_param_onto_stack(Registers* pregs, POINTER_SIZE_INT param) +{ + pregs->esp = pregs->esp - 4; + *((uint32*)pregs->esp) = param; } Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/include/exception_filter.h URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/include/exception_filter.h?view=diff&rev=512230&r1=512229&r2=512230 ============================================================================== --- harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/include/exception_filter.h (original) +++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/util/win/include/exception_filter.h Tue Feb 27 04:30:31 2007 @@ -23,8 +23,47 @@ #define nt_exception_filter_h #include "platform_lowlevel.h" +#include "vm_core_types.h" + +#ifdef __cplusplus +extern "C" { +#endif LONG NTAPI vectored_exception_handler(LPEXCEPTION_POINTERS nt_exception); + +// Internal exception handler +// Is used when vectored_exception_handler is assembler wrapper +LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception); + +// Function to throw exception +void __cdecl c_exception_handler(Class* exn_class, bool in_java); +// Assembler wrapper for c_exception_handler; is used to clear direction flag +void asm_c_exception_handler(Class *exn_class, bool in_java); + +// exception catch callback to restore stack after Stack Overflow Error +void __cdecl exception_catch_callback_wrapper(); +// exception catch support for JVMTI + void __cdecl jvmti_exception_catch_callback_wrapper(); +// Assembler wrappers; are used to restore registers +void asm_exception_catch_callback(); +//void asm_jvmti_exception_catch_callback(); // Declared in exceptions_jit.h + +#ifdef __cplusplus +} // extern "C" +#endif + + +// Prints register state +void print_state(LPEXCEPTION_POINTERS nt_exception, const char *msg); + +// Conversion from NT context to VM Registers structure and visa versa +void nt_to_vm_context(PCONTEXT context, Registers* regs); +void vm_to_nt_context(Registers* regs, PCONTEXT context); + +// Fuctions to manipulate with Registers structure +void* regs_get_sp(Registers* pregs); +void regs_push_param_onto_stack(Registers* pregs, POINTER_SIZE_INT param); + #endif // nt_exception_filter_h