7023589: Xrender : NullPointerException in sun.font.XRGlyphCache.freeGlyphs running Java 2D demo
authorceisserer
Thu, 03 Mar 2011 16:06:42 -0800
changeset 8508 a7e8d7418c54
parent 8507 78ea3ec4877b
child 8509 176660773a90
7023589: Xrender : NullPointerException in sun.font.XRGlyphCache.freeGlyphs running Java 2D demo Reviewed-by: prr
jdk/src/share/classes/sun/font/StrikeCache.java
jdk/src/solaris/classes/sun/font/XRGlyphCache.java
--- a/jdk/src/share/classes/sun/font/StrikeCache.java	Tue Mar 01 14:49:53 2011 -0800
+++ b/jdk/src/share/classes/sun/font/StrikeCache.java	Thu Mar 03 16:06:42 2011 -0800
@@ -319,8 +319,7 @@
                 ArrayList<Long> gids = null;
 
                 for (int i = 0; i < glyphPtrs.length; i++) {
-                    if (glyphPtrs[i] != 0 && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0
-                            && unsafe.getInt(glyphPtrs[i] + cacheCellOffset) != 0) {
+                    if (glyphPtrs[i] != 0 && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0) {
 
                         if (gids == null) {
                             gids = new ArrayList<Long>();
@@ -330,6 +329,8 @@
                 }
 
                 if (gids != null) {
+                    // Any reference by the disposers to the native glyph ptrs
+                    // must be done before this returns.
                     notifyDisposeListeners(gids);
                 }
             }
@@ -345,8 +346,7 @@
 
                 for (int i=0; i < glyphPtrs.length; i++) {
                     if (glyphPtrs[i] != 0
-                            && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0
-                            && unsafe.getInt(glyphPtrs[i] + cacheCellOffset) != 0) {
+                            && unsafe.getByte(glyphPtrs[i] + managedOffset) == 0) {
 
                         if (gids == null) {
                             gids = new ArrayList<Long>();
@@ -356,6 +356,8 @@
                 }
 
                 if (gids != null) {
+                    // Any reference by the disposers to the native glyph ptrs
+                    // must be done before this returns.
                     notifyDisposeListeners(gids);
                 }
         }
--- a/jdk/src/solaris/classes/sun/font/XRGlyphCache.java	Tue Mar 01 14:49:53 2011 -0800
+++ b/jdk/src/solaris/classes/sun/font/XRGlyphCache.java	Thu Mar 03 16:06:42 2011 -0800
@@ -70,9 +70,14 @@
         try {
             SunToolkit.awtLock();
 
-            ArrayList<Integer> glyphIDList = new ArrayList<Integer>(glyphPtrList.size());
+            GrowableIntArray glyphIDList = new GrowableIntArray(1, glyphPtrList.size());
             for (long glyphPtr : glyphPtrList) {
-                glyphIDList.add(XRGlyphCacheEntry.getGlyphID(glyphPtr));
+                int glyphID = XRGlyphCacheEntry.getGlyphID(glyphPtr);
+
+                //Check if glyph hasn't been freed already
+                if (glyphID != 0) {
+                   glyphIDList.addInt(glyphID);
+                }
             }
             freeGlyphs(glyphIDList);
         } finally {
@@ -83,7 +88,6 @@
     protected int getFreeGlyphID() {
         if (freeGlyphIDs.size() > 0) {
             int newID = freeGlyphIDs.remove(freeGlyphIDs.size() - 1);
-            ;
             return newID;
         }
         return nextID++;
@@ -246,7 +250,7 @@
             glyph.setPinned();
         }
 
-        ArrayList<Integer> deleteGlyphList = new ArrayList<Integer>();
+        GrowableIntArray deleteGlyphList = new GrowableIntArray(1, 10);
         int pixelsToRelease = cachedPixels - MAX_CACHED_PIXELS;
 
         for (int i = cacheList.size() - 1; i >= 0 && pixelsToRelease > 0; i--) {
@@ -254,7 +258,7 @@
 
             if (!entry.isPinned()) {
                 pixelsToRelease -= entry.getPixelCnt();
-                deleteGlyphList.add(new Integer(entry.getGlyphID()));
+                deleteGlyphList.addInt(entry.getGlyphID());
             }
         }
 
@@ -265,26 +269,23 @@
         freeGlyphs(deleteGlyphList);
     }
 
-    private void freeGlyphs(List<Integer> glyphIdList) {
-
-        freeGlyphIDs.addAll(glyphIdList);
+    private void freeGlyphs(GrowableIntArray glyphIdList) {
+        GrowableIntArray removedLCDGlyphs = new GrowableIntArray(1, 10);
+        GrowableIntArray removedGrayscaleGlyphs = new GrowableIntArray(1, 10);
 
-        GrowableIntArray removedLCDGlyphs = new GrowableIntArray(1, 1);
-        GrowableIntArray removedGrayscaleGlyphs = new GrowableIntArray(1, 1);
+        for (int i=0; i < glyphIdList.getSize(); i++) {
+            int glyphId = glyphIdList.getInt(i);
+            freeGlyphIDs.add(glyphId);
 
-        for (Integer glyphId : glyphIdList) {
-            tmp.setValue(glyphId.intValue());
+            tmp.setValue(glyphId);
             XRGlyphCacheEntry entry = cacheMap.get(tmp);
             cachedPixels -= entry.getPixelCnt();
-
-            int removedGlyphID = entry.getGlyphID();
-            tmp.setValue(removedGlyphID);
             cacheMap.remove(tmp);
 
             if (entry.getGlyphSet() == grayGlyphSet) {
-                removedGrayscaleGlyphs.addInt(removedGlyphID);
+                removedGrayscaleGlyphs.addInt(glyphId);
             } else {
-                removedLCDGlyphs.addInt(removedGlyphID);
+                removedLCDGlyphs.addInt(glyphId);
             }
 
             entry.setGlyphID(0);