mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8221477: Inject os/cpu-specific constants into Unsafe from JVM
Initialize Unsafe os/cpu-specific constants using injection instead of native callouts Reviewed-by: stuefe, coleenp, dholmes, plevart
This commit is contained in:
parent
7a093bcf50
commit
71164a973b
9 changed files with 190 additions and 52 deletions
|
@ -33,6 +33,7 @@ import sun.nio.ch.DirectBuffer;
|
|||
import java.lang.reflect.Field;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import static jdk.internal.misc.UnsafeConstants.*;
|
||||
|
||||
/**
|
||||
* A collection of methods for performing low-level, unsafe operations.
|
||||
|
@ -1166,14 +1167,13 @@ public final class Unsafe {
|
|||
}
|
||||
|
||||
/** The value of {@code addressSize()} */
|
||||
public static final int ADDRESS_SIZE = theUnsafe.addressSize0();
|
||||
public static final int ADDRESS_SIZE = ADDRESS_SIZE0;
|
||||
|
||||
/**
|
||||
* Reports the size in bytes of a native memory page (whatever that is).
|
||||
* This value will always be a power of two.
|
||||
*/
|
||||
public native int pageSize();
|
||||
|
||||
public int pageSize() { return PAGE_SIZE; }
|
||||
|
||||
/// random trusted operations from JNI:
|
||||
|
||||
|
@ -1417,7 +1417,7 @@ public final class Unsafe {
|
|||
byte x) {
|
||||
long wordOffset = offset & ~3;
|
||||
int shift = (int) (offset & 3) << 3;
|
||||
if (BE) {
|
||||
if (BIG_ENDIAN) {
|
||||
shift = 24 - shift;
|
||||
}
|
||||
int mask = 0xFF << shift;
|
||||
|
@ -1491,7 +1491,7 @@ public final class Unsafe {
|
|||
}
|
||||
long wordOffset = offset & ~3;
|
||||
int shift = (int) (offset & 3) << 3;
|
||||
if (BE) {
|
||||
if (BIG_ENDIAN) {
|
||||
shift = 16 - shift;
|
||||
}
|
||||
int mask = 0xFFFF << shift;
|
||||
|
@ -3354,14 +3354,14 @@ public final class Unsafe {
|
|||
* @return Returns true if the native byte ordering of this
|
||||
* platform is big-endian, false if it is little-endian.
|
||||
*/
|
||||
public final boolean isBigEndian() { return BE; }
|
||||
public final boolean isBigEndian() { return BIG_ENDIAN; }
|
||||
|
||||
/**
|
||||
* @return Returns true if this platform is capable of performing
|
||||
* accesses at addresses which are not aligned for the type of the
|
||||
* primitive type being accessed, false otherwise.
|
||||
*/
|
||||
public final boolean unalignedAccess() { return unalignedAccess; }
|
||||
public final boolean unalignedAccess() { return UNALIGNED_ACCESS; }
|
||||
|
||||
/**
|
||||
* Fetches a value at some byte offset into a given Java object.
|
||||
|
@ -3603,14 +3603,7 @@ public final class Unsafe {
|
|||
putCharUnaligned(o, offset, convEndian(bigEndian, x));
|
||||
}
|
||||
|
||||
// JVM interface methods
|
||||
// BE is true iff the native endianness of this platform is big.
|
||||
private static final boolean BE = theUnsafe.isBigEndian0();
|
||||
|
||||
// unalignedAccess is true iff this platform can perform unaligned accesses.
|
||||
private static final boolean unalignedAccess = theUnsafe.unalignedAccess0();
|
||||
|
||||
private static int pickPos(int top, int pos) { return BE ? top - pos : pos; }
|
||||
private static int pickPos(int top, int pos) { return BIG_ENDIAN ? top - pos : pos; }
|
||||
|
||||
// These methods construct integers from bytes. The byte ordering
|
||||
// is the native endianness of this platform.
|
||||
|
@ -3649,9 +3642,9 @@ public final class Unsafe {
|
|||
| (toUnsignedInt(i1) << pickPos(8, 8)));
|
||||
}
|
||||
|
||||
private static byte pick(byte le, byte be) { return BE ? be : le; }
|
||||
private static short pick(short le, short be) { return BE ? be : le; }
|
||||
private static int pick(int le, int be) { return BE ? be : le; }
|
||||
private static byte pick(byte le, byte be) { return BIG_ENDIAN ? be : le; }
|
||||
private static short pick(short le, short be) { return BIG_ENDIAN ? be : le; }
|
||||
private static int pick(int le, int be) { return BIG_ENDIAN ? be : le; }
|
||||
|
||||
// These methods write integers to memory from smaller parts
|
||||
// provided by their caller. The ordering in which these parts
|
||||
|
@ -3699,10 +3692,10 @@ public final class Unsafe {
|
|||
private static long toUnsignedLong(int n) { return n & 0xffffffffl; }
|
||||
|
||||
// Maybe byte-reverse an integer
|
||||
private static char convEndian(boolean big, char n) { return big == BE ? n : Character.reverseBytes(n); }
|
||||
private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; }
|
||||
private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; }
|
||||
private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; }
|
||||
private static char convEndian(boolean big, char n) { return big == BIG_ENDIAN ? n : Character.reverseBytes(n); }
|
||||
private static short convEndian(boolean big, short n) { return big == BIG_ENDIAN ? n : Short.reverseBytes(n) ; }
|
||||
private static int convEndian(boolean big, int n) { return big == BIG_ENDIAN ? n : Integer.reverseBytes(n) ; }
|
||||
private static long convEndian(boolean big, long n) { return big == BIG_ENDIAN ? n : Long.reverseBytes(n) ; }
|
||||
|
||||
|
||||
|
||||
|
@ -3721,11 +3714,8 @@ public final class Unsafe {
|
|||
private native void ensureClassInitialized0(Class<?> c);
|
||||
private native int arrayBaseOffset0(Class<?> arrayClass);
|
||||
private native int arrayIndexScale0(Class<?> arrayClass);
|
||||
private native int addressSize0();
|
||||
private native Class<?> defineAnonymousClass0(Class<?> hostClass, byte[] data, Object[] cpPatches);
|
||||
private native int getLoadAverage0(double[] loadavg, int nelems);
|
||||
private native boolean unalignedAccess0();
|
||||
private native boolean isBigEndian0();
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Red Hat Inc. 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package jdk.internal.misc;
|
||||
|
||||
/**
|
||||
* A class used to expose details of the underlying hardware that
|
||||
* configure the operation of class Unsafe. This class is
|
||||
* package-private as the only intended client is class Unsafe.
|
||||
* All fields in this class must be static final constants.
|
||||
*
|
||||
* @since 13
|
||||
*
|
||||
* @implNote
|
||||
*
|
||||
* The JVM injects hardware-specific values into all the static fields
|
||||
* of this class during JVM initialization. The static initialization
|
||||
* block is executed when the class is initialized then JVM injection
|
||||
* updates the fields with the correct constants. The static block
|
||||
* is required to prevent the fields from being considered constant
|
||||
* variables, so the field values will be not be compiled directly into
|
||||
* any class that uses them.
|
||||
*/
|
||||
|
||||
final class UnsafeConstants {
|
||||
|
||||
/**
|
||||
* This constructor is private because the class is not meant to
|
||||
* be instantiated.
|
||||
*/
|
||||
private UnsafeConstants() {}
|
||||
|
||||
/**
|
||||
* The size in bytes of a native pointer, as stored via {@link
|
||||
* #putAddress}. This value will be either 4 or 8. Note that the
|
||||
* sizes of other primitive types (as stored in native memory
|
||||
* blocks) is determined fully by their information content.
|
||||
*
|
||||
* @implNote
|
||||
* The actual value for this field is injected by the JVM.
|
||||
*/
|
||||
|
||||
static final int ADDRESS_SIZE0;
|
||||
|
||||
/**
|
||||
* The size in bytes of a native memory page (whatever that is).
|
||||
* This value will always be a power of two.
|
||||
*
|
||||
* @implNote
|
||||
* The actual value for this field is injected by the JVM.
|
||||
*/
|
||||
|
||||
static final int PAGE_SIZE;
|
||||
|
||||
/**
|
||||
* Flag whose value is true if and only if the native endianness
|
||||
* of this platform is big.
|
||||
*
|
||||
* @implNote
|
||||
* The actual value for this field is injected by the JVM.
|
||||
*/
|
||||
|
||||
static final boolean BIG_ENDIAN;
|
||||
|
||||
/**
|
||||
* Flag whose value is true if and only if the platform can
|
||||
* perform unaligned accesses
|
||||
*
|
||||
* @implNote
|
||||
* The actual value for this field is injected by the JVM.
|
||||
*/
|
||||
|
||||
static final boolean UNALIGNED_ACCESS;
|
||||
|
||||
static {
|
||||
ADDRESS_SIZE0 = 0;
|
||||
PAGE_SIZE = 0;
|
||||
BIG_ENDIAN = false;
|
||||
UNALIGNED_ACCESS = false;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue