diff options
author | Andrew Haley <aph@redhat.com> | 2008-09-23 13:51:58 +0000 |
---|---|---|
committer | Andrew Haley <aph@gcc.gnu.org> | 2008-09-23 13:51:58 +0000 |
commit | f0580031a7919f8e1401db1c2e6515e1682eaaa7 (patch) | |
tree | 5aa7ac0da62ededbaab14350de950b012a5759a3 /libjava/include/java-interp.h | |
parent | 5c0466b537af28f3cf7aff8d29c884a3c5725459 (diff) | |
download | gcc-f0580031a7919f8e1401db1c2e6515e1682eaaa7.zip gcc-f0580031a7919f8e1401db1c2e6515e1682eaaa7.tar.gz gcc-f0580031a7919f8e1401db1c2e6515e1682eaaa7.tar.bz2 |
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
Diffstat (limited to 'libjava/include/java-interp.h')
-rw-r--r-- | libjava/include/java-interp.h | 86 |
1 files changed, 84 insertions, 2 deletions
diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h index c6d9955..c088e9f 100644 --- a/libjava/include/java-interp.h +++ b/libjava/include/java-interp.h @@ -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__ */ |