RFR: 8067247: Crash: assert(method_holder->data() == 0 ...) failed: a) MT-unsafe modification of inline cache

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Mon Mar 28 15:47:42 UTC 2016


>> in addition it clears this.
>> void static_stub_Relocation::clear_inline_cache() {
>>   // Call stub is only used when calling the interpreted code.
>>   // It does not really need to be cleared, except that we want to
>> clean out the methodoop.
>>   CompiledStaticCall::set_stub_to_clean(this);
>
> i want assert to catch this issue. if static stubs are cleared, assert
> wouldn't fail.
I see. Then I suggest to rename the method to 
WhiteBox.cleanupInlineCaches() and iterate over the whole code cache 
(don't specify Method*).

void CodeCache::cleanup_inline_caches() {
   assert_locked_or_safepoint(CodeCache_lock);
   NMethodIterator iter;
   while(iter.next_alive()) {
     iter.method()->cleanup_inline_caches(true);
   }
}

Best regards,
Vladimir Ivanov


> -Jamsheed
>> }
>>
>> Best Regards,
>> Jamsheed
>>>
>>> WB_ENTRY(void, WB_ClearInlineCaches(JNIEnv* env, jobject wb))
>>>   VM_ClearICs clear_ics;
>>>   VMThread::execute(&clear_ics);
>>> WB_END
>>>
>>> class VM_ClearICs: public VM_Operation {
>>> ...
>>>   void doit()         { CodeCache::clear_inline_caches(); }
>>> ...
>>> };
>>>
>>> void CodeCache::clear_inline_caches() {
>>>   assert_locked_or_safepoint(CodeCache_lock);
>>>   NMethodIterator iter;
>>>   while(iter.next_alive()) {
>>>     iter.method()->clear_inline_caches();
>>>   }
>>> }
>>>
>>> void nmethod::clear_inline_caches() {
>>>   assert(SafepointSynchronize::is_at_safepoint(), "cleaning of IC's
>>> only allowed at safepoint");
>>>   if (is_zombie()) {
>>>     return;
>>>   }
>>>
>>>   RelocIterator iter(this);
>>>   while (iter.next()) {
>>>     iter.reloc()->clear_inline_cache();
>>>   }
>>> }
>>>
>>> void static_call_Relocation::clear_inline_cache() {
>>>   // Safe call site info
>>>   CompiledStaticCall* handler = compiledStaticCall_at(this);
>>>   handler->set_to_clean();
>>> }
>>>
>>> void opt_virtual_call_Relocation::clear_inline_cache() {
>>>   // No stubs for ICs
>>>   // Clean IC
>>>   ResourceMark rm;
>>>   CompiledIC* icache = CompiledIC_at(this);
>>>   icache->set_to_clean();
>>> }
>>>
>>> void virtual_call_Relocation::clear_inline_cache() {
>>>   // No stubs for ICs
>>>   // Clean IC
>>>   ResourceMark rm;
>>>   CompiledIC* icache = CompiledIC_at(this);
>>>   icache->set_to_clean();
>>> }
>>>
>>> Best regards,
>>> Vladimir Ivanov
>>>
>>>>
>>>> Best Regards,
>>>> Jamsheed
>>>>
>>>> On 3/26/2016 1:50 PM, Dean Long wrote:
>>>>> Instead of changing cleanup_inline_caches() to take a new flag, can
>>>>> you use the existing
>>>>> clear_inline_caches()?
>>>>>
>>>>> dl
>>>>>
>>>>> On 3/25/2016 9:54 AM, Jamsheed C m wrote:
>>>>>> Thank you Chris.
>>>>>> I have updated the code.
>>>>>>
>>>>>> + if (method == NULL) {
>>>>>> + return;
>>>>>> + }
>>>>>> + nmethod* nm = method->code();
>>>>>> + if (nm == NULL || nm->is_unloaded()) {
>>>>>> + return;
>>>>>> + }
>>>>>> + nm->cleanup_inline_caches(true);
>>>>>> Best Regards,
>>>>>> Jamsheed
>>>>>>
>>>>>> On 3/25/2016 6:58 AM, Christian Thalinger wrote:
>>>>>>>
>>>>>>>> On Mar 24, 2016, at 11:05 AM, Jamsheed C m
>>>>>>>> <jamsheed.c.m at oracle.com> wrote:
>>>>>>>>
>>>>>>>> Hi All,
>>>>>>>>
>>>>>>>> Request for review,
>>>>>>>>
>>>>>>>> bug url: https://bugs.openjdk.java.net/browse/JDK-8067247
>>>>>>>>
>>>>>>>> webrevs:
>>>>>>>> fix:
>>>>>>>>   jdk part: http://cr.openjdk.java.net/~jcm/8067247/webrev.jdk.00/
>>>>>>>> <http://cr.openjdk.java.net/%7Ejcm/8067247/webrev.jdk.00/>
>>>>>>>>
>>>>>>>> newly added test case
>>>>>>>> hotspot part:
>>>>>>>> http://cr.openjdk.java.net/~jcm/8067247/webrev.hs.00/
>>>>>>>> <http://cr.openjdk.java.net/%7Ejcm/8067247/webrev.hs.00/>
>>>>>>>> under hs-comp/test
>>>>>>>> http://cr.openjdk.java.net/~jcm/8067247/webrev.hs_comp.00/
>>>>>>>> <http://cr.openjdk.java.net/%7Ejcm/8067247/webrev.hs_comp.00/>
>>>>>>>>
>>>>>>>> Unit Test: test/compiler/jsr292/misc/gc/MHInvokeTest.java
>>>>>>>> Testing: JPRT with new test case, with fix, without fix
>>>>>>>>
>>>>>>>> Problem Summary:  MH.invoke linksite take assistance of java code
>>>>>>>> to get an adapter method. Here a new method holder class and a
>>>>>>>> adapter method are created for a MT and lform instance is cached.
>>>>>>>> Normally this cached lform get returned for a linksite request of
>>>>>>>> same MT.  When these cached lform get collected(due to memory
>>>>>>>> pressure),  a new class and method gets created for same MT(even
>>>>>>>> though old method holder class and  adapter method are live).
>>>>>>>> Fix Summary: Kept a strong reference to lform instance in adapter
>>>>>>>> method holder class of  MT.
>>>>>>>
>>>>>>> Wow!  You found the cause for his long-standing issue? Nice.
>>>>>>> + if (method == NULL) { return; }
>>>>>>> + nmethod* nm = method->code();
>>>>>>> + if (nm == NULL) { return; }
>>>>>>> + if (nm->is_unloaded()) { return; }
>>>>>>> Please put the return and } on separate lines.
>>>>>>>
>>>>>>>>
>>>>>>>> Best Regards,
>>>>>>>> Jamsheed
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>
>


More information about the hotspot-compiler-dev mailing list