[9] RFR(L) 8013267 : move MemberNameTable from native code to Java heap, use to intern MemberNames
David Chase
david.r.chase at oracle.com
Fri Oct 31 22:59:05 UTC 2014
Thanks very much, I shall attend to these irregularities.
David
On 2014-10-31, at 6:01 PM, Peter Levart <peter.levart at gmail.com> wrote:
>
> On 10/31/2014 07:11 PM, David Chase wrote:
>> I found a lurking bug and updated the webrevs — I was mistaken
>> about this version having passed the ute tests (but now, for real, it does).
>>
>> I also added converted Christian’s test code into a jtreg test (which passes):
>>
>>
>> http://cr.openjdk.java.net/~drchase/8013267/hotspot.05/
>> http://cr.openjdk.java.net/~drchase/8013267/jdk.05/
>
> Hi David,
>
> I'll just comment on the JDK side of things.
>
> In Class.ClassData.intern(), ther is a part that synchronizes on the elementData (volatile field holding array of Comparable(s)):
>
> 2500 synchronized (elementData) {
> 2501 final int index = Arrays.binarySearch(elementData, 0, size, memberName);
> 2502 if (index >= 0) {
> 2503 return (E) elementData[index];
> 2504 }
> 2505 // Not found, add carefully.
> 2506 return add(klass, ~index, memberName, redefined_count);
> 2507 }
>
> Inside this synchronized block, add() method is called, which can call grow() method:
>
> 2522 if (oldCapacity + 1 > element_data.length ) {
> 2523 // Replacing array with a copy is safe; elements are identical.
> 2524 grow(oldCapacity + 1);
> 2525 element_data = elementData;
> 2526 }
>
> grow() method creates a copy of elementData array and replaces it on this volatile field (line 2584):
>
> 2577 private void grow(int minCapacity) {
> 2578 // overflow-conscious code
> 2579 int oldCapacity = elementData.length;
> 2580 int newCapacity = oldCapacity + (oldCapacity >> 1);
> 2581 if (newCapacity - minCapacity < 0)
> 2582 newCapacity = minCapacity;
> 2583 // minCapacity is usually close to size, so this is a win:
> 2584 elementData = Arrays.copyOf(elementData, newCapacity);
> 2585 }
>
> A concurrent call to intern() can therefore synchronize on a different monitor, so two threads will be inserting the element into the same array at the same time, Auch!
>
>
>
> Also, lazy construction of ClassData instance:
>
> 2593 private ClassData<T> classData() {
> 2594 if (this.classData != null) {
> 2595 return this.classData;
> 2596 }
> 2597 synchronized (this) {
> 2598 if (this.classData == null) {
> 2599 this.classData = new ClassData<>();
> 2600 }
> 2601 }
> 2602 return this.classData;
> 2603 }
>
> Synchronizes on the j.l.Class instance, which can interfere with user synchronization (think synchronized static methods). This dangerous.
>
> Theres an inner class Class.Atomic which is a home for Unsafe machinery in j.l.Class. You can add a casClassData method to it and use it to atomically install the ClassData instance without synchronized blocks.
>
>
>
> Regards, Peter
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/attachments/20141031/f588b80e/signature.asc>
More information about the hotspot-compiler-dev
mailing list