提交 28916744 编写于 作者: D darcy

6838776: Defer initialization of static fields in java.math.BigInteger

Reviewed-by: mduigou, mduigou
上级 ffa2ff39
...@@ -3715,26 +3715,28 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> { ...@@ -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) {
unsafe.putLongVolatile(this, intCompactOffset, val);
}
private void setIntValVolatile(BigInteger val) { static void setIntValVolatile(BigDecimal bd, BigInteger val) {
unsafe.putObjectVolatile(this, intValOffset, val); unsafe.putObjectVolatile(bd, intValOffset, val);
}
} }
/** /**
...@@ -3753,7 +3755,7 @@ public class BigDecimal extends Number implements Comparable<BigDecimal> { ...@@ -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> { ...@@ -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> { ...@@ -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);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册