Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/java2d/marlin/ArrayCache.java
38918 views
/*1* Copyright (c) 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.util.Arrays;28import static sun.java2d.marlin.MarlinUtils.logInfo;2930public final class ArrayCache implements MarlinConst {3132static final int BUCKETS = 4;33static final int MIN_ARRAY_SIZE = 4096;34static final int MAX_ARRAY_SIZE;35static final int MASK_CLR_1 = ~1;36// threshold to grow arrays only by (3/2) instead of 237static final int THRESHOLD_ARRAY_SIZE;38static final int[] ARRAY_SIZES = new int[BUCKETS];39// dirty byte array sizes40static final int MIN_DIRTY_BYTE_ARRAY_SIZE = 32 * 2048; // 32px x 2048px41static final int MAX_DIRTY_BYTE_ARRAY_SIZE;42static final int[] DIRTY_BYTE_ARRAY_SIZES = new int[BUCKETS];43// large array thresholds:44static final long THRESHOLD_LARGE_ARRAY_SIZE;45static final long THRESHOLD_HUGE_ARRAY_SIZE;46// stats47private static int resizeInt = 0;48private static int resizeDirtyInt = 0;49private static int resizeDirtyFloat = 0;50private static int resizeDirtyByte = 0;51private static int oversize = 0;5253static {54// initialize buckets for int/float arrays55int arraySize = MIN_ARRAY_SIZE;5657for (int i = 0; i < BUCKETS; i++, arraySize <<= 2) {58ARRAY_SIZES[i] = arraySize;5960if (doTrace) {61logInfo("arraySize[" + i + "]: " + arraySize);62}63}64MAX_ARRAY_SIZE = arraySize >> 2;6566/* initialize buckets for dirty byte arrays67(large AA chunk = 32 x 2048 pixels) */68arraySize = MIN_DIRTY_BYTE_ARRAY_SIZE;6970for (int i = 0; i < BUCKETS; i++, arraySize <<= 1) {71DIRTY_BYTE_ARRAY_SIZES[i] = arraySize;7273if (doTrace) {74logInfo("dirty arraySize[" + i + "]: " + arraySize);75}76}77MAX_DIRTY_BYTE_ARRAY_SIZE = arraySize >> 1;7879// threshold to grow arrays only by (3/2) instead of 280THRESHOLD_ARRAY_SIZE = Math.max(2 * 1024 * 1024, MAX_ARRAY_SIZE); // 2M8182THRESHOLD_LARGE_ARRAY_SIZE = 8L * THRESHOLD_ARRAY_SIZE; // 16M83THRESHOLD_HUGE_ARRAY_SIZE = 8L * THRESHOLD_LARGE_ARRAY_SIZE; // 128M8485if (doStats || doMonitors) {86logInfo("ArrayCache.BUCKETS = " + BUCKETS);87logInfo("ArrayCache.MIN_ARRAY_SIZE = " + MIN_ARRAY_SIZE);88logInfo("ArrayCache.MAX_ARRAY_SIZE = " + MAX_ARRAY_SIZE);89logInfo("ArrayCache.ARRAY_SIZES = "90+ Arrays.toString(ARRAY_SIZES));91logInfo("ArrayCache.MIN_DIRTY_BYTE_ARRAY_SIZE = "92+ MIN_DIRTY_BYTE_ARRAY_SIZE);93logInfo("ArrayCache.MAX_DIRTY_BYTE_ARRAY_SIZE = "94+ MAX_DIRTY_BYTE_ARRAY_SIZE);95logInfo("ArrayCache.ARRAY_SIZES = "96+ Arrays.toString(DIRTY_BYTE_ARRAY_SIZES));97logInfo("ArrayCache.THRESHOLD_ARRAY_SIZE = "98+ THRESHOLD_ARRAY_SIZE);99logInfo("ArrayCache.THRESHOLD_LARGE_ARRAY_SIZE = "100+ THRESHOLD_LARGE_ARRAY_SIZE);101logInfo("ArrayCache.THRESHOLD_HUGE_ARRAY_SIZE = "102+ THRESHOLD_HUGE_ARRAY_SIZE);103}104}105106private ArrayCache() {107// Utility class108}109110static synchronized void incResizeInt() {111resizeInt++;112}113114static synchronized void incResizeDirtyInt() {115resizeDirtyInt++;116}117118static synchronized void incResizeDirtyFloat() {119resizeDirtyFloat++;120}121122static synchronized void incResizeDirtyByte() {123resizeDirtyByte++;124}125126static synchronized void incOversize() {127oversize++;128}129130static void dumpStats() {131if (resizeInt != 0 || resizeDirtyInt != 0 || resizeDirtyFloat != 0132|| resizeDirtyByte != 0 || oversize != 0) {133logInfo("ArrayCache: int resize: " + resizeInt134+ " - dirty int resize: " + resizeDirtyInt135+ " - dirty float resize: " + resizeDirtyFloat136+ " - dirty byte resize: " + resizeDirtyByte137+ " - oversize: " + oversize);138}139}140141// small methods used a lot (to be inlined / optimized by hotspot)142143static int getBucket(final int length) {144for (int i = 0; i < ARRAY_SIZES.length; i++) {145if (length <= ARRAY_SIZES[i]) {146return i;147}148}149return -1;150}151152static int getBucketDirtyBytes(final int length) {153for (int i = 0; i < DIRTY_BYTE_ARRAY_SIZES.length; i++) {154if (length <= DIRTY_BYTE_ARRAY_SIZES[i]) {155return i;156}157}158return -1;159}160161/**162* Return the new array size (~ x2)163* @param curSize current used size164* @param needSize needed size165* @return new array size166*/167public static int getNewSize(final int curSize, final int needSize) {168// check if needSize is negative or integer overflow:169if (needSize < 0) {170// hard overflow failure - we can't even accommodate171// new items without overflowing172throw new ArrayIndexOutOfBoundsException(173"array exceeds maximum capacity !");174}175assert curSize >= 0;176final int initial = (curSize & MASK_CLR_1);177int size;178if (initial > THRESHOLD_ARRAY_SIZE) {179size = initial + (initial >> 1); // x(3/2)180} else {181size = (initial << 1); // x2182}183// ensure the new size is >= needed size:184if (size < needSize) {185// align to 4096 (may overflow):186size = ((needSize >> 12) + 1) << 12;187}188// check integer overflow:189if (size < 0) {190// resize to maximum capacity:191size = Integer.MAX_VALUE;192}193return size;194}195196/**197* Return the new array size (~ x2)198* @param curSize current used size199* @param needSize needed size200* @return new array size201*/202public static long getNewLargeSize(final long curSize, final long needSize) {203// check if needSize is negative or integer overflow:204if ((needSize >> 31L) != 0L) {205// hard overflow failure - we can't even accommodate206// new items without overflowing207throw new ArrayIndexOutOfBoundsException(208"array exceeds maximum capacity !");209}210assert curSize >= 0L;211long size;212if (curSize > THRESHOLD_HUGE_ARRAY_SIZE) {213size = curSize + (curSize >> 2L); // x(5/4)214} else if (curSize > THRESHOLD_LARGE_ARRAY_SIZE) {215size = curSize + (curSize >> 1L); // x(3/2)216} else {217size = (curSize << 1L); // x2218}219// ensure the new size is >= needed size:220if (size < needSize) {221// align to 4096:222size = ((needSize >> 12L) + 1L) << 12L;223}224// check integer overflow:225if (size > Integer.MAX_VALUE) {226// resize to maximum capacity:227size = Integer.MAX_VALUE;228}229return size;230}231}232233234