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;