RFR 8151546: nsk/jvmti/RedefineClasses/StressRedefine fails in hs nightly
serguei.spitsyn at oracle.com
serguei.spitsyn at oracle.com
Wed Apr 13 02:24:06 UTC 2016
On 4/12/16 18:43, Coleen Phillimore wrote:
>
> Hi Serguei,
>
> On 4/12/16 9:35 PM, serguei.spitsyn at oracle.com wrote:
>> On 4/12/16 12:29, Coleen Phillimore wrote:
>>>
>>> Hi Serguei,
>>>
>>> Thank you for looking at this change.
>>>
>>> On 4/11/16 9:17 PM, serguei.spitsyn at oracle.com wrote:
>>>> Coleen,
>>>>
>>>> src/share/vm/prims/jvmtiRedefineClasses.cpp
>>>> - // Update the version number of the constant pool
>>>> + // Update the version number of the constant pools (may keep
>>>> scratch_cp)
>>>> merge_cp->increment_and_save_version(old_cp->version());
>>>> + scratch_cp->increment_and_save_version(old_cp->version());
>>>>
>>>> Not sure, I understand the change above.
>>>> Could you, please, explain why this change is needed?
>>>> I suspect, the scratch_cp->version() is never used.
>>>
>>> scratch_cp is used if it's equivalent to the old constant pool (see
>>> the code below this with the comments). But it could add entries.
>>> In this case, we want scratch_cp to have a new version number
>>> because scratch_class->_source_file_name_index may be an appended
>>> entry (old_cp->length() + n) which a parallel constant pool merge
>>> might append a different entry and be set to the constant pool after
>>> the safepoint. So source_file_name_index won't point to the first
>>> appended entry. So I need to update the version also in scratch_cp
>>> to detect this.
>>
>> Thank you for the explanation.
>> I'm Ok with this change, just wanted to understand.
>>
>> I think, we have to prevent multiple class redefinitions (prologues)
>> of the same class at the same time.
>> Otherwise, it is hard to isolate and fix all potential issues in this
>> scenario.
>> I doubt, the original goal was to allow this.
>>
>> I've never investigated this corner case.
>> It is not clear what happens with two merged constant pools prepared
>> concurrently.
>> We do not merge them again, right?
>> Most likely, the last redefinition wins with some side effects.
>> If so, then there has to be a way to detect and prevent this kind of
>> concurrency.
>
> Yes, if there are two constant pools prepared concurrently, the last
> one wins and will not contain any entries added by the other constant
> pool.
>
> I tried a change to detect concurrency and give an error. It's quite
> easy to detect with the constant pool versioning fixed. It failed a
> lot of our tests which do the same redefinition concurrently. I then
> tried a change to detect that the concurrent redefinition is
> incompatible. This change worked and I almost sent it out but since I
> couldn't write a test to provoke a failure in this case (because the
> old methods running are using their older constant pools), I decided
> to stick with the simplest fix to not depend on the constant pool
> index to be correct for the InstanceKlass::_source_file_name_index.
>
> So that's what happened.
>
> The ultimate answer is to stop merging constant pools. I have a
> repository with this change that passes all our tests but it's too big
> and risky of a change, ie needs more testing and verification, for
> this late in jdk9. I'd like to prepare it once the next release opens.
I think, even with the constant pool merge removal it is still too
dangerous to have multiple prologues executed concurrently.
We already have the following bug covering this topic:
https://bugs.openjdk.java.net/browse/JDK-6227506
JVMTI Spec: Atomicity of RedefineClasses should be specified
Thanks,
Serguei
>>
>>>
>>> Actually, I made this change because I was going to make a bigger
>>> change that compared constant pool entries if they were the same
>>> version (ie both old_cp->version + 1), indicating parallel constant
>>> pool merging. I decided this change was too much.
>>>
>>>>
>>>>
>>>> + // NOTE: this doesn't work because you can redefine the same
>>>> class in two
>>>> + // threads, each getting their own constant pool data appended to the
>>>> + // original constant pool. In order for the new methods to work
>>>> when they
>>>> + // become old methods, they need to keep their updated copy of
>>>> the constant pool.
>>>> +
>>>> It feels like the statement in this note is too strong, and as
>>>> such, confusing.
>>>> Would it be better to tell something like "not always work"?
>>>> Otherwise, the question is: why do we need this block of code if it
>>>> doesn't work?
>>>>
>>>
>>> The block of code is #if 0'ed out. In my debugging I figured out
>>> why it wouldn't work, so I thought I'd comment it.
>>
>> Oh, I see.
>> In this particular case, I looked at the Udiff that does not show all
>> the context.
>>
>> Please, consider it reviewed.
>
> Thank you. It's great that you know this code so well to review this!
>
> Coleen
>
>>
>> Thanks,
>> Serguei
>>
>>
>>>
>>> Thanks,
>>> Coleen
>>>
>>>>
>>>> Thanks,
>>>> Serguei
>>>>
>>>>
>>>> On 4/11/16 13:06, Coleen Phillimore wrote:
>>>>> Summary: Constant pool merging is not thread safe for
>>>>> source_file_name.
>>>>>
>>>>> This change includes the change for the following bug because they
>>>>> are tested together.
>>>>>
>>>>> 8148772: VM crash in nsk/jvmti/RedefineClasses/StressRedefine:
>>>>> assert failed: Corrupted constant pool
>>>>> Summary: ConstantPool::resolve_constant_at_impl() isn't thread
>>>>> safe for MethodHandleInError and MethodTypeInError.
>>>>>
>>>>> The parallel constant pool merges are mostly harmless because the
>>>>> old methods constant pool pointers aren't updated. The only case
>>>>> I found where it isn't harmless is that we rely on finding the
>>>>> source_file_name_index from the final merged constant pool, which
>>>>> could be any of the parallel merged constant pools. The code to
>>>>> attempt to dig out the name from redefined classes is removed.
>>>>>
>>>>> open webrev at http://cr.openjdk.java.net/~coleenp/8151546.01/webrev
>>>>> bug link https://bugs.openjdk.java.net/browse/JDK-8151546
>>>>>
>>>>> Tested with rbt, java/lang/instrument tests, com/sun/jdi tests. I
>>>>> tried to write a test with all the conditions of the failure but
>>>>> couldn't make it fail (so noreg-hard).
>>>>>
>>>>> Thanks,
>>>>> Coleen
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20160412/9f441bae/attachment.html>
More information about the serviceability-dev
mailing list