6838776: Defer initialization of static fields in java.math.BigInteger
authordarcy
Tue, 06 Sep 2011 06:17:52 -0700
changeset 10431 448fc54a8e23
parent 10430 f338d4485f5c
child 10432 ef33e56c55a9
6838776: Defer initialization of static fields in java.math.BigInteger Reviewed-by: mduigou, mduigou
jdk/src/share/classes/java/math/BigDecimal.java
jdk/src/share/classes/java/math/BigInteger.java
--- a/jdk/src/share/classes/java/math/BigDecimal.java	Mon Sep 05 08:04:04 2011 -0700
+++ b/jdk/src/share/classes/java/math/BigDecimal.java	Tue Sep 06 06:17:52 2011 -0700
@@ -3715,26 +3715,28 @@
         }
     }
 
-    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
-    private static final long intCompactOffset;
-    private static final long intValOffset;
-    static {
-        try {
-            intCompactOffset = unsafe.objectFieldOffset
-                (BigDecimal.class.getDeclaredField("intCompact"));
-            intValOffset = unsafe.objectFieldOffset
-                (BigDecimal.class.getDeclaredField("intVal"));
-        } catch (Exception ex) {
-            throw new Error(ex);
+    private static class UnsafeHolder {
+        private static final sun.misc.Unsafe unsafe;
+        private static final long intCompactOffset;
+        private static final long intValOffset;
+        static {
+            try {
+                unsafe = sun.misc.Unsafe.getUnsafe();
+                intCompactOffset = unsafe.objectFieldOffset
+                    (BigDecimal.class.getDeclaredField("intCompact"));
+                intValOffset = unsafe.objectFieldOffset
+                    (BigDecimal.class.getDeclaredField("intVal"));
+            } catch (Exception ex) {
+                throw new ExceptionInInitializerError(ex);
+            }
         }
-    }
-
-    private void setIntCompactVolatile(long val) {
-        unsafe.putLongVolatile(this, intCompactOffset, val);
-    }
-
-    private void setIntValVolatile(BigInteger val) {
-        unsafe.putObjectVolatile(this, intValOffset, val);
+        static void setIntCompactVolatile(BigDecimal bd, long val) {
+            unsafe.putLongVolatile(bd, intCompactOffset, val);
+        }
+
+        static void setIntValVolatile(BigDecimal bd, BigInteger val) {
+            unsafe.putObjectVolatile(bd, intValOffset, val);
+        }
     }
 
     /**
@@ -3753,7 +3755,7 @@
             throw new java.io.StreamCorruptedException(message);
         // [all values of scale are now allowed]
         }
-        setIntCompactVolatile(compactValFor(intVal));
+        UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal));
     }
 
    /**
@@ -3765,7 +3767,7 @@
        throws java.io.IOException {
        // Must inflate to maintain compatible serial form.
        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.
        s.defaultWriteObject();
    }
--- a/jdk/src/share/classes/java/math/BigInteger.java	Mon Sep 05 08:04:04 2011 -0700
+++ b/jdk/src/share/classes/java/math/BigInteger.java	Tue Sep 06 06:17:52 2011 -0700
@@ -3303,25 +3303,35 @@
         }
 
         // Commit final fields via Unsafe
-        unsafe.putIntVolatile(this, signumOffset, sign);
+        UnsafeHolder.putSign(this, sign);
 
         // Calculate mag field from magnitude and discard magnitude
-        unsafe.putObjectVolatile(this, magOffset,
-                                 stripLeadingZeroBytes(magnitude));
+        UnsafeHolder.putMag(this, stripLeadingZeroBytes(magnitude));
     }
 
     // Support for resetting final fields while deserializing
-    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
-    private static final long signumOffset;
-    private static final long magOffset;
-    static {
-        try {
-            signumOffset = unsafe.objectFieldOffset
-                (BigInteger.class.getDeclaredField("signum"));
-            magOffset = unsafe.objectFieldOffset
-                (BigInteger.class.getDeclaredField("mag"));
-        } catch (Exception ex) {
-            throw new Error(ex);
+    private static class UnsafeHolder {
+        private static final sun.misc.Unsafe unsafe;
+        private static final long signumOffset;
+        private static final long magOffset;
+        static {
+            try {
+                unsafe = sun.misc.Unsafe.getUnsafe();
+                signumOffset = unsafe.objectFieldOffset
+                    (BigInteger.class.getDeclaredField("signum"));
+                magOffset = unsafe.objectFieldOffset
+                    (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);
         }
     }