[13] RFR(L) 8220623: [JVMCI] Update JVMCI to support JVMCI based Compiler compiled into shared library

Doug Simon doug.simon at oracle.com
Mon Apr 1 06:59:42 UTC 2019

> On 1 Apr 2019, at 04:17, David Holmes <david.holmes at oracle.com> wrote:
> On 30/03/2019 1:16 am, Doug Simon wrote:
>> Hi Robbin,
>>> From: Robbin Ehn <robbin.ehn at oracle.com>
>>> Hi,
>>>  434     for (; JavaThread *thr = jtiwh.next(); ) {
>>>  435       if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
>>>  436         num_active++;
>>>  437         if (thr->is_Compiler_thread()) {
>>>  438           CompilerThread* ct = (CompilerThread*) thr;
>>>  439           if (ct->compiler() == NULL || !ct->compiler()->is_jvmci()) {
>>>  440             num_active_compiler_thread++;
>>>  441           } else {
>>>  442             // When using a Java based JVMCI compiler, it's possible
>>>  443             // for one compiler thread to grab a Java lock, enter
>>>  444             // HotSpot and go to sleep on the shutdown safepoint.
>>>  445             // Another JVMCI compiler thread can then attempt grab
>>>  446             // the lock and thus never make progress.
>>>  447           }
>>>  448         }
>>>  449       }
>>>  450     }
>>> We inc num_active on threads in native.
>>> If such thread is a compiler thread we also inc num_active_compiler_thread.
>>> JavaThread blocking on safepoint would be state blocked.
>>> JavaThread waiting on the 'Java lock' would also be blocked.
>>> Why are you not blocked when waiting on that contended Java lock ?
>> This change was made primarily in the context of libgraal.
>> It can happen that a JVMCI compiler thread acquires a lock in libgraal, enters HotSpot
>> and goes to sleep in the shutdown safepoint. Another JVMCI compiler thread then
>> attempts to acquire the same lock and goes to sleep in libgraal which from HotSpot’s
>> perspective is the _thread_in_native state.
>> This is the original fix I had for this:
>>           CompilerThread* ct = (CompilerThread*) thr;
>>           if (ct->compiler() == NULL || !ct->compiler()->is_jvmci() JVMCI_ONLY(|| !UseJVMCINativeLibrary)) {
>>             num_active_compiler_thread++;
>>           } else {
>>             // When using a compiler in a JVMCI shared library, it's possible
>>             // for one compiler thread to grab a lock in the shared library,
>>             // enter HotSpot and go to sleep on the shutdown safepoint. Another
>>             // JVMCI shared library compiler thread can then attempt to grab the
>>             // lock and thus never make progress.
>>           }
>> which is probably the right one. I hadn’t realized that a JavaGraal
>> (as opposed to libgraal) JVMCI compiler thread blocked on a lock will be in
>> the blocked state, not in the _thread_in_native state.
> It depends on whether the thread is supposed to participate in safepoints and whether the lock is acquired with or without a safepoint check.

The libgraal thread acquires the lock without a (HotSpot) safepoint check (note that SVM may have its own safepoint check but that safepoint implementation is disjoint from HotSpot’s).

> I'm confused by the use of "shared library" in this context. If the VM is exiting and the thread holding the lock is blocked at the termination safepoint, then why would you expect another compiler thread blocked on that lock to make progress?

I don’t expect it to make progress. However, there’s no way for HotSpot to know whether the other thread is blocked on a SVM lock or still progressing in SVM code. From HotSpot’s perspective, the thread is simply in the _thread_in_native state.

> This all sounds very odd to me.

Hopefully I could clarify things. The important thing to note is that code executing in SVM compiled code is just like any other native code.


More information about the graal-dev mailing list