This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: FYI: Fix PR 7587 - interpreter thread safety
- From: Bryce McKinlay <mckinlay at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Tue, 13 Jul 2004 17:02:23 -0400
- Subject: Patch: FYI: Fix PR 7587 - interpreter thread safety
Currently the interpreter can crash if a method is "compiled"
simultaniously by two different threads. This was occuring quite
frequently running GCTest on my machine. This patch fixes it by
introducing a global lock around _Jv_InterpMethod::compile(). Ideally
we'd have a more fine-grained lock, however I don't think its safe to
use the class lock because user code might hold it and there would be a
potential for deadlock.
I'm checking this in.
Regards
Bryce
2004-07-13 Bryce McKinlay <mckinlay@redhat.com>
PR libgcj/7587
* interpret.cc (compile_mutex): New.
(_Jv_InitInterpreter): New. Initialize compile_mutex.
(run): Lock compile_mutex before calling compile() if compilation is
required.
* prims.cc (_Jv_CreateJavaVM): Call _Jv_InitInterpreter().
* include/java-interp.h (_Jv_InitInterpreter): Declare.
Index: prims.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/prims.cc,v
retrieving revision 1.91
diff -u -r1.91 prims.cc
--- prims.cc 11 Jul 2004 21:19:46 -0000 1.91
+++ prims.cc 13 Jul 2004 21:01:47 -0000
@@ -25,6 +25,7 @@
#include <jvm.h>
#include <java-signal.h>
#include <java-threads.h>
+#include <java-interp.h>
#ifdef ENABLE_JVMPI
#include <jvmpi.h>
@@ -953,6 +954,10 @@
_Jv_InitThreads ();
_Jv_InitGC ();
_Jv_InitializeSyncMutex ();
+
+#ifdef INTERPRETER
+ _Jv_InitInterpreter ();
+#endif
#ifdef HANDLE_SEGV
INIT_SEGV;
Index: interpret.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/interpret.cc,v
retrieving revision 1.43
diff -u -r1.43 interpret.cc
--- interpret.cc 13 Jul 2004 01:04:46 -0000 1.43
+++ interpret.cc 13 Jul 2004 21:01:48 -0000
@@ -54,6 +54,21 @@
__attribute__ ((__noreturn__));
#endif
+#ifdef DIRECT_THREADED
+// Lock to ensure that methods are not compiled concurrently.
+// We could use a finer-grained lock here, however it is not safe to use
+// the Class monitor as user code in another thread could hold it.
+static _Jv_Mutex_t compile_mutex;
+
+void
+_Jv_InitInterpreter()
+{
+ _Jv_MutexInit (&compile_mutex);
+}
+#else
+void _Jv_InitInterpreter() {}
+#endif
+
extern "C" double __ieee754_fmod (double,double);
// This represents a single slot in the "compiled" form of the
@@ -1032,9 +1047,14 @@
#define PCVAL(unionval) unionval.p
#define AMPAMP(label) &&label
- // Compile if we must.
+ // Compile if we must. NOTE: Double-check locking.
if (prepared == NULL)
- compile (insn_target);
+ {
+ _Jv_MutexLock (&compile_mutex);
+ if (prepared == NULL)
+ compile (insn_target);
+ _Jv_MutexUnlock (&compile_mutex);
+ }
pc = (insn_slot *) prepared;
#else
Index: include/java-interp.h
===================================================================
RCS file: /cvs/gcc/gcc/libjava/include/java-interp.h,v
retrieving revision 1.24
diff -u -r1.24 java-interp.h
--- include/java-interp.h 20 Apr 2004 01:38:45 -0000 1.24
+++ include/java-interp.h 13 Jul 2004 21:01:48 -0000
@@ -35,6 +35,7 @@
struct _Jv_ResolvedMethod;
+void _Jv_InitInterpreter ();
void _Jv_DefineClass (jclass, jbyteArray, jint, jint);
void _Jv_InitField (jobject, jclass, int);