Moved unsafe to FastObjectPool (which is where it should have been)

This commit is contained in:
nathan 2015-02-01 23:39:48 +01:00
parent a45c25652a
commit e3bad2a55a
2 changed files with 38 additions and 35 deletions

View File

@ -30,8 +30,6 @@ import java.net.NetworkInterface;
import java.net.SocketException; import java.net.SocketException;
import java.net.URL; import java.net.URL;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Enumeration; import java.util.Enumeration;
@ -47,8 +45,6 @@ public class Sys {
public static final int javaVersion = getJavaVersion(); public static final int javaVersion = getJavaVersion();
public static final boolean isAndroid = getIsAndroid(); public static final boolean isAndroid = getIsAndroid();
public static final sun.misc.Unsafe unsafe = getUNSAFE();
public static final int KILOBYTE = 1024; public static final int KILOBYTE = 1024;
public static final int MEGABYTE = 1024 * KILOBYTE; public static final int MEGABYTE = 1024 * KILOBYTE;
public static final int GIGABYTE = 1024 * MEGABYTE; public static final int GIGABYTE = 1024 * MEGABYTE;
@ -95,29 +91,7 @@ public class Sys {
} }
} }
private static sun.misc.Unsafe getUNSAFE() {
try {
final PrivilegedExceptionAction<sun.misc.Unsafe> action = new PrivilegedExceptionAction<sun.misc.Unsafe>() {
@Override
public sun.misc.Unsafe run() throws Exception {
Class<sun.misc.Unsafe> unsafeClass = sun.misc.Unsafe.class;
Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Object unsafeObject = theUnsafe.get(null);
if (unsafeClass.isInstance(unsafeObject)) {
return unsafeClass.cast(unsafeObject);
}
throw new NoSuchFieldError("the Unsafe");
}
};
return AccessController.doPrivileged(action);
}
catch (Exception e) {
throw new RuntimeException("Unable to load unsafe", e);
}
}
public static final void eraseString(String string) { public static final void eraseString(String string) {
// You can change the value of the inner char[] using reflection. // You can change the value of the inner char[] using reflection.
@ -137,9 +111,13 @@ public class Sys {
valueField.set(string, new char[0]); // replace it. valueField.set(string, new char[0]); // replace it.
// set count to 0 // set count to 0
Field countField = String.class.getDeclaredField("count"); try {
countField.setAccessible(true); // newer versions of java don't have this field
countField.set(string, 0); Field countField = String.class.getDeclaredField("count");
countField.setAccessible(true);
countField.set(string, 0);
} catch (Exception ignored) {
}
// set hash to 0 // set hash to 0
Field hashField = String.class.getDeclaredField("hash"); Field hashField = String.class.getDeclaredField("hash");

View File

@ -19,13 +19,16 @@
*/ */
package dorkbox.util.objectPool; package dorkbox.util.objectPool;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import dorkbox.util.Sys;
class FastObjectPool<T> implements ObjectPool<T> { class FastObjectPool<T> implements ObjectPool<T> {
private final sun.misc.Unsafe unsafe;
private static final boolean FREE = true; private static final boolean FREE = true;
private static final boolean USED = false; private static final boolean USED = false;
@ -43,6 +46,28 @@ class FastObjectPool<T> implements ObjectPool<T> {
private ThreadLocal<ObjectPoolHolder<T>> localValue = new ThreadLocal<>(); private ThreadLocal<ObjectPoolHolder<T>> localValue = new ThreadLocal<>();
FastObjectPool(PoolableObject<T> poolableObject, int size) { FastObjectPool(PoolableObject<T> poolableObject, int size) {
try {
final PrivilegedExceptionAction<sun.misc.Unsafe> action = new PrivilegedExceptionAction<sun.misc.Unsafe>() {
@Override
public sun.misc.Unsafe run() throws Exception {
Class<sun.misc.Unsafe> unsafeClass = sun.misc.Unsafe.class;
Field theUnsafe = unsafeClass.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
Object unsafeObject = theUnsafe.get(null);
if (unsafeClass.isInstance(unsafeObject)) {
return unsafeClass.cast(unsafeObject);
}
throw new NoSuchFieldError("the Unsafe");
}
};
this.unsafe = AccessController.doPrivileged(action);
}
catch (Exception e) {
throw new RuntimeException("Unable to load unsafe", e);
}
int newSize = 1; int newSize = 1;
while (newSize < size) { while (newSize < size) {
@ -61,8 +86,8 @@ class FastObjectPool<T> implements ObjectPool<T> {
this.mask = size-1; this.mask = size-1;
this.releasePointer = size; this.releasePointer = size;
this.BASE = Sys.unsafe.arrayBaseOffset(ObjectPoolHolder[].class); this.BASE = this.unsafe.arrayBaseOffset(ObjectPoolHolder[].class);
this.INDEXSCALE = Sys.unsafe.arrayIndexScale(ObjectPoolHolder[].class); this.INDEXSCALE = this.unsafe.arrayIndexScale(ObjectPoolHolder[].class);
this.ASHIFT = 31 - Integer.numberOfLeadingZeros((int) this.INDEXSCALE); this.ASHIFT = 31 - Integer.numberOfLeadingZeros((int) this.INDEXSCALE);
} }
@ -78,7 +103,7 @@ class FastObjectPool<T> implements ObjectPool<T> {
} }
} }
sun.misc.Unsafe unsafe = Sys.unsafe; sun.misc.Unsafe unsafe = this.unsafe;
while (this.releasePointer != (localTakePointer=this.takePointer)) { while (this.releasePointer != (localTakePointer=this.takePointer)) {
int index = localTakePointer & this.mask; int index = localTakePointer & this.mask;
@ -109,7 +134,7 @@ class FastObjectPool<T> implements ObjectPool<T> {
long index = ((localValue & this.mask)<<this.ASHIFT ) + this.BASE; long index = ((localValue & this.mask)<<this.ASHIFT ) + this.BASE;
if (object.state.compareAndSet(USED, FREE)) { if (object.state.compareAndSet(USED, FREE)) {
Sys.unsafe.putOrderedObject(this.objects, index, object); this.unsafe.putOrderedObject(this.objects, index, object);
this.releasePointer = localValue+1; this.releasePointer = localValue+1;
} }
else { else {