[9] RFR(S): 8029443: 'assert(klass->is_loader_alive(_is_alive)) failed: must be alive' during VM_CollectForMetadataAllocation

Vladimir Kozlov vladimir.kozlov at oracle.com
Tue Jul 15 17:59:50 UTC 2014

On 7/15/14 12:48 AM, Tobias Hartmann wrote:
> Hi Vladimir,
>> Impressive work, Tobias!
> Thanks! Took me a while to figure out what's happening.
>> So before the permgen removal embedded method* were oops and they were
>> processed in relocInfo::oop_type loop.
> Okay, good to know. That explains why the terms oops and metadata are
> used interchangeably at some points in the code.
>> May be instead of specializing opt_virtual_call_type and
>> static_call_type call site you can simple add a loop for
>> relocInfo::metadata_type (similar to oop_type loop)?
> The problem with iterating over relocInfo::metadata_type is that we
> don't know to which stub, i.e., to which IC the Method* pointer belongs.
> Since we don't want to unload the entire method but only clear the
> corresponding IC, we need this information.

Got it: you are cleaning call site IC: ic->set_to_clean().

My point was these to_interp stubs are part of a nmethod (they are in 
stubs section) and contain dead metadata. Should we unload this nmethod 
then? We do unloading nmethods if any embedded oops are dead (see 
can_unload()). Should we do the same if a nmethod (and its stubs) have 
dead metadata? Note, embedded metadata could be Method* and MethodData*.


> Thanks,
> Tobias
>> Thanks,
>> Vladimir
>> On 7/14/14 4:56 AM, Tobias Hartmann wrote:
>>> Hi,
>>> please review the following patch for JDK-8029443.
>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8029443
>>> Webrev: http://cr.openjdk.java.net/~thartmann/8029443/webrev.00/
>>> *Problem*
>>> After the tracing/marking phase of GC, nmethod::do_unloading(..) checks
>>> if a nmethod can be unloaded because it contains dead oops. If class
>>> unloading occurred we additionally clear all ICs where the cached
>>> metadata refers to an unloaded klass or method. If the nmethod is not
>>> unloaded, nmethod::verify_metadata_loaders(..) finally checks if all
>>> metadata is alive. The assert in CheckClass::check_class fails because
>>> the nmethod contains Method* metadata corresponding to a dead Klass.
>>> The Method* belongs to a to-interpreter stub [1] of an optimized
>>> compiled IC. Normally we clear those stubs prior to verification to
>>> avoid dangling references to Method* [2], but only if the stub is not in
>>> use, i.e. if the IC is not in to-interpreted mode. In this case the
>>> to-interpreter stub may be executed and hand a stale Method* to the
>>> interpreter.
>>> *Solution
>>> *The implementation of nmethod::do_unloading(..) is changed to clean
>>> compiled ICs and compiled static calls if they call into a
>>> to-interpreter stub that references dead Method* metadata.
>>> The patch was affected by the G1 class unloading changes (JDK-8048248)
>>> because the method nmethod::do_unloading_parallel(..) was added. I
>>> adapted the implementation as well.
>>> *
>>> Testing
>>> *Failing test (runThese)
>>> JPRT
>>> Thanks,
>>> Tobias
>>> [1] see CompiledStaticCall::emit_to_interp_stub(..)
>>> [2] see nmethod::verify_metadata_loaders(..),
>>> static_stub_reloc()->clear_inline_cache() clears the stub

More information about the hotspot-dev mailing list