提交 fb03234a 编写于 作者: R redestad

8182487: Add Unsafe.objectFieldOffset(Class, String)

Reviewed-by: dsimms, twisti, bchristi, mgerdin, chegar, psandoz
上级 f7bbb23c
......@@ -2236,22 +2236,12 @@ public class File
UNSAFE.putIntVolatile(this, PREFIX_LENGTH_OFFSET, fs.prefixLength(path));
}
private static final long PATH_OFFSET;
private static final long PREFIX_LENGTH_OFFSET;
private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
PATH_OFFSET = unsafe.objectFieldOffset(
File.class.getDeclaredField("path"));
PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset(
File.class.getDeclaredField("prefixLength"));
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final jdk.internal.misc.Unsafe UNSAFE
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long PATH_OFFSET
= UNSAFE.objectFieldOffset(File.class, "path");
private static final long PREFIX_LENGTH_OFFSET
= UNSAFE.objectFieldOffset(File.class, "prefixLength");
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = 301077366599181567L;
......
......@@ -2856,26 +2856,14 @@ public final class Class<T> implements java.io.Serializable,
// and have to avoid calling it in the static initializer of the Class class...
private static final Unsafe unsafe = Unsafe.getUnsafe();
// offset of Class.reflectionData instance field
private static final long reflectionDataOffset;
private static final long reflectionDataOffset
= unsafe.objectFieldOffset(Class.class, "reflectionData");
// offset of Class.annotationType instance field
private static final long annotationTypeOffset;
private static final long annotationTypeOffset
= unsafe.objectFieldOffset(Class.class, "annotationType");
// offset of Class.annotationData instance field
private static final long annotationDataOffset;
static {
Field[] fields = Class.class.getDeclaredFields0(false); // bypass caches
reflectionDataOffset = objectFieldOffset(fields, "reflectionData");
annotationTypeOffset = objectFieldOffset(fields, "annotationType");
annotationDataOffset = objectFieldOffset(fields, "annotationData");
}
private static long objectFieldOffset(Field[] fields, String fieldName) {
Field field = searchFields(fields, fieldName);
if (field == null) {
throw new Error("No " + fieldName + " field found in java.lang.Class");
}
return unsafe.objectFieldOffset(field);
}
private static final long annotationDataOffset
= unsafe.objectFieldOffset(Class.class, "annotationData");
static <T> boolean casReflectionData(Class<?> clazz,
SoftReference<ReflectionData<T>> oldData,
......
......@@ -30,7 +30,6 @@ import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.net.URL;
import java.security.AccessController;
import java.security.AccessControlContext;
......@@ -2876,12 +2875,7 @@ public abstract class ClassLoader {
Unsafe unsafe = Unsafe.getUnsafe();
Class<?> k = ClassLoader.class;
long offset;
try {
Field f = k.getDeclaredField(name);
offset = unsafe.objectFieldOffset(f);
} catch (NoSuchFieldException e) {
throw new InternalError(e);
}
offset = unsafe.objectFieldOffset(k, name);
return unsafe.compareAndSetObject(this, offset, null, obj);
}
}
......
......@@ -276,11 +276,9 @@ public class CallSite {
if (offset > 0) {
return offset;
}
try {
offset = TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
assert(offset > 0);
return offset;
} catch (Exception ex) { throw newInternalError(ex); }
offset = TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class, "target");
assert(offset > 0);
return offset;
}
/*package-private*/
......
......@@ -1587,12 +1587,6 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
}
}
private static final long FORM_OFFSET;
static {
try {
FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}
}
private static final long FORM_OFFSET
= UNSAFE.objectFieldOffset(MethodHandle.class, "form");
}
......@@ -1239,17 +1239,11 @@ s.writeObject(this.parameterArray());
// Support for resetting final fields while deserializing. Implement Holder
// pattern to make the rarely needed offset calculation lazy.
private static class OffsetHolder {
private static final long rtypeOffset, ptypesOffset;
static {
try {
rtypeOffset = UNSAFE.objectFieldOffset
(MethodType.class.getDeclaredField("rtype"));
ptypesOffset = UNSAFE.objectFieldOffset
(MethodType.class.getDeclaredField("ptypes"));
} catch (Exception ex) {
throw new Error(ex);
}
}
static final long rtypeOffset
= UNSAFE.objectFieldOffset(MethodType.class, "rtype");
static final long ptypesOffset
= UNSAFE.objectFieldOffset(MethodType.class, "ptypes");
}
/**
......
......@@ -2000,12 +2000,7 @@ public abstract class VarHandle {
private static final long VFORM_OFFSET;
static {
try {
VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class.getDeclaredField("vform"));
}
catch (ReflectiveOperationException e) {
throw newInternalError(e);
}
VFORM_OFFSET = UNSAFE.objectFieldOffset(VarHandle.class, "vform");
// The VarHandleGuards must be initialized to ensure correct
// compilation of the guard methods
......
......@@ -35,32 +35,20 @@ import static java.lang.invoke.MethodHandleStatics.UNSAFE;
*/
abstract class VarHandleByteArrayBase {
// Buffer.address
static final long BUFFER_ADDRESS;
// Buffer.limit
static final long BUFFER_LIMIT;
// ByteBuffer.hb
static final long BYTE_BUFFER_HB;
// ByteBuffer.isReadOnly
static final long BYTE_BUFFER_IS_READ_ONLY;
static {
try {
BUFFER_ADDRESS = UNSAFE.objectFieldOffset(
Buffer.class.getDeclaredField("address"));
static final long BUFFER_ADDRESS
= UNSAFE.objectFieldOffset(Buffer.class, "address");
BUFFER_LIMIT = UNSAFE.objectFieldOffset(
Buffer.class.getDeclaredField("limit"));
// Buffer.limit
static final long BUFFER_LIMIT
= UNSAFE.objectFieldOffset(Buffer.class, "limit");
BYTE_BUFFER_HB = UNSAFE.objectFieldOffset(
ByteBuffer.class.getDeclaredField("hb"));
// ByteBuffer.hb
static final long BYTE_BUFFER_HB
= UNSAFE.objectFieldOffset(ByteBuffer.class, "hb");
BYTE_BUFFER_IS_READ_ONLY = UNSAFE.objectFieldOffset(
ByteBuffer.class.getDeclaredField("isReadOnly"));
}
catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
// ByteBuffer.isReadOnly
static final long BYTE_BUFFER_IS_READ_ONLY
= UNSAFE.objectFieldOffset(ByteBuffer.class, "isReadOnly");
static final boolean BE = UNSAFE.isBigEndian();
......
......@@ -4067,20 +4067,13 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
}
private static class UnsafeHolder {
private static final jdk.internal.misc.Unsafe unsafe;
private static final long intCompactOffset;
private static final long intValOffset;
static {
try {
unsafe = jdk.internal.misc.Unsafe.getUnsafe();
intCompactOffset = unsafe.objectFieldOffset
(BigDecimal.class.getDeclaredField("intCompact"));
intValOffset = unsafe.objectFieldOffset
(BigDecimal.class.getDeclaredField("intVal"));
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
private static final jdk.internal.misc.Unsafe unsafe
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long intCompactOffset
= unsafe.objectFieldOffset(BigDecimal.class, "intCompact");
private static final long intValOffset
= unsafe.objectFieldOffset(BigDecimal.class, "intVal");
static void setIntCompact(BigDecimal bd, long val) {
unsafe.putLong(bd, intCompactOffset, val);
}
......
......@@ -4582,20 +4582,12 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
// Support for resetting final fields while deserializing
private static class UnsafeHolder {
private static final jdk.internal.misc.Unsafe unsafe;
private static final long signumOffset;
private static final long magOffset;
static {
try {
unsafe = jdk.internal.misc.Unsafe.getUnsafe();
signumOffset = unsafe.objectFieldOffset
(BigInteger.class.getDeclaredField("signum"));
magOffset = unsafe.objectFieldOffset
(BigInteger.class.getDeclaredField("mag"));
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
private static final jdk.internal.misc.Unsafe unsafe
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long signumOffset
= unsafe.objectFieldOffset(BigInteger.class, "signum");
private static final long magOffset
= unsafe.objectFieldOffset(BigInteger.class, "mag");
static void putSign(BigInteger bi, int sign) {
unsafe.putInt(bi, signumOffset, sign);
......
......@@ -576,19 +576,10 @@ class Inet6Address extends InetAddress {
new ObjectStreamField("ifname", String.class)
};
private static final long FIELDS_OFFSET;
private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
Inet6Address.class.getDeclaredField("holder6"));
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final jdk.internal.misc.Unsafe UNSAFE
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long FIELDS_OFFSET = UNSAFE.objectFieldOffset(
Inet6Address.class, "holder6");
/**
* restore the state of this object from stream
......
......@@ -1706,20 +1706,10 @@ class InetAddress implements java.io.Serializable {
}
}
private static final long FIELDS_OFFSET;
private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetAddress.class.getDeclaredField("holder")
);
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final jdk.internal.misc.Unsafe UNSAFE
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long FIELDS_OFFSET
= UNSAFE.objectFieldOffset(InetAddress.class, "holder");
private void readObject (ObjectInputStream s) throws
IOException, ClassNotFoundException {
......
......@@ -302,18 +302,10 @@ public class InetSocketAddress
throw new InvalidObjectException("Stream data required");
}
private static final long FIELDS_OFFSET;
private static final jdk.internal.misc.Unsafe UNSAFE;
static {
try {
jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetSocketAddress.class.getDeclaredField("holder"));
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final jdk.internal.misc.Unsafe UNSAFE
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long FIELDS_OFFSET
= UNSAFE.objectFieldOffset(InetSocketAddress.class, "holder");
/**
* Gets the port number.
......
......@@ -3307,15 +3307,8 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
}
private static final Unsafe U = Unsafe.getUnsafe();
private static final long LOCKSTATE;
static {
try {
LOCKSTATE = U.objectFieldOffset
(TreeBin.class.getDeclaredField("lockState"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final long LOCKSTATE
= U.objectFieldOffset(TreeBin.class, "lockState");
}
/* ----------------Table Traversal -------------- */
......@@ -6381,27 +6374,23 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
private static final int ASHIFT;
static {
try {
SIZECTL = U.objectFieldOffset
(ConcurrentHashMap.class.getDeclaredField("sizeCtl"));
TRANSFERINDEX = U.objectFieldOffset
(ConcurrentHashMap.class.getDeclaredField("transferIndex"));
BASECOUNT = U.objectFieldOffset
(ConcurrentHashMap.class.getDeclaredField("baseCount"));
CELLSBUSY = U.objectFieldOffset
(ConcurrentHashMap.class.getDeclaredField("cellsBusy"));
CELLVALUE = U.objectFieldOffset
(CounterCell.class.getDeclaredField("value"));
ABASE = U.arrayBaseOffset(Node[].class);
int scale = U.arrayIndexScale(Node[].class);
if ((scale & (scale - 1)) != 0)
throw new Error("array index scale not a power of two");
ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
SIZECTL = U.objectFieldOffset
(ConcurrentHashMap.class, "sizeCtl");
TRANSFERINDEX = U.objectFieldOffset
(ConcurrentHashMap.class, "transferIndex");
BASECOUNT = U.objectFieldOffset
(ConcurrentHashMap.class, "baseCount");
CELLSBUSY = U.objectFieldOffset
(ConcurrentHashMap.class, "cellsBusy");
CELLVALUE = U.objectFieldOffset
(CounterCell.class, "value");
ABASE = U.arrayBaseOffset(Node[].class);
int scale = U.arrayIndexScale(Node[].class);
if ((scale & (scale - 1)) != 0)
throw new Error("array index scale not a power of two");
ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
// Reduce the risk of rare disastrous classloading in first call to
// LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
......
......@@ -1050,30 +1050,18 @@ public class ThreadLocalRandom extends Random {
// Unsafe mechanics
private static final Unsafe U = Unsafe.getUnsafe();
private static final long SEED;
private static final long PROBE;
private static final long SECONDARY;
private static final long THREADLOCALS;
private static final long INHERITABLETHREADLOCALS;
private static final long INHERITEDACCESSCONTROLCONTEXT;
static {
try {
SEED = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomSeed"));
PROBE = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomProbe"));
SECONDARY = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
THREADLOCALS = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocals"));
INHERITABLETHREADLOCALS = U.objectFieldOffset
(Thread.class.getDeclaredField("inheritableThreadLocals"));
INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
(Thread.class.getDeclaredField("inheritedAccessControlContext"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final long SEED = U.objectFieldOffset
(Thread.class, "threadLocalRandomSeed");
private static final long PROBE = U.objectFieldOffset
(Thread.class, "threadLocalRandomProbe");
private static final long SECONDARY = U.objectFieldOffset
(Thread.class, "threadLocalRandomSecondarySeed");
private static final long THREADLOCALS = U.objectFieldOffset
(Thread.class, "threadLocals");
private static final long INHERITABLETHREADLOCALS = U.objectFieldOffset
(Thread.class, "inheritableThreadLocals");
private static final long INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset
(Thread.class, "inheritedAccessControlContext");
/** Rarely-used holder for the second of a pair of Gaussians */
private static final ThreadLocal<Double> nextLocalGaussian =
......
......@@ -59,16 +59,7 @@ public class AtomicInteger extends Number implements java.io.Serializable {
* are unresolved cyclic startup dependencies.
*/
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
try {
VALUE = U.objectFieldOffset
(AtomicInteger.class.getDeclaredField("value"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final long VALUE = U.objectFieldOffset(AtomicInteger.class, "value");
private volatile int value;
......
......@@ -73,16 +73,7 @@ public class AtomicLong extends Number implements java.io.Serializable {
* are unresolved cyclic startup dependencies.
*/
private static final jdk.internal.misc.Unsafe U = jdk.internal.misc.Unsafe.getUnsafe();
private static final long VALUE;
static {
try {
VALUE = U.objectFieldOffset
(AtomicLong.class.getDeclaredField("value"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final long VALUE = U.objectFieldOffset(AtomicLong.class, "value");
private volatile long value;
......
......@@ -421,21 +421,11 @@ public class LockSupport {
// Hotspot implementation via intrinsics API
private static final Unsafe U = Unsafe.getUnsafe();
private static final long PARKBLOCKER;
private static final long SECONDARY;
private static final long TID;
static {
try {
PARKBLOCKER = U.objectFieldOffset
(Thread.class.getDeclaredField("parkBlocker"));
SECONDARY = U.objectFieldOffset
(Thread.class.getDeclaredField("threadLocalRandomSecondarySeed"));
TID = U.objectFieldOffset
(Thread.class.getDeclaredField("tid"));
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private static final long PARKBLOCKER = U.objectFieldOffset
(Thread.class, "parkBlocker");
private static final long SECONDARY = U.objectFieldOffset
(Thread.class, "threadLocalRandomSecondarySeed");
private static final long TID = U.objectFieldOffset
(Thread.class, "tid");
}
......@@ -135,17 +135,16 @@ public final class InnocuousThread extends Thread {
Class<?> tk = Thread.class;
Class<?> gk = ThreadGroup.class;
THREAD_LOCALS = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocals"));
THREAD_LOCALS = UNSAFE.objectFieldOffset(tk, "threadLocals");
INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritableThreadLocals"));
(tk, "inheritableThreadLocals");
INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritedAccessControlContext"));
(tk, "inheritedAccessControlContext");
CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
(tk.getDeclaredField("contextClassLoader"));
(tk, "contextClassLoader");
long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group"));
long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent"));
long tg = UNSAFE.objectFieldOffset(tk, "group");
long gp = UNSAFE.objectFieldOffset(gk, "parent");
ThreadGroup group = (ThreadGroup)
UNSAFE.getObject(Thread.currentThread(), tg);
......
......@@ -953,6 +953,25 @@ public final class Unsafe {
return objectFieldOffset0(f);
}
/**
* Reports the location of the field with a given name in the storage
* allocation of its class.
*
* @throws NullPointerException if any parameter is {@code null}.
* @throws InternalError if there is no field named {@code name} declared
* in class {@code c}, i.e., if {@code c.getDeclaredField(name)}
* would throw {@code java.lang.NoSuchFieldException}.
*
* @see #objectFieldOffset(Field)
*/
public long objectFieldOffset(Class<?> c, String name) {
if (c == null || name == null) {
throw new NullPointerException();
}
return objectFieldOffset1(c, name);
}
/**
* Reports the location of a given static field, in conjunction with {@link
* #staticFieldBase}.
......@@ -3685,6 +3704,7 @@ public final class Unsafe {
private native void copyMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes);
private native void copySwapMemory0(Object srcBase, long srcOffset, Object destBase, long destOffset, long bytes, long elemSize);
private native long objectFieldOffset0(Field f);
private native long objectFieldOffset1(Class<?> c, String name);
private native long staticFieldOffset0(Field f);
private native Object staticFieldBase0(Field f);
private native boolean shouldBeInitialized0(Class<?> c);
......
......@@ -614,20 +614,13 @@ class AnnotationInvocationHandler implements InvocationHandler, Serializable {
}
private static class UnsafeAccessor {
private static final jdk.internal.misc.Unsafe unsafe;
private static final long typeOffset;
private static final long memberValuesOffset;
static {
try {
unsafe = jdk.internal.misc.Unsafe.getUnsafe();
typeOffset = unsafe.objectFieldOffset
(AnnotationInvocationHandler.class.getDeclaredField("type"));
memberValuesOffset = unsafe.objectFieldOffset
(AnnotationInvocationHandler.class.getDeclaredField("memberValues"));
} catch (Exception ex) {
throw new ExceptionInInitializerError(ex);
}
}
private static final jdk.internal.misc.Unsafe unsafe
= jdk.internal.misc.Unsafe.getUnsafe();
private static final long typeOffset = unsafe.objectFieldOffset
(AnnotationInvocationHandler.class, "type");
private static final long memberValuesOffset = unsafe.objectFieldOffset
(AnnotationInvocationHandler.class, "memberValues");
static void setType(AnnotationInvocationHandler o,
Class<? extends Annotation> type) {
unsafe.putObject(o, typeOffset, type);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册