8147443: Use the Common Cleaner in Marlin OffHeapArray
authorlbourges
Wed, 20 Jan 2016 22:53:26 +0100
changeset 35688 744b6cf60397
parent 35687 78e8e8fea09b
child 35689 fc4e2debc320
8147443: Use the Common Cleaner in Marlin OffHeapArray Summary: OffHeapArray clean-up to use the jdk.internal.ref.Cleaner to free unsafe arrays (PhantomReference) Reviewed-by: prr, rriggs, mchung
jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java
jdk/src/java.desktop/share/classes/sun/java2d/marlin/OffHeapArray.java
jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java
jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java
jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java	Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/MarlinCache.java	Wed Jan 20 22:53:26 2016 +0100
@@ -110,7 +110,7 @@
     MarlinCache(final RendererContext rdrCtx) {
         this.rdrCtx = rdrCtx;
 
-        rowAAChunk = new OffHeapArray(rdrCtx, INITIAL_CHUNK_ARRAY);
+        rowAAChunk = new OffHeapArray(rdrCtx.cleanerObj, INITIAL_CHUNK_ARRAY); // 64K
 
         touchedTile = touchedTile_initial;
 
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/OffHeapArray.java	Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/OffHeapArray.java	Wed Jan 20 22:53:26 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,9 @@
 
 package sun.java2d.marlin;
 
-import java.lang.ref.PhantomReference;
-import java.lang.ref.ReferenceQueue;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.Vector;
 import static sun.java2d.marlin.MarlinConst.logUnsafeMalloc;
-import sun.awt.util.ThreadGroupUtils;
 import jdk.internal.misc.Unsafe;
+import jdk.internal.ref.CleanerFactory;
 
 /**
  *
@@ -45,36 +40,9 @@
     // size of int / float
     static final int SIZE_INT;
 
-    // RendererContext reference queue
-    private static final ReferenceQueue<Object> rdrQueue
-        = new ReferenceQueue<Object>();
-    // reference list
-    private static final Vector<OffHeapReference> refList
-        = new Vector<OffHeapReference>(32);
-
     static {
         unsafe   = Unsafe.getUnsafe();
         SIZE_INT = Unsafe.ARRAY_INT_INDEX_SCALE;
-
-        // Mimics Java2D Disposer:
-        AccessController.doPrivileged(
-            (PrivilegedAction<Void>) () -> {
-                /*
-                 * The thread must be a member of a thread group
-                 * which will not get GCed before VM exit.
-                 * Make its parent the top-level thread group.
-                 */
-                final ThreadGroup rootTG
-                    = ThreadGroupUtils.getRootThreadGroup();
-                final Thread t = new Thread(rootTG, new OffHeapDisposer(),
-                    "MarlinRenderer Disposer");
-                t.setContextClassLoader(null);
-                t.setDaemon(true);
-                t.setPriority(Thread.MAX_PRIORITY);
-                t.start();
-                return null;
-            }
-        );
     }
 
     /* members */
@@ -89,12 +57,12 @@
         this.used    = 0;
         if (logUnsafeMalloc) {
             MarlinUtils.logInfo(System.currentTimeMillis()
-                                + ": OffHeapArray.allocateMemory = "
+                                + ": OffHeapArray.allocateMemory =   "
                                 + len + " to addr = " + this.address);
         }
 
-        // Create the phantom reference to ensure freeing off-heap memory:
-        refList.add(new OffHeapReference(parent, this));
+        // Register a cleaning function to ensure freeing off-heap memory:
+        CleanerFactory.cleaner().register(parent, () -> this.free());
     }
 
     /*
@@ -117,7 +85,7 @@
         unsafe.freeMemory(this.address);
         if (logUnsafeMalloc) {
             MarlinUtils.logInfo(System.currentTimeMillis()
-                                + ": OffHeapEdgeArray.free = "
+                                + ": OffHeapArray.freeMemory =       "
                                 + this.length
                                 + " at addr = " + this.address);
         }
@@ -126,41 +94,4 @@
     void fill(final byte val) {
         unsafe.setMemory(this.address, this.length, val);
     }
-
-    static final class OffHeapReference extends PhantomReference<Object> {
-
-        private final OffHeapArray array;
-
-        OffHeapReference(final Object parent, final OffHeapArray edges) {
-            super(parent, rdrQueue);
-            this.array = edges;
-        }
-
-        void dispose() {
-            // free off-heap blocks
-            this.array.free();
-        }
-    }
-
-    static final class OffHeapDisposer implements Runnable {
-        @Override
-        public void run() {
-            final Thread currentThread = Thread.currentThread();
-            OffHeapReference ref;
-
-            // check interrupted:
-            for (; !currentThread.isInterrupted();) {
-                try {
-                    ref = (OffHeapReference)rdrQueue.remove();
-                    ref.dispose();
-
-                    refList.remove(ref);
-
-                } catch (InterruptedException ie) {
-                    MarlinUtils.logException("OffHeapDisposer interrupted:",
-                                             ie);
-                }
-            }
-        }
-    }
 }
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java	Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Renderer.java	Wed Jan 20 22:53:26 2016 +0100
@@ -514,7 +514,7 @@
     Renderer(final RendererContext rdrCtx) {
         this.rdrCtx = rdrCtx;
 
-        this.edges = new OffHeapArray(rdrCtx, INITIAL_EDGES_CAPACITY); // 96K
+        this.edges = new OffHeapArray(rdrCtx.cleanerObj, INITIAL_EDGES_CAPACITY); // 96K
 
         this.curve = rdrCtx.curve;
 
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java	Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/RendererContext.java	Wed Jan 20 22:53:26 2016 +0100
@@ -68,6 +68,8 @@
      * @see MarlinRenderingEngine#REF_TYPE
      */
     final Object reference;
+    // Smallest object used as Cleaner's parent reference
+    final Object cleanerObj = new Object();
     // dirty flag indicating an exception occured during pipeline in pathTo()
     boolean dirty = false;
     // dynamic array caches kept using weak reference (low memory footprint)
@@ -187,10 +189,10 @@
                 if (USE_CACHE_HARD_REF) {
                     // update hard reference:
                     hardRefArrayCaches = holder;
+                } else {
+                    // update weak reference:
+                    refArrayCaches = new WeakReference<ArrayCachesHolder>(holder);
                 }
-
-                // update weak reference:
-                refArrayCaches = new WeakReference<ArrayCachesHolder>(holder);
             }
         }
         return holder;
--- a/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java	Thu Jan 14 23:14:01 2016 +0300
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/marlin/Version.java	Wed Jan 20 22:53:26 2016 +0100
@@ -27,7 +27,7 @@
 
 public final class Version {
 
-    private static final String version = "marlin-0.7.2-Unsafe-OpenJDK";
+    private static final String version = "marlin-0.7.3-Unsafe-OpenJDK";
 
     public static String getVersion() {
         return version;