6838776: Defer initialization of static fields in java.math.BigInteger
Reviewed-by: mduigou, mduigou
This commit is contained in:
parent
59a4dbb95a
commit
2a22d4691a
@ -3715,26 +3715,28 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
private static class UnsafeHolder {
|
||||||
private static final long intCompactOffset;
|
private static final sun.misc.Unsafe unsafe;
|
||||||
private static final long intValOffset;
|
private static final long intCompactOffset;
|
||||||
static {
|
private static final long intValOffset;
|
||||||
try {
|
static {
|
||||||
intCompactOffset = unsafe.objectFieldOffset
|
try {
|
||||||
(BigDecimal.class.getDeclaredField("intCompact"));
|
unsafe = sun.misc.Unsafe.getUnsafe();
|
||||||
intValOffset = unsafe.objectFieldOffset
|
intCompactOffset = unsafe.objectFieldOffset
|
||||||
(BigDecimal.class.getDeclaredField("intVal"));
|
(BigDecimal.class.getDeclaredField("intCompact"));
|
||||||
} catch (Exception ex) {
|
intValOffset = unsafe.objectFieldOffset
|
||||||
throw new Error(ex);
|
(BigDecimal.class.getDeclaredField("intVal"));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new ExceptionInInitializerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void setIntCompactVolatile(BigDecimal bd, long val) {
|
||||||
|
unsafe.putLongVolatile(bd, intCompactOffset, val);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void setIntCompactVolatile(long val) {
|
static void setIntValVolatile(BigDecimal bd, BigInteger val) {
|
||||||
unsafe.putLongVolatile(this, intCompactOffset, val);
|
unsafe.putObjectVolatile(bd, intValOffset, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setIntValVolatile(BigInteger val) {
|
|
||||||
unsafe.putObjectVolatile(this, intValOffset, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3753,7 +3755,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
throw new java.io.StreamCorruptedException(message);
|
throw new java.io.StreamCorruptedException(message);
|
||||||
// [all values of scale are now allowed]
|
// [all values of scale are now allowed]
|
||||||
}
|
}
|
||||||
setIntCompactVolatile(compactValFor(intVal));
|
UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3765,7 +3767,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> {
|
|||||||
throws java.io.IOException {
|
throws java.io.IOException {
|
||||||
// Must inflate to maintain compatible serial form.
|
// Must inflate to maintain compatible serial form.
|
||||||
if (this.intVal == null)
|
if (this.intVal == null)
|
||||||
this.setIntValVolatile(BigInteger.valueOf(this.intCompact));
|
UnsafeHolder.setIntValVolatile(this, BigInteger.valueOf(this.intCompact));
|
||||||
// Could reset intVal back to null if it has to be set.
|
// Could reset intVal back to null if it has to be set.
|
||||||
s.defaultWriteObject();
|
s.defaultWriteObject();
|
||||||
}
|
}
|
||||||
|
@ -3303,25 +3303,35 @@ public class BigInteger extends Number implements Comparable<BigInteger> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Commit final fields via Unsafe
|
// Commit final fields via Unsafe
|
||||||
unsafe.putIntVolatile(this, signumOffset, sign);
|
UnsafeHolder.putSign(this, sign);
|
||||||
|
|
||||||
// Calculate mag field from magnitude and discard magnitude
|
// Calculate mag field from magnitude and discard magnitude
|
||||||
unsafe.putObjectVolatile(this, magOffset,
|
UnsafeHolder.putMag(this, stripLeadingZeroBytes(magnitude));
|
||||||
stripLeadingZeroBytes(magnitude));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support for resetting final fields while deserializing
|
// Support for resetting final fields while deserializing
|
||||||
private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
|
private static class UnsafeHolder {
|
||||||
private static final long signumOffset;
|
private static final sun.misc.Unsafe unsafe;
|
||||||
private static final long magOffset;
|
private static final long signumOffset;
|
||||||
static {
|
private static final long magOffset;
|
||||||
try {
|
static {
|
||||||
signumOffset = unsafe.objectFieldOffset
|
try {
|
||||||
(BigInteger.class.getDeclaredField("signum"));
|
unsafe = sun.misc.Unsafe.getUnsafe();
|
||||||
magOffset = unsafe.objectFieldOffset
|
signumOffset = unsafe.objectFieldOffset
|
||||||
(BigInteger.class.getDeclaredField("mag"));
|
(BigInteger.class.getDeclaredField("signum"));
|
||||||
} catch (Exception ex) {
|
magOffset = unsafe.objectFieldOffset
|
||||||
throw new Error(ex);
|
(BigInteger.class.getDeclaredField("mag"));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new ExceptionInInitializerError(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void putSign(BigInteger bi, int sign) {
|
||||||
|
unsafe.putIntVolatile(bi, signumOffset, sign);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void putMag(BigInteger bi, int[] magnitude) {
|
||||||
|
unsafe.putObjectVolatile(bi, magOffset, magnitude);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user