You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2007/03/21 21:18:49 UTC

svn commit: r520988 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3404/ vm/vmcore/src/exception/ vm/vmcore/src/jvmti/

Author: gshimansky
Date: Wed Mar 21 13:18:48 2007
New Revision: 520988

URL: http://svn.apache.org/viewvc?view=rev&rev=520988
Log:
Fixed bug in HARMONY-3404 [drlvm][testing] Tomcat application is OK to start but on failed on shutdown on WinXP

The bug is that continuous native frames weren't supported by exception
propagation mechanism. When called native method via reflection (which
is a native method as well) threw an exception, VM would abort on assertion.
Committed the fix and regression test for this bug.


Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3404/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.cpp   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.java   (with props)
    harmony/enhanced/drlvm/trunk/src/test/regression/H3404/run.test.xml   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.cpp?view=auto&rev=520988
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.cpp (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.cpp Wed Mar 21 13:18:48 2007
@@ -0,0 +1,27 @@
+#include <jni.h>
+#include <assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT void JNICALL Java_org_apache_harmony_drlvm_tests_regression_h3404_H3404_mmm
+  (JNIEnv *env, jclass that, jint depth)
+{
+    if (depth > 0)
+    {
+        jmethodID mid = env->GetStaticMethodID(that, "mmm", "(I)V");
+        assert(mid);
+        env->CallStaticVoidMethod(that, mid, depth - 1);
+    }
+    else
+    {
+        jclass ecl = env->FindClass("org/apache/harmony/drlvm/tests/regression/h3404/MyException");
+        assert(ecl);
+        env->ThrowNew(ecl, "Crash me");
+    }
+}
+
+#ifdef __cplusplus
+}
+#endif

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.java?view=auto&rev=520988
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.java Wed Mar 21 13:18:48 2007
@@ -0,0 +1,32 @@
+package org.apache.harmony.drlvm.tests.regression.h3404;
+
+import junit.framework.TestCase;
+
+public class H3404 extends TestCase {
+    public static native void mmm(int depth) throws MyException;
+
+    static {
+        System.loadLibrary("H3404");
+    }
+    
+    public H3404(String message) {
+        super(message);
+    }
+    
+    public void test() {
+        try {
+            mmm(10);
+        } catch (MyException e) {
+            System.out.println("Test passed");
+            return;
+        }
+        fail("No exception was thrown from native code");
+    }
+}
+
+class MyException extends Exception {
+    public MyException(String message) {
+        super(message);
+    }
+}
+

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3404/H3404.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3404/run.test.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3404/run.test.xml?view=auto&rev=520988
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3404/run.test.xml (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3404/run.test.xml Wed Mar 21 13:18:48 2007
@@ -0,0 +1,11 @@
+<project name="RUN HARMONY-3404 Regression Test">
+    <target name="run-test">
+        <run-junit-test 
+            test="org.apache.harmony.drlvm.tests.regression.h3404.H3404">
+            <junit-element>
+              <sysproperty key="java.library.path" value="${reg.test.native.path}/H3404"/>
+            </junit-element>
+        </run-junit-test>
+    </target>
+</project>
+

Propchange: harmony/enhanced/drlvm/trunk/src/test/regression/H3404/run.test.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp?view=diff&rev=520988&r1=520987&r2=520988
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp Wed Mar 21 13:18:48 2007
@@ -201,13 +201,24 @@
         si_goto_previous(si);
     }
 
-    assert(!si_is_native(si));
+    Method *interrupted_method;
+    NativeCodePtr interrupted_method_location;
+    JIT *interrupted_method_jit;
 
-    CodeChunkInfo *interrupted_cci = si_get_code_chunk_info(si);
-    assert(interrupted_cci);
-    Method *interrupted_method = interrupted_cci->get_method();
-    NativeCodePtr interrupted_method_location = si_get_ip(si);
-    JIT *interrupted_method_jit = interrupted_cci->get_jit();
+    if (!si_is_native(si))
+    {
+        CodeChunkInfo *interrupted_cci = si_get_code_chunk_info(si);
+        assert(interrupted_cci);
+        interrupted_method = interrupted_cci->get_method();
+        interrupted_method_location = si_get_ip(si);
+        interrupted_method_jit = interrupted_cci->get_jit();
+    }
+    else
+    {
+        interrupted_method = m2n_get_method(si_get_m2n(si));
+        interrupted_method_location = 0;
+        interrupted_method_jit = 0;
+    }
 
     if (NULL != *exn_obj)
     {
@@ -218,6 +229,7 @@
         // So in this case IP reported by stack iterator is past the athrow bytecode
         // and should be moved back to be inside of bytecode location for interrupted
         // method.
+
         interrupted_method_location = (NativeCodePtr)((POINTER_SIZE_INT)interrupted_method_location - 1);
 
         // Determine the type of the exception for the type tests below.
@@ -248,112 +260,116 @@
     Class_Handle search_exn_class = !VM_Global_State::loader_env->IsVmShutdowning()
         ? exn_class : VM_Global_State::loader_env->JavaLangObject_Class;
 
-    bool same_frame = true;
-    while (!si_is_past_end(si) && !si_is_native(si)) {
-        CodeChunkInfo *cci = si_get_code_chunk_info(si);
-        assert(cci);
-        Method *method = cci->get_method();
-        JIT *jit = cci->get_jit();
-        assert(method && jit);
-        NativeCodePtr ip = si_get_ip(si);
-        bool is_ip_past = !!si_get_jit_context(si)->is_ip_past;
+    if (!si_is_native(si))
+    {
+        bool same_frame = true;
+        while (!si_is_past_end(si) && !si_is_native(si)) {
+            CodeChunkInfo *cci = si_get_code_chunk_info(si);
+            assert(cci);
+            Method *method = cci->get_method();
+            JIT *jit = cci->get_jit();
+            assert(method && jit);
+            NativeCodePtr ip = si_get_ip(si);
+            bool is_ip_past = !!si_get_jit_context(si)->is_ip_past;
 
 #ifdef VM_STATS
-        cci->num_throws++;
+            cci->num_throws++;
 #endif // VM_STATS
 
-        // Examine this frame's exception handlers looking for a match
-        unsigned num_handlers = cci->get_num_target_exception_handlers();
-        for (unsigned i = 0; i < num_handlers; i++) {
-            Target_Exception_Handler_Ptr handler =
-                cci->get_target_exception_handler_info(i);
-            if (!handler)
-                continue;
-            if (handler->is_in_range(ip, is_ip_past)
-                && handler->is_assignable(search_exn_class)) {
-                // Found a handler that catches the exception.
+            // Examine this frame's exception handlers looking for a match
+            unsigned num_handlers = cci->get_num_target_exception_handlers();
+            for (unsigned i = 0; i < num_handlers; i++) {
+                Target_Exception_Handler_Ptr handler =
+                    cci->get_target_exception_handler_info(i);
+                if (!handler)
+                    continue;
+                if (handler->is_in_range(ip, is_ip_past)
+                    && handler->is_assignable(search_exn_class)) {
+                    // Found a handler that catches the exception.
 #ifdef VM_STATS
-                cci->num_catches++;
-                if (same_frame) {
-                    VM_Statistics::get_vm_stats().num_exceptions_caught_same_frame++;
-                }
-                if (handler->is_exc_obj_dead()) {
-                    VM_Statistics::get_vm_stats().num_exceptions_dead_object++;
-                    if (!*exn_obj) {
-                        VM_Statistics::get_vm_stats().num_exceptions_object_not_created++;
+                    cci->num_catches++;
+                    if (same_frame) {
+                        VM_Statistics::get_vm_stats().num_exceptions_caught_same_frame++;
+                    }
+                    if (handler->is_exc_obj_dead()) {
+                        VM_Statistics::get_vm_stats().num_exceptions_dead_object++;
+                        if (!*exn_obj) {
+                            VM_Statistics::get_vm_stats().num_exceptions_object_not_created++;
+                        }
                     }
-                }
 #endif // VM_STATS
-                // Setup handler context
-                jit->fix_handler_context(method, si_get_jit_context(si));
-                si_set_ip(si, handler->get_handler_ip(), false);
-
-                // Start single step in exception handler
-                if (ti->isEnabled() && ti->is_single_step_enabled())
-                {
-                    VM_thread *vm_thread = p_TLS_vmthread;
-                    ti->vm_brpt->lock();
-                    if (NULL != vm_thread->ss_state)
+                    // Setup handler context
+                    jit->fix_handler_context(method, si_get_jit_context(si));
+                    si_set_ip(si, handler->get_handler_ip(), false);
+
+                    // Start single step in exception handler
+                    if (ti->isEnabled() && ti->is_single_step_enabled())
                     {
-                        uint16 bc;
-                        NativeCodePtr ip = handler->get_handler_ip();
-                        OpenExeJpdaError UNREF result =
-                            jit->get_bc_location_for_native(method, ip, &bc);
-                        assert(EXE_ERROR_NONE == result);
+                        VM_thread *vm_thread = p_TLS_vmthread;
+                        ti->vm_brpt->lock();
+                        if (NULL != vm_thread->ss_state)
+                        {
+                            uint16 bc;
+                            NativeCodePtr ip = handler->get_handler_ip();
+                            OpenExeJpdaError UNREF result =
+                                jit->get_bc_location_for_native(method, ip, &bc);
+                            assert(EXE_ERROR_NONE == result);
 
-                        jvmti_StepLocation method_start = {(Method *)method, ip, bc, false};
+                            jvmti_StepLocation method_start = {(Method *)method, ip, bc, false};
 
-                        jvmti_set_single_step_breakpoints(ti, vm_thread,
+                            jvmti_set_single_step_breakpoints(ti, vm_thread,
                                 &method_start, 1);
+                        }
+                        ti->vm_brpt->unlock();
                     }
-                    ti->vm_brpt->unlock();
-                }
 
-                // Create exception if necessary
-                if (!*exn_obj && !handler->is_exc_obj_dead()) {
-                    *exn_obj = create_lazy_exception(exn_class, exn_constr,
-                        jit_exn_constr_args, vm_exn_constr_args);
-                }
-
-                if (jvmti_is_exception_event_requested()) {
                     // Create exception if necessary
-                    if (NULL == *exn_obj) {
+                    if (!*exn_obj && !handler->is_exc_obj_dead()) {
                         *exn_obj = create_lazy_exception(exn_class, exn_constr,
                             jit_exn_constr_args, vm_exn_constr_args);
                     }
 
-                    BEGIN_RAISE_AREA;
-                    // Reload exception object pointer because it could have
-                    // moved while calling JVMTI callback
-                    *exn_obj = jvmti_jit_exception_event_callback_call(*exn_obj,
-                        interrupted_method_jit, interrupted_method,
-                        interrupted_method_location,
-                        jit, method, handler->get_handler_ip());
-                    END_RAISE_AREA;
-                }
+                    if (jvmti_is_exception_event_requested()) {
+                        // Create exception if necessary
+                        if (NULL == *exn_obj) {
+                            *exn_obj = create_lazy_exception(exn_class, exn_constr,
+                                jit_exn_constr_args, vm_exn_constr_args);
+                        }
+
+                        BEGIN_RAISE_AREA;
+                        // Reload exception object pointer because it could have
+                        // moved while calling JVMTI callback
+
+                        *exn_obj = jvmti_jit_exception_event_callback_call(*exn_obj,
+                            interrupted_method_jit, interrupted_method,
+                            interrupted_method_location,
+                            jit, method, handler->get_handler_ip());
+
+                        END_RAISE_AREA;
+                    }
 
-                TRACE2("exn", ("setting return pointer to %d", exn_obj));
+                    TRACE2("exn", ("setting return pointer to %d", exn_obj));
 
-                si_set_return_pointer(si, (void **) exn_obj);
-                si_free(throw_si);
-                return;
+                    si_set_return_pointer(si, (void **) exn_obj);
+                    si_free(throw_si);
+                    return;
+                }
             }
-        }
 
-        // No appropriate handler found, undo synchronization
-        vm_monitor_exit_synchronized_method(si);
+            // No appropriate handler found, undo synchronization
+            vm_monitor_exit_synchronized_method(si);
 
-        BEGIN_RAISE_AREA;
-        jvalue ret_val = {(jlong)0};
-        jvmti_process_method_exception_exit_event(
-            reinterpret_cast<jmethodID>(method), JNI_TRUE, ret_val, si);
-        END_RAISE_AREA;
-
-        // Goto previous frame
-        si_goto_previous(si);
-        same_frame = false;
+            BEGIN_RAISE_AREA;
+            jvalue ret_val = {(jlong)0};
+            jvmti_process_method_exception_exit_event(
+                reinterpret_cast<jmethodID>(method), JNI_TRUE, ret_val, si);
+            END_RAISE_AREA;
+
+            // Goto previous frame
+            si_goto_previous(si);
+            same_frame = false;
+        }
     }
-
     // Exception propagates to the native code
     assert(si_is_native(si));
 
@@ -371,6 +387,7 @@
 
     // Reload exception object pointer because it could have
     // moved while calling JVMTI callback
+
     *exn_obj = jvmti_jit_exception_event_callback_call(*exn_obj,
         interrupted_method_jit, interrupted_method, interrupted_method_location,
         NULL, NULL, NULL);

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp?view=diff&rev=520988&r1=520987&r2=520988
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_event.cpp Wed Mar 21 13:18:48 2007
@@ -1497,22 +1497,19 @@
 
     jlocation location = -1, catch_location = -1;
 
-    if (NULL == jit)
+    uint16 bc = 0;
+    if (NULL != jit)
     {
-        LWARN(37, "Zero interrupted method encountered");
-        return exn_object;
+        OpenExeJpdaError UNREF result = jit->get_bc_location_for_native(
+            method, native_location, &bc);
+        TRACE2("jvmti.event.exn",
+            "Exception method = " << (Method_Handle)method << " location " << bc);
+        if (EXE_ERROR_NONE != result)
+            LWARN(38, "JIT {0} {1} returned error {2} for exception method {3} location {4}" 
+                << jit << "get_bc_location_for_native"
+                << result << (Method_Handle)method << native_location);
+        location = bc;
     }
-
-    uint16 bc = 0;
-    OpenExeJpdaError UNREF result = jit->get_bc_location_for_native(
-        method, native_location, &bc);
-    TRACE2("jvmti.event.exn",
-        "Exception method = " << (Method_Handle)method << " location " << bc);
-    if (EXE_ERROR_NONE != result)
-        LWARN(38, "JIT {0} {1} returned error {2} for exception method {3} location {4}" 
-                  << jit << "get_bc_location_for_native"
-                  << result << (Method_Handle)method << native_location);
-    location = bc;
 
     if (catch_method)
     {