8344168: Change Unsafe base offset from int to long

Reviewed-by: liach
This commit is contained in:
Shaojin Wen 2025-01-30 15:57:13 +00:00
parent 5d5b294b0a
commit fdfb68c8d0
53 changed files with 164 additions and 154 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -715,7 +715,7 @@ final class StringLatin1 {
static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) {
assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check";
// Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores.
long offset = (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
UNSAFE.putByte(val, offset , (byte)(c1));
UNSAFE.putByte(val, offset + 1, (byte)(c2));
UNSAFE.putByte(val, offset + 2, (byte)(c3));
@ -725,7 +725,7 @@ final class StringLatin1 {
static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) {
assert index >= 0 && index + 4 < length(val) : "Trusted caller missed bounds check";
// Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores.
long offset = (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + index;
UNSAFE.putByte(val, offset , (byte)(c1));
UNSAFE.putByte(val, offset + 1, (byte)(c2));
UNSAFE.putByte(val, offset + 2, (byte)(c3));

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -196,7 +196,7 @@ final class VarHandles {
Class<?> componentType = arrayClass.getComponentType();
int aoffset = UNSAFE.arrayBaseOffset(arrayClass);
int aoffset = (int) UNSAFE.arrayBaseOffset(arrayClass);
int ascale = UNSAFE.arrayIndexScale(arrayClass);
int ashift = 31 - Integer.numberOfLeadingZeros(ascale);

View file

@ -6383,7 +6383,7 @@ public class ConcurrentHashMap<K,V> extends AbstractMap<K,V>
= U.objectFieldOffset(ConcurrentHashMap.class, "cellsBusy");
private static final long CELLVALUE
= U.objectFieldOffset(CounterCell.class, "value");
private static final int ABASE = U.arrayBaseOffset(Node[].class);
private static final long ABASE = U.arrayBaseOffset(Node[].class);
private static final int ASHIFT;
static {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -222,9 +222,9 @@ public final class CRC32C implements Checksum {
if (end - off >= 8 && Unsafe.ARRAY_BYTE_INDEX_SCALE == 1) {
// align on 8 bytes
int alignLength
long alignLength
= (8 - ((Unsafe.ARRAY_BYTE_BASE_OFFSET + off) & 0x7)) & 0x7;
for (int alignEnd = off + alignLength; off < alignEnd; off++) {
for (long alignEnd = off + alignLength; off < alignEnd; off++) {
crc = (crc >>> 8) ^ byteTable[(crc ^ b[off]) & 0xFF];
}
@ -238,11 +238,11 @@ public final class CRC32C implements Checksum {
int secondHalf;
if (Unsafe.ADDRESS_SIZE == 4) {
// On 32 bit platforms read two ints instead of a single 64bit long
firstHalf = UNSAFE.getInt(b, (long)Unsafe.ARRAY_BYTE_BASE_OFFSET + off);
secondHalf = UNSAFE.getInt(b, (long)Unsafe.ARRAY_BYTE_BASE_OFFSET + off
firstHalf = UNSAFE.getInt(b, Unsafe.ARRAY_BYTE_BASE_OFFSET + off);
secondHalf = UNSAFE.getInt(b, Unsafe.ARRAY_BYTE_BASE_OFFSET + off
+ Integer.BYTES);
} else {
long value = UNSAFE.getLong(b, (long)Unsafe.ARRAY_BYTE_BASE_OFFSET + off);
long value = UNSAFE.getLong(b, Unsafe.ARRAY_BYTE_BASE_OFFSET + off);
if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
firstHalf = (int) value;
secondHalf = (int) (value >>> 32);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2025, 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
@ -174,7 +174,7 @@ class ZipUtils {
Preconditions.checkIndex(off, b.length, Preconditions.AIOOBE_FORMATTER);
Preconditions.checkIndex(off + 1, b.length, Preconditions.AIOOBE_FORMATTER);
return Short.toUnsignedInt(
UNSAFE.getShortUnaligned(b, off + (long) Unsafe.ARRAY_BYTE_BASE_OFFSET, false));
UNSAFE.getShortUnaligned(b, off + Unsafe.ARRAY_BYTE_BASE_OFFSET, false));
}
/**
@ -185,7 +185,7 @@ class ZipUtils {
Preconditions.checkIndex(off, b.length, Preconditions.AIOOBE_FORMATTER);
Preconditions.checkIndex(off + 3, b.length, Preconditions.AIOOBE_FORMATTER);
return Integer.toUnsignedLong(
UNSAFE.getIntUnaligned(b, off + (long) Unsafe.ARRAY_BYTE_BASE_OFFSET, false));
UNSAFE.getIntUnaligned(b, off + Unsafe.ARRAY_BYTE_BASE_OFFSET, false));
}
/**
@ -195,7 +195,7 @@ class ZipUtils {
public static final long get64S(byte[] b, int off) {
Preconditions.checkIndex(off, b.length, Preconditions.AIOOBE_FORMATTER);
Preconditions.checkIndex(off + 7, b.length, Preconditions.AIOOBE_FORMATTER);
return UNSAFE.getLongUnaligned(b, off + (long) Unsafe.ARRAY_BYTE_BASE_OFFSET, false);
return UNSAFE.getLongUnaligned(b, off + Unsafe.ARRAY_BYTE_BASE_OFFSET, false);
}
/**
@ -206,7 +206,7 @@ class ZipUtils {
public static final int get32S(byte[] b, int off) {
Preconditions.checkIndex(off, b.length, Preconditions.AIOOBE_FORMATTER);
Preconditions.checkIndex(off + 3, b.length, Preconditions.AIOOBE_FORMATTER);
return UNSAFE.getIntUnaligned(b, off + (long) Unsafe.ARRAY_BYTE_BASE_OFFSET, false);
return UNSAFE.getIntUnaligned(b, off + Unsafe.ARRAY_BYTE_BASE_OFFSET, false);
}
/*

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2025, 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
@ -386,16 +386,16 @@ public final class RawBytecodeHelper {
}
public int getU2Unchecked(int bci) {
return UNSAFE.getCharUnaligned(code.array, (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + bci, true);
return UNSAFE.getCharUnaligned(code.array, Unsafe.ARRAY_BYTE_BASE_OFFSET + bci, true);
}
public int getShortUnchecked(int bci) {
return UNSAFE.getShortUnaligned(code.array, (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + bci, true);
return UNSAFE.getShortUnaligned(code.array, Unsafe.ARRAY_BYTE_BASE_OFFSET + bci, true);
}
// used after switch validation
public int getIntUnchecked(int bci) {
return UNSAFE.getIntUnaligned(code.array, (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + bci, true);
return UNSAFE.getIntUnaligned(code.array, Unsafe.ARRAY_BYTE_BASE_OFFSET + bci, true);
}
// non-wide branches

View file

@ -93,7 +93,7 @@ abstract sealed class HeapMemorySegmentImpl extends AbstractMemorySegmentImpl {
throw new UnsupportedOperationException("Not an address to an heap-allocated byte array");
}
JavaNioAccess nioAccess = SharedSecrets.getJavaNioAccess();
return nioAccess.newHeapByteBuffer(baseByte, (int)offset - Utils.BaseAndScale.BYTE.base(), (int) byteSize(), null);
return nioAccess.newHeapByteBuffer(baseByte, (int)(offset - Utils.BaseAndScale.BYTE.base()), (int) byteSize(), null);
}
// factories

View file

@ -298,7 +298,7 @@ public final class Utils {
return "0x" + Long.toHexString(value);
}
public record BaseAndScale(int base, long scale) {
public record BaseAndScale(long base, long scale) {
public static final BaseAndScale BYTE =
new BaseAndScale(Unsafe.ARRAY_BYTE_BASE_OFFSET, Unsafe.ARRAY_BYTE_INDEX_SCALE);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2025, 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
@ -1043,8 +1043,11 @@ public final class Unsafe {
* This constant differs from all results that will ever be returned from
* {@link #staticFieldOffset}, {@link #objectFieldOffset},
* or {@link #arrayBaseOffset}.
* <p>
* The static type is @code long} to emphasize that long arithmetic should
* always be used for offset calculations to avoid overflows.
*/
public static final int INVALID_FIELD_OFFSET = -1;
public static final long INVALID_FIELD_OFFSET = -1;
/**
* Reports the location of a given field in the storage allocation of its
@ -1172,11 +1175,15 @@ public final class Unsafe {
* for the same class, you may use that scale factor, together with this
* base offset, to form new offsets to access elements of arrays of the
* given class.
* <p>
* The return value is in the range of a {@code int}. The return type is
* {@code long} to emphasize that long arithmetic should always be used
* for offset calculations to avoid overflows.
*
* @see #getInt(Object, long)
* @see #putInt(Object, long, int)
*/
public int arrayBaseOffset(Class<?> arrayClass) {
public long arrayBaseOffset(Class<?> arrayClass) {
if (arrayClass == null) {
throw new NullPointerException();
}
@ -1186,39 +1193,39 @@ public final class Unsafe {
/** The value of {@code arrayBaseOffset(boolean[].class)} */
public static final int ARRAY_BOOLEAN_BASE_OFFSET
public static final long ARRAY_BOOLEAN_BASE_OFFSET
= theUnsafe.arrayBaseOffset(boolean[].class);
/** The value of {@code arrayBaseOffset(byte[].class)} */
public static final int ARRAY_BYTE_BASE_OFFSET
public static final long ARRAY_BYTE_BASE_OFFSET
= theUnsafe.arrayBaseOffset(byte[].class);
/** The value of {@code arrayBaseOffset(short[].class)} */
public static final int ARRAY_SHORT_BASE_OFFSET
public static final long ARRAY_SHORT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(short[].class);
/** The value of {@code arrayBaseOffset(char[].class)} */
public static final int ARRAY_CHAR_BASE_OFFSET
public static final long ARRAY_CHAR_BASE_OFFSET
= theUnsafe.arrayBaseOffset(char[].class);
/** The value of {@code arrayBaseOffset(int[].class)} */
public static final int ARRAY_INT_BASE_OFFSET
public static final long ARRAY_INT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(int[].class);
/** The value of {@code arrayBaseOffset(long[].class)} */
public static final int ARRAY_LONG_BASE_OFFSET
public static final long ARRAY_LONG_BASE_OFFSET
= theUnsafe.arrayBaseOffset(long[].class);
/** The value of {@code arrayBaseOffset(float[].class)} */
public static final int ARRAY_FLOAT_BASE_OFFSET
public static final long ARRAY_FLOAT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(float[].class);
/** The value of {@code arrayBaseOffset(double[].class)} */
public static final int ARRAY_DOUBLE_BASE_OFFSET
public static final long ARRAY_DOUBLE_BASE_OFFSET
= theUnsafe.arrayBaseOffset(double[].class);
/** The value of {@code arrayBaseOffset(Object[].class)} */
public static final int ARRAY_OBJECT_BASE_OFFSET
public static final long ARRAY_OBJECT_BASE_OFFSET
= theUnsafe.arrayBaseOffset(Object[].class);
/**
@ -1227,6 +1234,9 @@ public final class Unsafe {
* will generally not work properly with accessors like {@link
* #getByte(Object, long)}, so the scale factor for such classes is reported
* as zero.
* <p>
* The computation of the actual memory offset should always use {@code
* long} arithmetic to avoid overflows.
*
* @see #arrayBaseOffset
* @see #getInt(Object, long)
@ -3840,7 +3850,7 @@ public final class Unsafe {
private native Object staticFieldBase0(Field f);
private native boolean shouldBeInitialized0(Class<?> c);
private native void ensureClassInitialized0(Class<?> c);
private native int arrayBaseOffset0(Class<?> arrayClass);
private native int arrayBaseOffset0(Class<?> arrayClass); // public version returns long to promote correct arithmetic
private native int arrayIndexScale0(Class<?> arrayClass);
private native int getLoadAverage0(double[] loadavg, int nelems);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -457,8 +457,8 @@ public class ArraysSupport {
if (length > 7) {
if (a[aFromIndex] != b[bFromIndex])
return 0;
int aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex;
int bOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + bFromIndex;
long aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex;
long bOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + bFromIndex;
i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -550,8 +550,8 @@ public class ArraysSupport {
if (length > 7) {
if (a[aFromIndex] != b[bFromIndex])
return 0;
int aOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + aFromIndex;
int bOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + bFromIndex;
long aOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + aFromIndex;
long bOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + bFromIndex;
i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -599,8 +599,8 @@ public class ArraysSupport {
if (length > 3) {
if (a[aFromIndex] != b[bFromIndex])
return 0;
int aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
int bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
long aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
long bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE);
i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -648,8 +648,8 @@ public class ArraysSupport {
if (length > 3) {
if (a[aFromIndex] != b[bFromIndex])
return 0;
int aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
int bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
long aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
long bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE);
i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -697,8 +697,8 @@ public class ArraysSupport {
if (length > 1) {
if (a[aFromIndex] != b[bFromIndex])
return 0;
int aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
int bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
long aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
long bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE);
i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -729,8 +729,8 @@ public class ArraysSupport {
int i = 0;
if (length > 1) {
if (Float.floatToRawIntBits(a[aFromIndex]) == Float.floatToRawIntBits(b[bFromIndex])) {
int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
int bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
long aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
long bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE);
i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -787,8 +787,8 @@ public class ArraysSupport {
}
if (a[aFromIndex] != b[bFromIndex])
return 0;
int aOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE);
int bOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE);
long aOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE);
long bOffset = Unsafe.ARRAY_LONG_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_LONG_INDEX_SCALE);
int i = vectorizedMismatch(
a, aOffset,
b, bOffset,
@ -813,8 +813,8 @@ public class ArraysSupport {
}
int i = 0;
if (Double.doubleToRawLongBits(a[aFromIndex]) == Double.doubleToRawLongBits(b[bFromIndex])) {
int aOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
int bOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
long aOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
long bOffset = Unsafe.ARRAY_DOUBLE_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_DOUBLE_INDEX_SCALE);
i = vectorizedMismatch(
a, aOffset,
b, bOffset,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2025, 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
@ -426,7 +426,7 @@ public final class DecimalDigits {
}
private static void putCharLatin1(byte[] buf, int charPos, int c) {
UNSAFE.putByte(buf, ARRAY_BYTE_BASE_OFFSET + (long) charPos, (byte) c);
UNSAFE.putByte(buf, ARRAY_BYTE_BASE_OFFSET + charPos, (byte) c);
}
private static void putCharUTF16(byte[] buf, int charPos, int c) {