RFR (S): 8198909: [Graal] compiler/codecache/stress/UnexpectedDeoptimizationTest.java crashed with SIGSEGV

Tom Rodriguez tom.rodriguez at oracle.com
Tue Jun 19 21:34:46 UTC 2018


I've generated a webrev with a new KlassRefHandle protecting 
questionable uses in JVMCI. 
http://cr.openjdk.java.net/~never/8198909.1/webrev

One outstanding question is whether ObjArrayKlass also needs a working 
holder_phantom method.  It would seem so to me but maybe there's some 
reason not?

tom

Tom Rodriguez wrote on 6/11/18 10:04 AM:
> 
> 
> Erik Ă–sterlund wrote on 6/11/18 2:09 AM:
>> Hi Tom,
>>
>> Could you please call InstanceKlass::holder_phantom() instead to keep 
>> the class alive? That is the more general mechanism that is also used 
>> by ciInstanceKlass. We don't want to use explicit G1 enqueue calls 
>> anymore.
> 
> Ok.  I guess the same fix in JDK8 will have the use the explicit enqueue 
> though or is it not required in JDK8?
> 
>> Also, you must not perform any thread transition between loading the 
>> weak klass from the MDO until you call holder_phantom, otherwise it 
>> might have been unloaded before you get to call holder_phantom(). Is 
>> this guaranteed somehow in this scenario? I looked through all 
>> callsites and could not find where the Klass pointer is read in the 
>> MDO and subsequently passed into the CompilerToVM::get_jvmci_type API, 
>> and therefore I do not know if this is guaranteed.
> 
> The obviously problematic path is at 
> http://hg.openjdk.java.net/jdk/jdk/file/50469fb301c4/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp#l334 
> when either base_address is a Klass* or base_object is NULL which is 
> where we are reading from non-heap memory.  There are other paths which 
> are reading Klasses through more standard APIs from the ConstantPool for 
> instance.
> 
> There isn't an easy way to ensure no safepoint occurs in between so 
> maybe we require the caller of get_jvmci_type to pass in the 
> phantom_holder() as a way of forcing the caller to call holder_phantom() 
> at the appropriate places?  Or is it the case that getResolvedType is 
> the only place where special effort is required?  All the other paths 
> are fairly normal HotSpot code but though place that uses 
> klass->implementor() for instance seems like it could be considered to 
> be weak by G1.
> 
> http://hg.openjdk.java.net/jdk/jdk/file/50469fb301c4/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp#l368 
> 
> 
> The lack of a properly working KlassHandle seems like an oversight in 
> the API to me.
> 
> tom
> 
>>
>> Thanks,
>> /Erik
>>
>> On 2018-06-08 22:46, Tom Rodriguez wrote:
>>> The JVMCI API may read Klass* and java.lang.Class instances from 
>>> locations which G1 would consider to be weakly referenced.  This can 
>>> result in HotSpotResolvedObjectTypeImpl instances with references to 
>>> Classes that have been unloaded.  In the this crash, JVMCI was 
>>> reading a Klass* from the profile in an MDO and building a wrapper 
>>> around it. The MDO reference is weak and was the only remaining 
>>> reference to the type so it could be dropped resulting in an eventual 
>>> crash.
>>>
>>> I've added an explicit G1 enqueue before we call out to create the 
>>> wrapper object but is there a more recommended way of doing this? 
>>> Dean had pointed out the oddly named InstanceKlass::holder_phantom 
>>> which is used by the CI.  Should I be using that?  The G1 barrier is 
>>> only really need when reading from non-Java heap memory but since the 
>>> get_jvmci_type method is the main entry point for this logic it 
>>> safest to always perform it in this path.
>>>
>>> https://bugs.openjdk.java.net/browse/JDK-8198909
>>> http://cr.openjdk.java.net/~never/8198909/webrev
>>



More information about the hotspot-gc-dev mailing list