re PR libgcj/8995 (race cases in interpreter)
2008-09-17 Andrew Haley <aph@redhat.com> PR libgcj/8995: * defineclass.cc (_Jv_ClassReader::handleCodeAttribute): Initialize thread_count. * include/java-interp.h (_Jv_InterpMethod::thread_count): New field. (_Jv_InterpMethod::rewrite_insn_mutex): New mutex. (_Jv_InterpFrame:: _Jv_InterpFrame): Pass frame_type. * interpret.cc (ThreadCountAdjuster): New class. (_Jv_InterpMethod::thread_count): New field. (_Jv_InitInterpreter): Initialize rewrite_insn_mutex. Increment and decrement thread_count field in methods. * interpret-run.cc (REWRITE_INSN): Check thread_count <= 1. (REWRITE_INSN): Likewise. Declare a ThreadCountAdjuster. * java/lang/reflect/natVMProxy.cc (run_proxy): Initialize frame type as frame_proxy. From-SVN: r140593
This commit is contained in:
committed by
Andrew Haley
parent
5c0466b537
commit
f0580031a7
@@ -175,6 +175,17 @@ class _Jv_InterpMethod : public _Jv_MethodBase
|
||||
static pc_t breakpoint_insn;
|
||||
#ifdef DIRECT_THREADED
|
||||
static insn_slot bp_insn_slot;
|
||||
|
||||
public:
|
||||
// Mutex to prevent a data race between threads when rewriting
|
||||
// instructions. See interpret-run.cc for an explanation of its use.
|
||||
static _Jv_Mutex_t rewrite_insn_mutex;
|
||||
|
||||
// The count of threads executing this method.
|
||||
long thread_count;
|
||||
|
||||
private:
|
||||
|
||||
#else
|
||||
static unsigned char bp_insn_opcode;
|
||||
#endif
|
||||
@@ -455,9 +466,10 @@ public:
|
||||
jobject obj_ptr;
|
||||
|
||||
_Jv_InterpFrame (void *meth, java::lang::Thread *thr, jclass proxyCls = NULL,
|
||||
pc_t *pc = NULL)
|
||||
pc_t *pc = NULL,
|
||||
_Jv_FrameType frame_type = frame_interpreter)
|
||||
: _Jv_Frame (reinterpret_cast<_Jv_MethodBase *> (meth), thr,
|
||||
frame_interpreter)
|
||||
frame_type)
|
||||
{
|
||||
next_interp = (_Jv_InterpFrame *) thr->interp_frame;
|
||||
proxyClass = proxyCls;
|
||||
@@ -501,6 +513,76 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef DIRECT_THREADED
|
||||
// This class increments and decrements the thread_count field in an
|
||||
// interpreted method. On entry to the interpreter a
|
||||
// ThreadCountAdjuster is created when increments the thread_count in
|
||||
// the current method and uses the next_interp field in the frame to
|
||||
// find the previous method and decrement its thread_count.
|
||||
class ThreadCountAdjuster
|
||||
{
|
||||
|
||||
// A class used to handle the rewrite_insn_mutex while we're
|
||||
// adjusting the thread_count in a method. Unlocking the mutex in a
|
||||
// destructor ensures that it's unlocked even if (for example) a
|
||||
// segfault occurs in the critical section.
|
||||
class MutexLock
|
||||
{
|
||||
private:
|
||||
_Jv_Mutex_t *mutex;
|
||||
public:
|
||||
MutexLock (_Jv_Mutex_t *m)
|
||||
{
|
||||
mutex = m;
|
||||
_Jv_MutexLock (mutex);
|
||||
}
|
||||
~MutexLock ()
|
||||
{
|
||||
_Jv_MutexUnlock (mutex);
|
||||
}
|
||||
};
|
||||
|
||||
_Jv_InterpMethod *method;
|
||||
_Jv_InterpMethod *next_method;
|
||||
|
||||
public:
|
||||
|
||||
ThreadCountAdjuster (_Jv_InterpMethod *m, _Jv_InterpFrame *fr)
|
||||
{
|
||||
MutexLock lock (&::_Jv_InterpMethod::rewrite_insn_mutex);
|
||||
|
||||
method = m;
|
||||
next_method = NULL;
|
||||
|
||||
_Jv_InterpFrame *next_interp = fr->next_interp;
|
||||
|
||||
// Record the fact that we're executing this method and that
|
||||
// we're no longer executing the method that called us.
|
||||
method->thread_count++;
|
||||
|
||||
if (next_interp && next_interp->frame_type == frame_interpreter)
|
||||
{
|
||||
next_method
|
||||
= reinterpret_cast<_Jv_InterpMethod *> (next_interp->meth);
|
||||
next_method->thread_count--;
|
||||
}
|
||||
}
|
||||
|
||||
~ThreadCountAdjuster ()
|
||||
{
|
||||
MutexLock lock (&::_Jv_InterpMethod::rewrite_insn_mutex);
|
||||
|
||||
// We're going to return to the method that called us, so bump its
|
||||
// thread_count and decrement our own.
|
||||
|
||||
method->thread_count--;
|
||||
|
||||
if (next_method)
|
||||
next_method->thread_count++;
|
||||
}
|
||||
};
|
||||
#endif // DIRECT_THREADED
|
||||
|
||||
#endif /* INTERPRETER */
|
||||
|
||||
#endif /* __JAVA_INTERP_H__ */
|
||||
|
||||
Reference in New Issue
Block a user