# HG changeset patch # User redestad # Date 1497963327 -7200 # Tue Jun 20 14:55:27 2017 +0200 # Node ID daa7a161da7b1167c62f31be8de81601a9374018 # Parent afbec24a44ee058ed7fdce8ce9b4321cca19995d 8182487: Add Unsafe.objectFieldOffset(Class, String) Reviewed-by: dsimms diff --git a/src/java.base/share/classes/java/io/File.java b/src/java.base/share/classes/java/io/File.java --- a/src/java.base/share/classes/java/io/File.java +++ b/src/java.base/share/classes/java/io/File.java @@ -2240,16 +2240,12 @@ 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); - } + jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + PATH_OFFSET = unsafe.objectFieldOffset( + File.class, "path"); + PREFIX_LENGTH_OFFSET = unsafe.objectFieldOffset( + File.class, "prefixLength"); + UNSAFE = unsafe; } diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -2863,18 +2863,13 @@ 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"); + reflectionDataOffset = objectFieldOffset("reflectionData"); + annotationTypeOffset = objectFieldOffset("annotationType"); + annotationDataOffset = objectFieldOffset("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 long objectFieldOffset(String fieldName) { + return unsafe.objectFieldOffset(Class.class, fieldName); } static boolean casReflectionData(Class clazz, diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -2878,12 +2878,7 @@ 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); } } diff --git a/src/java.base/share/classes/java/lang/invoke/CallSite.java b/src/java.base/share/classes/java/lang/invoke/CallSite.java --- a/src/java.base/share/classes/java/lang/invoke/CallSite.java +++ b/src/java.base/share/classes/java/lang/invoke/CallSite.java @@ -276,11 +276,9 @@ 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*/ diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java --- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java @@ -1589,10 +1589,6 @@ private static final long FORM_OFFSET; static { - try { - FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form")); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); - } + FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class, "form"); } } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodType.java b/src/java.base/share/classes/java/lang/invoke/MethodType.java --- a/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -1241,14 +1241,8 @@ 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); - } + rtypeOffset = UNSAFE.objectFieldOffset(MethodType.class, "rtype"); + ptypesOffset = UNSAFE.objectFieldOffset(MethodType.class, "ptypes"); } } diff --git a/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/src/java.base/share/classes/java/lang/invoke/VarHandle.java --- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java +++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java @@ -2000,12 +2000,7 @@ 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 diff --git a/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java b/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java --- a/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java +++ b/src/java.base/share/classes/java/lang/invoke/VarHandleByteArrayBase.java @@ -44,22 +44,13 @@ static final long BYTE_BUFFER_IS_READ_ONLY; static { - try { - BUFFER_ADDRESS = UNSAFE.objectFieldOffset( - Buffer.class.getDeclaredField("address")); + BUFFER_ADDRESS = UNSAFE.objectFieldOffset(Buffer.class, "address"); - BUFFER_LIMIT = UNSAFE.objectFieldOffset( - Buffer.class.getDeclaredField("limit")); + BUFFER_LIMIT = UNSAFE.objectFieldOffset(Buffer.class, "limit"); - BYTE_BUFFER_HB = UNSAFE.objectFieldOffset( - ByteBuffer.class.getDeclaredField("hb")); + 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); - } + BYTE_BUFFER_IS_READ_ONLY = UNSAFE.objectFieldOffset(ByteBuffer.class, "isReadOnly"); } static final boolean BE = UNSAFE.isBigEndian(); diff --git a/src/java.base/share/classes/java/math/BigDecimal.java b/src/java.base/share/classes/java/math/BigDecimal.java --- a/src/java.base/share/classes/java/math/BigDecimal.java +++ b/src/java.base/share/classes/java/math/BigDecimal.java @@ -4070,15 +4070,11 @@ 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); - } + unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + intCompactOffset = unsafe.objectFieldOffset + (BigDecimal.class, "intCompact"); + intValOffset = unsafe.objectFieldOffset + (BigDecimal.class, "intVal"); } static void setIntCompact(BigDecimal bd, long val) { unsafe.putLong(bd, intCompactOffset, val); diff --git a/src/java.base/share/classes/java/math/BigInteger.java b/src/java.base/share/classes/java/math/BigInteger.java --- a/src/java.base/share/classes/java/math/BigInteger.java +++ b/src/java.base/share/classes/java/math/BigInteger.java @@ -4586,15 +4586,9 @@ 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); - } + unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + signumOffset = unsafe.objectFieldOffset(BigInteger.class, "signum"); + magOffset = unsafe.objectFieldOffset(BigInteger.class, "mag"); } static void putSign(BigInteger bi, int sign) { diff --git a/src/java.base/share/classes/java/net/Inet6Address.java b/src/java.base/share/classes/java/net/Inet6Address.java --- a/src/java.base/share/classes/java/net/Inet6Address.java +++ b/src/java.base/share/classes/java/net/Inet6Address.java @@ -580,14 +580,10 @@ 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); - } + jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + FIELDS_OFFSET = unsafe.objectFieldOffset( + Inet6Address.class, "holder6"); + UNSAFE = unsafe; } /** diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -1710,15 +1710,9 @@ 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); - } + jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + FIELDS_OFFSET = unsafe.objectFieldOffset(InetAddress.class, "holder"); + UNSAFE = unsafe; } private void readObject (ObjectInputStream s) throws diff --git a/src/java.base/share/classes/java/net/InetSocketAddress.java b/src/java.base/share/classes/java/net/InetSocketAddress.java --- a/src/java.base/share/classes/java/net/InetSocketAddress.java +++ b/src/java.base/share/classes/java/net/InetSocketAddress.java @@ -305,14 +305,9 @@ 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); - } + jdk.internal.misc.Unsafe unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + FIELDS_OFFSET = unsafe.objectFieldOffset(InetSocketAddress.class, "holder"); + UNSAFE = unsafe; } /** diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -3309,12 +3309,8 @@ 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); - } + LOCKSTATE = U.objectFieldOffset + (TreeBin.class, "lockState"); } } @@ -6381,27 +6377,23 @@ 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 diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java --- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -1057,22 +1057,18 @@ 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); - } + SEED = U.objectFieldOffset + (Thread.class, "threadLocalRandomSeed"); + PROBE = U.objectFieldOffset + (Thread.class, "threadLocalRandomProbe"); + SECONDARY = U.objectFieldOffset + (Thread.class, "threadLocalRandomSecondarySeed"); + THREADLOCALS = U.objectFieldOffset + (Thread.class, "threadLocals"); + INHERITABLETHREADLOCALS = U.objectFieldOffset + (Thread.class, "inheritableThreadLocals"); + INHERITEDACCESSCONTROLCONTEXT = U.objectFieldOffset + (Thread.class, "inheritedAccessControlContext"); } /** Rarely-used holder for the second of a pair of Gaussians */ diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -62,12 +62,7 @@ private static final long VALUE; static { - try { - VALUE = U.objectFieldOffset - (AtomicInteger.class.getDeclaredField("value")); - } catch (ReflectiveOperationException e) { - throw new Error(e); - } + VALUE = U.objectFieldOffset(AtomicInteger.class, "value"); } private volatile int value; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -76,12 +76,7 @@ private static final long VALUE; static { - try { - VALUE = U.objectFieldOffset - (AtomicLong.class.getDeclaredField("value")); - } catch (ReflectiveOperationException e) { - throw new Error(e); - } + VALUE = U.objectFieldOffset(AtomicLong.class, "value"); } private volatile long value; diff --git a/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java b/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java --- a/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java @@ -423,17 +423,12 @@ 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); - } + PARKBLOCKER = U.objectFieldOffset + (Thread.class, "parkBlocker"); + SECONDARY = U.objectFieldOffset + (Thread.class, "threadLocalRandomSecondarySeed"); + TID = U.objectFieldOffset + (Thread.class, "tid"); } } diff --git a/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java b/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java --- a/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java +++ b/src/java.base/share/classes/jdk/internal/misc/InnocuousThread.java @@ -135,17 +135,16 @@ 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); diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -954,6 +954,25 @@ } /** + * 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}. *

Do not expect to perform any sort of arithmetic on this offset; @@ -3685,6 +3704,7 @@ 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); diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -618,15 +618,11 @@ 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); - } + unsafe = jdk.internal.misc.Unsafe.getUnsafe(); + typeOffset = unsafe.objectFieldOffset + (AnnotationInvocationHandler.class, "type"); + memberValuesOffset = unsafe.objectFieldOffset + (AnnotationInvocationHandler.class, "memberValues"); } static void setType(AnnotationInvocationHandler o, Class type) {