Skip to content

Commit

Permalink
Merged with latest openjdk branch
Browse files Browse the repository at this point in the history
  • Loading branch information
bourgesl committed Jun 30, 2016
1 parent f6c2b07 commit 3dd0250
Show file tree
Hide file tree
Showing 31 changed files with 2,434 additions and 1,930 deletions.
4 changes: 3 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<groupId>org.marlin</groupId>
<artifactId>marlin</artifactId>
<packaging>jar</packaging>
<version>0.7.3.3-Unsafe</version>
<version>0.7.4-Unsafe</version>
<name>Marlin software rasterizer</name>

<url>https://github.com/bourgesl/marlin-renderer</url>
Expand Down Expand Up @@ -102,6 +102,8 @@
<!--
Marlin: -Dsun.java2d.renderer=org.marlin.pisces.PiscesRenderingEngine
Pisces: -Dsun.java2d.renderer=sun.java2d.pisces.PiscesRenderingEngine
CrashTest may need large heap: -Xms4g -Xmx4g
-->
<argLine>
-Xms512m -Xmx512m
Expand Down
206 changes: 128 additions & 78 deletions src/main/java/org/marlin/pisces/ArrayCache.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
Expand Down Expand Up @@ -29,71 +29,60 @@

public final class ArrayCache implements MarlinConst {

static final int BUCKETS = 4;
static final int BUCKETS = 8;
static final int MIN_ARRAY_SIZE = 4096;
static final int MAX_ARRAY_SIZE;
static final int MASK_CLR_1 = ~1;
// threshold below to grow arrays by 4
static final int THRESHOLD_SMALL_ARRAY_SIZE = 4 * 1024 * 1024;
// threshold to grow arrays only by (3/2) instead of 2
static final int THRESHOLD_ARRAY_SIZE;
static final int[] ARRAY_SIZES = new int[BUCKETS];
// dirty byte array sizes
static final int MIN_DIRTY_BYTE_ARRAY_SIZE = 32 * 2048; // 32px x 2048px
static final int MAX_DIRTY_BYTE_ARRAY_SIZE;
static final int[] DIRTY_BYTE_ARRAY_SIZES = new int[BUCKETS];
// large array thresholds:
// threshold to grow arrays only by (3/2) instead of 2
static final long THRESHOLD_LARGE_ARRAY_SIZE;
// threshold to grow arrays only by (5/4) instead of 2
static final long THRESHOLD_HUGE_ARRAY_SIZE;
// stats
private static int resizeInt = 0;
private static int resizeDirtyInt = 0;
private static int resizeDirtyFloat = 0;
private static int resizeDirtyByte = 0;
private static int oversize = 0;

static {
// initialize buckets for int/float arrays
int arraySize = MIN_ARRAY_SIZE;

for (int i = 0; i < BUCKETS; i++, arraySize <<= 2) {
int inc_lg = 2; // x4

for (int i = 0; i < BUCKETS; i++, arraySize <<= inc_lg) {
ARRAY_SIZES[i] = arraySize;

if (doTrace) {
if (DO_TRACE) {
logInfo("arraySize[" + i + "]: " + arraySize);
}
}
MAX_ARRAY_SIZE = arraySize >> 2;

/* initialize buckets for dirty byte arrays
(large AA chunk = 32 x 2048 pixels) */
arraySize = MIN_DIRTY_BYTE_ARRAY_SIZE;

for (int i = 0; i < BUCKETS; i++, arraySize <<= 1) {
DIRTY_BYTE_ARRAY_SIZES[i] = arraySize;

if (doTrace) {
logInfo("dirty arraySize[" + i + "]: " + arraySize);
if (arraySize >= THRESHOLD_SMALL_ARRAY_SIZE) {
inc_lg = 1; // x2
}
}
MAX_DIRTY_BYTE_ARRAY_SIZE = arraySize >> 1;
MAX_ARRAY_SIZE = arraySize >> inc_lg;

if (MAX_ARRAY_SIZE <= 0) {
throw new IllegalStateException("Invalid max array size !");
}

// threshold to grow arrays only by (3/2) instead of 2
THRESHOLD_ARRAY_SIZE = Math.max(2 * 1024 * 1024, MAX_ARRAY_SIZE); // 2M
THRESHOLD_ARRAY_SIZE = Math.max(THRESHOLD_SMALL_ARRAY_SIZE,
MAX_ARRAY_SIZE); // >4M

THRESHOLD_LARGE_ARRAY_SIZE = 8L * THRESHOLD_ARRAY_SIZE; // 16M
THRESHOLD_HUGE_ARRAY_SIZE = 8L * THRESHOLD_LARGE_ARRAY_SIZE; // 128M
THRESHOLD_LARGE_ARRAY_SIZE = 16L * 1024 * 1024; // >12M
THRESHOLD_HUGE_ARRAY_SIZE = 48L * 1024 * 1024; // >48M

if (doStats || doMonitors) {
if (THRESHOLD_HUGE_ARRAY_SIZE <= 0) {
throw new IllegalStateException("Invalid huge array size !");
}

if (DO_STATS || DO_MONITORS) {
logInfo("ArrayCache.BUCKETS = " + BUCKETS);
logInfo("ArrayCache.MIN_ARRAY_SIZE = " + MIN_ARRAY_SIZE);
logInfo("ArrayCache.MAX_ARRAY_SIZE = " + MAX_ARRAY_SIZE);
logInfo("ArrayCache.ARRAY_SIZES = "
+ Arrays.toString(ARRAY_SIZES));
logInfo("ArrayCache.MIN_DIRTY_BYTE_ARRAY_SIZE = "
+ MIN_DIRTY_BYTE_ARRAY_SIZE);
logInfo("ArrayCache.MAX_DIRTY_BYTE_ARRAY_SIZE = "
+ MAX_DIRTY_BYTE_ARRAY_SIZE);
logInfo("ArrayCache.ARRAY_SIZES = "
+ Arrays.toString(DIRTY_BYTE_ARRAY_SIZES));
logInfo("ArrayCache.THRESHOLD_ARRAY_SIZE = "
+ THRESHOLD_ARRAY_SIZE);
logInfo("ArrayCache.THRESHOLD_LARGE_ARRAY_SIZE = "
Expand All @@ -107,37 +96,6 @@ private ArrayCache() {
// Utility class
}

static synchronized void incResizeInt() {
resizeInt++;
}

static synchronized void incResizeDirtyInt() {
resizeDirtyInt++;
}

static synchronized void incResizeDirtyFloat() {
resizeDirtyFloat++;
}

static synchronized void incResizeDirtyByte() {
resizeDirtyByte++;
}

static synchronized void incOversize() {
oversize++;
}

static void dumpStats() {
if (resizeInt != 0 || resizeDirtyInt != 0 || resizeDirtyFloat != 0
|| resizeDirtyByte != 0 || oversize != 0) {
logInfo("ArrayCache: int resize: " + resizeInt
+ " - dirty int resize: " + resizeDirtyInt
+ " - dirty float resize: " + resizeDirtyFloat
+ " - dirty byte resize: " + resizeDirtyByte
+ " - oversize: " + oversize);
}
}

// small methods used a lot (to be inlined / optimized by hotspot)

static int getBucket(final int length) {
Expand All @@ -149,15 +107,6 @@ static int getBucket(final int length) {
return -1;
}

static int getBucketDirtyBytes(final int length) {
for (int i = 0; i < DIRTY_BYTE_ARRAY_SIZES.length; i++) {
if (length <= DIRTY_BYTE_ARRAY_SIZES[i]) {
return i;
}
}
return -1;
}

/**
* Return the new array size (~ x2)
* @param curSize current used size
Expand All @@ -173,7 +122,7 @@ public static int getNewSize(final int curSize, final int needSize) {
"array exceeds maximum capacity !");
}
assert curSize >= 0;
final int initial = (curSize & MASK_CLR_1);
final int initial = curSize;
int size;
if (initial > THRESHOLD_ARRAY_SIZE) {
size = initial + (initial >> 1); // x(3/2)
Expand Down Expand Up @@ -213,6 +162,8 @@ public static long getNewLargeSize(final long curSize, final long needSize) {
size = curSize + (curSize >> 2L); // x(5/4)
} else if (curSize > THRESHOLD_LARGE_ARRAY_SIZE) {
size = curSize + (curSize >> 1L); // x(3/2)
} else if (curSize < THRESHOLD_SMALL_ARRAY_SIZE) {
size = (curSize << 2L); // x4
} else {
size = (curSize << 1L); // x2
}
Expand All @@ -228,4 +179,103 @@ public static long getNewLargeSize(final long curSize, final long needSize) {
}
return size;
}

static final class CacheStats {
final String name;
final BucketStats[] bucketStats;
int resize = 0;
int oversize = 0;
long totalInitial = 0L;

CacheStats(final String name) {
this.name = name;

bucketStats = new BucketStats[BUCKETS];
for (int i = 0; i < BUCKETS; i++) {
bucketStats[i] = new BucketStats();
}
}

void reset() {
resize = 0;
oversize = 0;

for (int i = 0; i < BUCKETS; i++) {
final BucketStats s = bucketStats[i];
s.getOp = 0;
s.createOp = 0;
s.returnOp = 0;
s.maxSize = 0;
}
}

long dumpStats() {
long totalCacheBytes = 0L;

if (DO_STATS) {
for (int i = 0; i < BUCKETS; i++) {
final BucketStats s = bucketStats[i];

if (s.maxSize != 0) {
totalCacheBytes += getByteFactor()
* (s.maxSize * ARRAY_SIZES[i]);
}
}

if (totalInitial != 0L || totalCacheBytes != 0L
|| resize != 0 || oversize != 0)
{
logInfo(name + ": resize: " + resize
+ " - oversize: " + oversize
+ " - initial: " + getTotalInitialBytes()
+ " bytes (" + totalInitial + " elements)"
+ " - cache: " + totalCacheBytes + " bytes"
);
}

if (totalCacheBytes != 0L) {
logInfo(name + ": usage stats:");

for (int i = 0; i < BUCKETS; i++) {
final BucketStats s = bucketStats[i];

if (s.getOp != 0) {
logInfo(" Bucket[" + ARRAY_SIZES[i] + "]: "
+ "get: " + s.getOp
+ " - put: " + s.returnOp
+ " - create: " + s.createOp
+ " :: max size: " + s.maxSize
);
}
}
}
}
return totalCacheBytes;
}

private int getByteFactor() {
int factor = 1;
if (name.contains("Int") || name.contains("Float")) {
factor = 4;
}
return factor;
}

long getTotalInitialBytes() {
return getByteFactor() * totalInitial;
}
}

static final class BucketStats {
int getOp = 0;
int createOp = 0;
int returnOp = 0;
int maxSize = 0;

void updateMaxSize(final int size) {
if (size > maxSize) {
maxSize = size;
}
}
}
}
Loading

0 comments on commit 3dd0250

Please sign in to comment.