Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8212178

Soft reference reclamation race in com.sun.xml.internal.stream.util.ThreadLocalBufferAllocator

XMLWordPrintable

    • b16
    • generic
    • generic
    • Not verified

        In ThreadLocalBufferAllocator.getBufferAllocator() there is no guarantee that the SoftReference doesn't get cleared between its construction and its later use of bAllocatorRef.get(). Therefore the method can return null. Calling code (e.g. UTF8Reader.<init>() ) does expects to get non-null though and can crash with NPE.

           public static BufferAllocator getBufferAllocator() {
                SoftReference<BufferAllocator> bAllocatorRef = tlba.get();
                if (bAllocatorRef == null || bAllocatorRef.get() == null) {
                    bAllocatorRef = new SoftReference<>(new BufferAllocator());
                    tlba.set(bAllocatorRef);
                }
         
                return bAllocatorRef.get(); // <--- returns null, because soft-ref was already cleared
           }

        This semi-reliably crashes SPECjvm2008 XML tests with Shenandoah and aggressive mode that does back-to-back cycles.

        Example fix that keeps return value reachable:

           public static BufferAllocator getBufferAllocator() {
                BufferAllocator ba = null;

                SoftReference<BufferAllocator> bAllocatorRef = tlba.get();
                if (bAllocatorRef != null) {
                    ba = bAllocatorRef.get();
                }

                if (ba == null) {
                    ba = new BufferAllocator();
                    bAllocatorRef = new SoftReference<>(ba);
                    tlba.set(bAllocatorRef);
                }

                return ba;
           }

              shade Aleksey Shipilev
              rkennke Roman Kennke
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: