Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/java2d/marlin/OffHeapArray.java
38918 views
/*1* Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.marlin;2627import java.lang.ref.PhantomReference;28import java.lang.ref.ReferenceQueue;29import java.security.AccessController;30import java.security.PrivilegedAction;31import java.util.Vector;32import static sun.java2d.marlin.MarlinConst.logUnsafeMalloc;33import sun.misc.ThreadGroupUtils;34import sun.misc.Unsafe;3536/**37*38* @author bourgesl39*/40final class OffHeapArray {4142// unsafe reference43static final Unsafe unsafe;44// size of int / float45static final int SIZE_INT;4647// RendererContext reference queue48private static final ReferenceQueue<Object> rdrQueue49= new ReferenceQueue<Object>();50// reference list51private static final Vector<OffHeapReference> refList52= new Vector<OffHeapReference>(32);5354static {55unsafe = Unsafe.getUnsafe();56SIZE_INT = Unsafe.ARRAY_INT_INDEX_SCALE;5758// Mimics Java2D Disposer:59AccessController.doPrivileged(60(PrivilegedAction<Void>) () -> {61/*62* The thread must be a member of a thread group63* which will not get GCed before VM exit.64* Make its parent the top-level thread group.65*/66final ThreadGroup rootTG67= ThreadGroupUtils.getRootThreadGroup();68final Thread t = new Thread(rootTG, new OffHeapDisposer(),69"MarlinRenderer Disposer");70t.setContextClassLoader(null);71t.setDaemon(true);72t.setPriority(Thread.MAX_PRIORITY);73t.start();74return null;75}76);77}7879/* members */80long address;81long length;82int used;8384OffHeapArray(final Object parent, final long len) {85// note: may throw OOME:86this.address = unsafe.allocateMemory(len);87this.length = len;88this.used = 0;89if (logUnsafeMalloc) {90MarlinUtils.logInfo(System.currentTimeMillis()91+ ": OffHeapArray.allocateMemory = "92+ len + " to addr = " + this.address);93}9495// Create the phantom reference to ensure freeing off-heap memory:96refList.add(new OffHeapReference(parent, this));97}9899/*100* As realloc may change the address, updating address is MANDATORY101* @param len new array length102* @throws OutOfMemoryError if the allocation is refused by the system103*/104void resize(final long len) {105// note: may throw OOME:106this.address = unsafe.reallocateMemory(address, len);107this.length = len;108if (logUnsafeMalloc) {109MarlinUtils.logInfo(System.currentTimeMillis()110+ ": OffHeapArray.reallocateMemory = "111+ len + " to addr = " + this.address);112}113}114115void free() {116unsafe.freeMemory(this.address);117if (logUnsafeMalloc) {118MarlinUtils.logInfo(System.currentTimeMillis()119+ ": OffHeapEdgeArray.free = "120+ this.length121+ " at addr = " + this.address);122}123}124125void fill(final byte val) {126unsafe.setMemory(this.address, this.length, val);127}128129static final class OffHeapReference extends PhantomReference<Object> {130131private final OffHeapArray array;132133OffHeapReference(final Object parent, final OffHeapArray edges) {134super(parent, rdrQueue);135this.array = edges;136}137138void dispose() {139// free off-heap blocks140this.array.free();141}142}143144static final class OffHeapDisposer implements Runnable {145@Override146public void run() {147final Thread currentThread = Thread.currentThread();148OffHeapReference ref;149150// check interrupted:151for (; !currentThread.isInterrupted();) {152try {153ref = (OffHeapReference)rdrQueue.remove();154ref.dispose();155156refList.remove(ref);157158} catch (InterruptedException ie) {159MarlinUtils.logException("OffHeapDisposer interrupted:",160ie);161}162}163}164}165}166167168