--- a/hotspot/src/share/vm/runtime/thread.cpp Wed Feb 01 07:59:01 2012 -0800
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Feb 01 16:57:08 2012 -0800
@@ -33,6 +33,7 @@
#include "interpreter/linkResolver.hpp"
#include "interpreter/oopMapCache.hpp"
#include "jvmtifiles/jvmtiEnv.hpp"
+#include "memory/gcLocker.inline.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
#include "oops/instanceKlass.hpp"
@@ -2278,6 +2279,26 @@
}
}
+// This is a variant of the normal
+// check_special_condition_for_native_trans with slightly different
+// semantics for use by critical native wrappers. It does all the
+// normal checks but also performs the transition back into
+// thread_in_Java state. This is required so that critical natives
+// can potentially block and perform a GC if they are the last thread
+// exiting the GC_locker.
+void JavaThread::check_special_condition_for_native_trans_and_transition(JavaThread *thread) {
+ check_special_condition_for_native_trans(thread);
+
+ // Finish the transition
+ thread->set_thread_state(_thread_in_Java);
+
+ if (thread->do_critical_native_unlock()) {
+ ThreadInVMfromJavaNoAsyncException tiv(thread);
+ GC_locker::unlock_critical(thread);
+ thread->clear_critical_native_unlock();
+ }
+}
+
// We need to guarantee the Threads_lock here, since resumes are not
// allowed during safepoint synchronization
// Can only resume from an external suspension