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 2006/12/01 01:07:04 UTC

svn commit: r481113 - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src: class_support/Initialize.cpp exception/exceptions.cpp exception/exceptions_impl.cpp exception/exceptions_jit.cpp

Author: gshimansky
Date: Thu Nov 30 16:07:03 2006
New Revision: 481113

URL: http://svn.apache.org/viewvc?view=rev&rev=481113
Log:
Applied HARMONY-2327 [drlvm][exceptions] enumeration safety state is inconsistent through exceptions call stacks.

Tests passed on ubuntu, windows XP and partly on SuSE9 x86_64 (kernel tests
on Jitrino.OPT failed from the beginning)


Modified:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Initialize.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_impl.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Initialize.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Initialize.cpp?view=diff&rev=481113&r1=481112&r2=481113
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Initialize.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Initialize.cpp Thu Nov 30 16:07:03 2006
@@ -137,8 +137,13 @@
     jthrowable p_error_object;
 
     assert(!hythread_is_suspend_enabled());
+    // it's a safe poin so enviroment should be protected
     vm_execute_java_method_array((jmethodID) meth, 0, 0);
+
+    // suspend can be enabeled in safe enviroment
+    tmn_suspend_enable();
     p_error_object = exn_get();
+    tmn_suspend_disable();
 
     // ---  step 9   ----------------------------------------------------------
     TRACE2("class.init", "initializing class " << m_name->bytes << " STEP 9" ); 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp?view=diff&rev=481113&r1=481112&r2=481113
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions.cpp Thu Nov 30 16:07:03 2006
@@ -49,6 +49,8 @@
 //Find all usage and change to lazy use
 jthrowable exn_get()
 {
+    assert(hythread_is_suspend_enabled());
+
     // we can check heap references for equality to NULL
     // without disabling gc, because GC wouldn't change 
     // null to non-null and vice versa.
@@ -62,10 +64,10 @@
     jobject exc;
 
     if (NULL != p_TLS_vmthread->thread_exception.exc_object) {
-        tmn_suspend_disable_recursive();
+        tmn_suspend_disable();
         exc = oh_allocate_local_handle();
         exc->object = (ManagedObject *) p_TLS_vmthread->thread_exception.exc_object;
-        tmn_suspend_enable_recursive();
+        tmn_suspend_enable();
     } else if (NULL != p_TLS_vmthread->thread_exception.exc_class) {
         exc = exn_create((Exception*)&(p_TLS_vmthread->thread_exception));
     } else {
@@ -144,6 +146,7 @@
 }
 
 jthrowable exn_create(Exception* exception) {
+    assert(hythread_is_suspend_enabled());
     return create_exception(exception);
 }
 
@@ -165,6 +168,7 @@
 jthrowable exn_create(Class* exc_class, const char* exc_message, jthrowable exc_cause)
 {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
     jthrowable exc_object = create_exception(exc_class, exc_message, exc_cause);
 
     if (exc_object == NULL) {
@@ -196,6 +200,7 @@
 jthrowable exn_create(const char *exc_name, const char *exc_message, jthrowable cause)
 {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
     Class *exc_class = get_exc_class(exc_name);
 
     if (exc_class == NULL) {
@@ -206,12 +211,7 @@
 }   // exn_create
 
 void exn_throw_object(jthrowable exc_object) {
-    assert(!hythread_is_suspend_enabled());
     assert(is_unwindable());
-    // XXX salikh: change to unconditional thread_disable_suspend()
-    // we use conditional until all of the VM
-    // is refactored to be definitely gc-safe.
-
     exn_throw_object_internal(exc_object);
 }
 
@@ -233,7 +233,6 @@
 void exn_throw_by_class(Class* exc_class, const char* exc_message,
     jthrowable exc_cause)
 {
-    assert(!hythread_is_suspend_enabled());
     assert(is_unwindable());
 
     exn_throw_by_class_internal(exc_class, exc_message, exc_cause);
@@ -257,7 +256,6 @@
 void exn_throw_by_name(const char* exc_name, const char* exc_message,
     jthrowable exc_cause)
 {
-    assert(!hythread_is_suspend_enabled());
     assert(is_unwindable());
 
     exn_throw_by_name_internal(exc_name, exc_message, exc_cause);
@@ -311,11 +309,13 @@
 void exn_raise_by_name(const char* exc_name, const char* exc_message,
     jthrowable exc_cause)
 {
+    assert(hythread_is_suspend_enabled());
     assert(!is_unwindable());
     assert(exc_name);
     exn_raise_by_name_internal(exc_name, exc_message, exc_cause);
 }
 
+// FIXME moove to exception_impl.cpp
 static void check_pop_frame(ManagedObject *exn) {
     if (exn == VM_Global_State::loader_env->popFrameException->object) {
         exn_clear();
@@ -327,8 +327,16 @@
     }
 }
 
+// function can be cold from suspen enabled and disabled mode 
 void exn_rethrow()
 {
+    // exception is throwing, so suspend can be disabeled without following enabling
+    if (hythread_is_suspend_enabled()) {
+        tmn_suspend_disable();
+    }
+
+    assert(!hythread_is_suspend_enabled());
+
 #ifndef VM_LAZY_EXCEPTION
     ManagedObject *exn = get_exception_object_internal();
     assert(exn);
@@ -355,6 +363,7 @@
             exc_cause->object = p_TLS_vmthread->thread_exception.exc_cause;
         }
         clear_exception_internal();
+
         exn_throw_by_class_internal(exc_class, exc_message, exc_cause);
     } else {
         DIE(("There is no exception."));
@@ -377,6 +386,7 @@
 // prints stackTrace via java
 inline void exn_java_print_stack_trace(FILE * UNREF f, jthrowable exc)
 {
+    assert(hythread_is_suspend_enabled());
     // finds java environment
     JNIEnv *jenv = p_TLS_vmthread->jni_env;
 
@@ -539,6 +549,7 @@
 inline void exn_native_print_stack_trace(FILE * f, ManagedObject * exn)
 {
 //Afremov Pavel 20050119 Should be changed when classpath will raplaced by DRL
+    assert(hythread_is_suspend_enabled());
     assert(gid_throwable_traceinfo);
 
     // ? 20030428: This code should be elsewhere!

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_impl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_impl.cpp?view=diff&rev=481113&r1=481112&r2=481113
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_impl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_impl.cpp Thu Nov 30 16:07:03 2006
@@ -72,6 +72,7 @@
 // cause can be null
 static Method* prepare_exc_creating(Class* exc_class, jvalue* args) {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
 
     // Finds corresponding constructor
     Method* exc_init = lookup_exc_constructor(exc_class, "()V");
@@ -88,6 +89,7 @@
 static Method* prepare_exc_creating(Class* exc_class, jvalue* args,
     jthrowable exc_cause) {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
 
     // Checks that it's corresponding method
     if (NULL == exc_cause) {
@@ -112,6 +114,7 @@
 static Method* prepare_exc_creating(Class* exc_class, jvalue* args,
     const char* exc_message) {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
 
     // Checks that it's corresponding method
     if (NULL == exc_message) {
@@ -127,7 +130,7 @@
     }
 
     // Creates string object
-    tmn_suspend_disable_recursive();
+    tmn_suspend_disable();
 
     ManagedObject *arg_obj =
         string_create_from_utf8(exc_message, (unsigned) strlen(exc_message));
@@ -139,7 +142,7 @@
     jobject arg = oh_allocate_local_handle();
     arg->object = arg_obj;
 
-    tmn_suspend_enable_recursive();
+    tmn_suspend_enable();
 
     // Fills arguments for constructor
     args[1].l = arg;
@@ -151,6 +154,7 @@
 static Method* prepare_exc_creating(Class* exc_class, jvalue* args,
     const char* exc_message, jthrowable exc_cause) {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
 
     // Checks that it's corresponding method
     if (NULL == exc_message) {
@@ -196,12 +200,9 @@
 void init_cause(jthrowable exc_object, jthrowable exc_cause) {
     ASSERT_RAISE_AREA;
     assert(exc_cause);
+    assert(hythread_is_suspend_enabled());
 
-    bool suspended_enabled = hythread_is_suspend_enabled();
-
-    if (suspended_enabled) {
-        tmn_suspend_disable();
-    }
+    tmn_suspend_disable();
 
     Class* exc_class = exc_object->object->vt()->clss;
     Method *init_cause_method = class_lookup_method_recursive(exc_class,
@@ -213,10 +214,7 @@
     jvalue ret_val;
     vm_execute_java_method_array((jmethodID) init_cause_method, &ret_val,
         args);
-
-    if (suspended_enabled) {
-        tmn_suspend_enable();
-    }
+    tmn_suspend_enable();
 
     if (exn_raised()) {
         DIE(("Exception constructor has thrown an exception"));
@@ -225,6 +223,7 @@
 
 jthrowable create_exception(Class* exc_class, Method* exc_init, jvalue* args) {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
 
     bool suspended_enabled = hythread_is_suspend_enabled();
 
@@ -255,6 +254,8 @@
 jthrowable create_exception(Class* exc_class,
     const char* exc_message, jthrowable exc_cause)
 {
+    ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
     jvalue args[3];
     Method *exc_init =
         prepare_exc_creating(exc_class, args, exc_message, exc_cause);
@@ -274,6 +275,8 @@
 jthrowable create_exception(Exception* exception)
 {
     ASSERT_RAISE_AREA;
+    assert(hythread_is_suspend_enabled());
+
     if ( NULL != exception->exc_class) {
         jthrowable exc_cause = NULL;
         Class* exc_class = exception->exc_class;
@@ -286,7 +289,10 @@
             tmn_suspend_enable_recursive();
         }
         exn_clear();
-        return exn_create(exc_class, exc_message, exc_cause);
+        
+        jthrowable exc_exception = NULL;
+        exc_exception = exn_create(exc_class, exc_message, exc_cause);
+        return exc_exception;
     } else {
         return NULL;
     }
@@ -294,6 +300,11 @@
 
 void exn_throw_object_internal(jthrowable exc_object)
 {
+    // functions can be invoked in suspend disabled and enabled state
+    if (hythread_is_suspend_enabled()) {
+        tmn_suspend_disable();
+    }
+    assert(!hythread_is_suspend_enabled());
     TRACE2("exn", ("%s", "exn_throw_object(), delegating to exn_throw_for_JIT()"));
     exn_throw_for_JIT(exc_object->object, NULL, NULL, NULL, NULL);
 }
@@ -301,6 +312,12 @@
 void exn_throw_by_class_internal(Class* exc_class, const char* exc_message,
     jthrowable exc_cause)
 {
+    // functions can be invoked in suspend disabled and enabled state
+    if (!hythread_is_suspend_enabled()) {
+        // exception is throwing, so suspend can be enabled safely
+        tmn_suspend_enable();
+    }
+    assert(hythread_is_suspend_enabled());
 #ifdef VM_LAZY_EXCEPTION
     set_unwindable(false);
 
@@ -318,7 +335,11 @@
     } else {
         TRACE2("exn", ("%s", "exn_throw_by_class(), lazy delegating to exn_throw_for_JIT()"));
         set_unwindable(true);
+
+        // no return, so enable isn't required
+        tmn_suspend_disable();
         exn_throw_for_JIT(NULL, exc_class, exc_init, NULL, args);
+        //tmn_suspend_enable();
     }
 #else
     set_unwindable(false);
@@ -328,9 +349,15 @@
     exn_throw_object_internal(exc_object);
 #endif
 }
+
 void exn_throw_by_name_internal(const char* exc_name, const char* exc_message,
     jthrowable exc_cause)
 {
+    // functions can be invoked in suspend disabled and enabled state
+    if (!hythread_is_suspend_enabled()) {
+        // exception is throwing, so suspend can be enabled safely
+        tmn_suspend_enable();
+    }
     assert(hythread_is_suspend_enabled());
     set_unwindable(false);
     Class *exc_class = get_exc_class(exc_name);
@@ -393,27 +420,37 @@
     exn_raise_by_class_internal(exc_class, exc_message, exc_cause);
 }
 
+// function should be called in disable mode
 void __stdcall clear_exception_internal()
 {
+    assert(!hythread_is_suspend_enabled());
     p_TLS_vmthread->thread_exception.exc_object = NULL;
     p_TLS_vmthread->thread_exception.exc_class = NULL;
     p_TLS_vmthread->thread_exception.exc_cause = NULL;
     p_TLS_vmthread->thread_exception.exc_message = NULL;
-}
+} // clear_exception_internal
 
+// function should be called in disable mode
 void __stdcall set_exception_object_internal(ManagedObject * exc)
 {
     assert(!hythread_is_suspend_enabled());
     p_TLS_vmthread->thread_exception.exc_object = exc;
 } // set_exc_object_internal
 
+// function is safe point & should be called in disable mode in safe enviroment
 ManagedObject* __stdcall get_exception_object_internal()
 {
+    assert(!hythread_is_suspend_enabled());
     if (NULL != p_TLS_vmthread->thread_exception.exc_object) {
         return p_TLS_vmthread->thread_exception.exc_object;
     } else if (NULL != p_TLS_vmthread->thread_exception.exc_class) {
         Exception* exception = (Exception*)&(p_TLS_vmthread->thread_exception);
+
+        // suspend can be enabeled in safe enviroment
+        tmn_suspend_enable();
         jthrowable exc_object = create_exception(exception);
+        tmn_suspend_disable();
+
         return exc_object->object;
     } else {
         return NULL;

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=481113&r1=481112&r2=481113
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/exception/exceptions_jit.cpp Thu Nov 30 16:07:03 2006
@@ -135,7 +135,8 @@
 //////////////////////////////////////////////////////////////////////////
 // Lazy Exception Utilities
 
-// Note: Function runs from unwindable area
+// Note: Function runs from unwindable area before exception throwing
+// function can be safe point & should be called with disable reqursion = 1
 static ManagedObject *create_lazy_exception(
     Class_Handle exn_class,
     Method_Handle exn_constr,
@@ -150,9 +151,12 @@
         result = class_alloc_new_object_and_run_constructor(
             (Class*) exn_class, (Method*) exn_constr, exn_constr_args);
     } else {
+        // exception is throwing, so suspend can be enabled safely
+        tmn_suspend_enable();
         jthrowable exc_object = create_exception(
             (Class*) exn_class, (Method*) exn_constr, vm_exn_constr_args);
         result = exc_object->object;
+        tmn_suspend_disable();
     }
     set_unwindable(unwindable);
     exn_rethrow_if_pending();
@@ -174,6 +178,7 @@
 // The client should either use si_transfer_control to resume it, or use an OS context mechanism
 // copied from the final stack iterator.
 
+// function can be safe point & should be called with disable reqursion = 1
 static void exn_propagate_exception(
     StackIterator * si,
     ManagedObject ** exn_obj,
@@ -383,6 +388,7 @@
 }
 #endif // _IPF_
 
+// function can be safe point & should be called with disable reqursion = 1
 void exn_throw_for_JIT(ManagedObject* exn_obj, Class_Handle exn_class,
     Method_Handle exn_constr, uint8* jit_exn_constr_args, jvalue* vm_exn_constr_args)
 {
@@ -433,9 +439,11 @@
 // Exception defined as in previous function.
 // Does not return.
 
+// function can be safe point & should be called with disable reqursion = 1
 void exn_athrow(ManagedObject* exn_obj, Class_Handle exn_class,
     Method_Handle exn_constr, uint8* exn_constr_args)
 {
+    assert(!hythread_is_suspend_enabled());
     exn_throw_for_JIT(exn_obj, exn_class, exn_constr, exn_constr_args, NULL);
 }
 
@@ -445,8 +453,10 @@
 // Exception defined as in previous two functions.
 // Mutates the regs value, which should be used to "resume" the managed code.
 
+// function can be safe point & should be called with disable reqursion = 1
 void exn_athrow_regs(Registers * regs, Class_Handle exn_class, bool java_code)
 {
+    assert(!hythread_is_suspend_enabled());
     assert(exn_class);
 #ifndef _IPF_
     M2nFrame *m2nf;