[vmkit-commits] [vmkit] r180547 - Fixed some issue whith multiple JNI calls and thread cooperative code state

Peter Senna Tschudin peter.senna at gmail.com
Thu Apr 25 10:23:46 PDT 2013


Author: peter.senna
Date: Thu Apr 25 12:22:10 2013
New Revision: 180547

URL: http://llvm.org/viewvc/llvm-project?rev=180547&view=rev
Log:
Fixed some issue whith multiple JNI calls and thread cooperative code state
(cherry picked from commit e5192d6d9e4e3291c109ff179c187c0baba2b120)

Modified:
    vmkit/trunk/include/vmkit/Thread.h
    vmkit/trunk/lib/j3/LLVMRuntime/runtime-default.ll
    vmkit/trunk/lib/j3/VMCore/JavaThread.h
    vmkit/trunk/lib/vmkit/CommonThread/ctthread.cpp

Modified: vmkit/trunk/include/vmkit/Thread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/vmkit/Thread.h?rev=180547&r1=180546&r2=180547&view=diff
==============================================================================
--- vmkit/trunk/include/vmkit/Thread.h (original)
+++ vmkit/trunk/include/vmkit/Thread.h Thu Apr 25 12:22:10 2013
@@ -117,6 +117,7 @@ public:
   Thread() {
     lastExceptionBuffer = 0;
     lastKnownFrame = 0;
+    inUncooperativeCode = false;
   }
 
   /// yield - Yield the processor to another thread.
@@ -213,7 +214,7 @@ public:
   void enterUncooperativeCode(uint16_t level = 0) __attribute__ ((noinline));
   void enterUncooperativeCode(word_t SP);
   void leaveUncooperativeCode();
-  bool isInUncooperativeCode()	{	return lastSP;	};
+  bool isInUncooperativeCode()	{	return inUncooperativeCode;	};
   word_t waitOnSP();
 
 
@@ -276,6 +277,10 @@ public:
   ///
   ExceptionBuffer* lastExceptionBuffer;
 
+  /// inUncooperativeCode - Status of the Thread toward Collection.
+  ///
+  bool inUncooperativeCode;
+
   void internalThrowException();
 
   void startKnownFrame(KnownFrame& F) __attribute__ ((noinline));

Modified: vmkit/trunk/lib/j3/LLVMRuntime/runtime-default.ll
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/LLVMRuntime/runtime-default.ll?rev=180547&r1=180546&r2=180547&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/LLVMRuntime/runtime-default.ll (original)
+++ vmkit/trunk/lib/j3/LLVMRuntime/runtime-default.ll Thu Apr 25 12:22:10 2013
@@ -41,7 +41,8 @@
 ;;; field 9:  void*  routine
 ;;; field 10: void*  lastKnownFrame
 ;;; field 11: void*  lastExceptionBuffer
-%Thread = type { %CircularBase, i32, i8*, i8*, i1, i1, i1, i8*, i8*, i8*, i8*, i8* }
+;;; field 12: bool   inUncooperativeCode
+%Thread = type { %CircularBase, i32, i8*, i8*, i1, i1, i1, i8*, i8*, i8*, i8*, i8*, i1 }
 
 %JavaThread = type { %MutatorThread, i8*, %JavaObject* }
 

Modified: vmkit/trunk/lib/j3/VMCore/JavaThread.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/j3/VMCore/JavaThread.h?rev=180547&r1=180546&r2=180547&view=diff
==============================================================================
--- vmkit/trunk/lib/j3/VMCore/JavaThread.h (original)
+++ vmkit/trunk/lib/j3/VMCore/JavaThread.h Thu Apr 25 12:22:10 2013
@@ -33,32 +33,44 @@ class Jnjvm;
 #define BEGIN_NATIVE_EXCEPTION(level)
 #define END_NATIVE_EXCEPTION
 
+
+/*
+ * FIXME Have to find a solution for both implementations
+ */
+#ifdef USE_OPENJDK
+#define BEGIN_JNI_EXCEPTION \
+  JavaThread* th = JavaThread::get(); \
+  word_t SP = th->getLastSP(); \
+  th->leaveUncooperativeCode(); \
+  vmkit::KnownFrame Frame; \
+  th->startKnownFrame(Frame); \
+  Frame.currentFP = vmkit::System::GetCallerAddress();\
+  TRY {
+#else
 #define BEGIN_JNI_EXCEPTION \
   JavaThread* th = JavaThread::get(); \
   word_t SP = th->getLastSP(); \
-  bool _inUncooperative = th->isInUncooperativeCode(); \
-  if (_inUncooperative)	{\
   th->leaveUncooperativeCode(); \
   vmkit::KnownFrame Frame; \
   th->startKnownFrame(Frame); \
-  Frame.currentFP = vmkit::System::GetCallerAddress(); }\
   TRY {
 
+#endif
+
+
 #define END_JNI_EXCEPTION \
   } CATCH { \
     th->throwFromJNI(SP); \
   } END_CATCH;
 
 #define RETURN_FROM_JNI(a) {\
-  if (_inUncooperative)	{\
   th->endKnownFrame(); \
-  th->enterUncooperativeCode(SP); }\
+  th->enterUncooperativeCode(SP); \
   return (a); } \
 
 #define RETURN_VOID_FROM_JNI {\
-  if (_inUncooperative)	{\
   th->endKnownFrame(); \
-  th->enterUncooperativeCode(SP); }\
+  th->enterUncooperativeCode(SP); \
   return; } \
 
 /// This is used to implement park/unpark behavior.

Modified: vmkit/trunk/lib/vmkit/CommonThread/ctthread.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/vmkit/CommonThread/ctthread.cpp?rev=180547&r1=180546&r2=180547&view=diff
==============================================================================
--- vmkit/trunk/lib/vmkit/CommonThread/ctthread.cpp (original)
+++ vmkit/trunk/lib/vmkit/CommonThread/ctthread.cpp Thu Apr 25 12:22:10 2013
@@ -192,7 +192,7 @@ void Thread::scanStack(word_t closure) {
 
 void Thread::enterUncooperativeCode(uint16_t level) {
   if (isVmkitThread()) {
-    if (!inRV) {
+    if (!inRV && !inUncooperativeCode) {
       assert(!lastSP && "SP already set when entering uncooperative code");
       // Get the caller.
       word_t temp = System::GetCallerAddress();
@@ -204,25 +204,27 @@ void Thread::enterUncooperativeCode(uint
       __sync_bool_compare_and_swap(&lastSP, 0, temp);
       if (doYield) joinRVBeforeEnter();
       assert(lastSP && "No last SP when entering uncooperative code");
+      inUncooperativeCode=true;
     }
   }
 }
 
 void Thread::enterUncooperativeCode(word_t SP) {
   if (isVmkitThread()) {
-    if (!inRV) {
+    if (!inRV && !inUncooperativeCode) {
       assert(!lastSP && "SP already set when entering uncooperative code");
       // The cas is not necessary, but it does a memory barrier.
       __sync_bool_compare_and_swap(&lastSP, 0, SP);
       if (doYield) joinRVBeforeEnter();
       assert(lastSP && "No last SP when entering uncooperative code");
+      inUncooperativeCode=true;
     }
   }
 }
 
 void Thread::leaveUncooperativeCode() {
   if (isVmkitThread()) {
-    if (!inRV) {
+    if (!inRV && inUncooperativeCode) {
       assert(lastSP && "No last SP when leaving uncooperative code");
       word_t savedSP = lastSP;
       // The cas is not necessary, but it does a memory barrier.
@@ -230,6 +232,7 @@ void Thread::leaveUncooperativeCode() {
       // A rendezvous has just been initiated, join it.
       if (doYield) joinRVAfterLeave(savedSP);
       assert(!lastSP && "SP has a value after leaving uncooperative code");
+      inUncooperativeCode=false;
     }
   }
 }





More information about the vmkit-commits mailing list