8201179: Regression due loading java.nio.charset.StandardCharsets during bootstrap
authorredestad
Tue, 10 Apr 2018 16:16:34 +0200
changeset 49556 809b178407cc
parent 49555 12fe57c319e1
child 49557 7b00ac6c11ab
8201179: Regression due loading java.nio.charset.StandardCharsets during bootstrap Reviewed-by: sherman, martin
src/java.base/share/classes/java/lang/StringCoding.java
src/java.base/share/classes/java/nio/charset/Charset.java
src/java.base/share/classes/java/nio/charset/StandardCharsets.java
src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java
src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template
src/java.base/share/classes/sun/nio/cs/US_ASCII.java
src/java.base/share/classes/sun/nio/cs/UTF_8.java
--- a/src/java.base/share/classes/java/lang/StringCoding.java	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/java/lang/StringCoding.java	Tue Apr 10 16:16:34 2018 +0200
@@ -42,7 +42,6 @@
 import sun.nio.cs.HistoricallyNamedCharset;
 import sun.nio.cs.ArrayDecoder;
 import sun.nio.cs.ArrayEncoder;
-import sun.nio.cs.StandardCharsets;
 
 import static java.lang.String.LATIN1;
 import static java.lang.String.UTF16;
@@ -52,9 +51,6 @@
 import static java.lang.Character.lowSurrogate;
 import static java.lang.Character.isSupplementaryCodePoint;
 import static java.lang.StringUTF16.putChar;
-import static java.nio.charset.StandardCharsets.ISO_8859_1;
-import static java.nio.charset.StandardCharsets.US_ASCII;
-import static java.nio.charset.StandardCharsets.UTF_8;
 
 /**
  * Utility class for string encoding and decoding.
@@ -70,6 +66,10 @@
     private static final ThreadLocal<SoftReference<StringEncoder>> encoder =
         new ThreadLocal<>();
 
+    private static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
+    private static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
+    private static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
+
     private static <T> T deref(ThreadLocal<SoftReference<T>> tl) {
         SoftReference<T> sr = tl.get();
         if (sr == null)
--- a/src/java.base/share/classes/java/nio/charset/Charset.java	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/java/nio/charset/Charset.java	Tue Apr 10 16:16:34 2018 +0200
@@ -609,7 +609,7 @@
                 if (cs != null)
                     defaultCharset = cs;
                 else
-                    defaultCharset = StandardCharsets.UTF_8;
+                    defaultCharset = sun.nio.cs.UTF_8.INSTANCE;
             }
         }
         return defaultCharset;
--- a/src/java.base/share/classes/java/nio/charset/StandardCharsets.java	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/java/nio/charset/StandardCharsets.java	Tue Apr 10 16:16:34 2018 +0200
@@ -34,22 +34,28 @@
  */
 public final class StandardCharsets {
 
+    // To avoid accidental eager initialization of often unused Charsets
+    // from happening while the VM is booting up, which may delay
+    // initialization of VM components, we should generally avoid depending
+    // on this class from elsewhere in java.base.
+
     private StandardCharsets() {
         throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
     }
+
     /**
      * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
      * Unicode character set
      */
-    public static final Charset US_ASCII = new sun.nio.cs.US_ASCII();
+    public static final Charset US_ASCII = sun.nio.cs.US_ASCII.INSTANCE;
     /**
      * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
      */
-    public static final Charset ISO_8859_1 = new sun.nio.cs.ISO_8859_1();
+    public static final Charset ISO_8859_1 = sun.nio.cs.ISO_8859_1.INSTANCE;
     /**
      * Eight-bit UCS Transformation Format
      */
-    public static final Charset UTF_8 = new sun.nio.cs.UTF_8();
+    public static final Charset UTF_8 = sun.nio.cs.UTF_8.INSTANCE;
     /**
      * Sixteen-bit UCS Transformation Format, big-endian byte order
      */
--- a/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/sun/nio/cs/ISO_8859_1.java	Tue Apr 10 16:16:34 2018 +0200
@@ -39,6 +39,8 @@
     extends Charset
     implements HistoricallyNamedCharset
 {
+    public static final ISO_8859_1 INSTANCE = new ISO_8859_1();
+
     public ISO_8859_1() {
         super("ISO-8859-1", StandardCharsets.aliases_ISO_8859_1());
     }
--- a/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/sun/nio/cs/StandardCharsets.java.template	Tue Apr 10 16:16:34 2018 +0200
@@ -83,9 +83,9 @@
         Map<String,Charset> map = cache;
         if (map == null) {
             map = new Cache();
-            map.put("utf-8", java.nio.charset.StandardCharsets.UTF_8);
-            map.put("iso-8859-1", java.nio.charset.StandardCharsets.ISO_8859_1);
-            map.put("us-ascii", java.nio.charset.StandardCharsets.US_ASCII);
+            map.put("utf-8", UTF_8.INSTANCE);
+            map.put("iso-8859-1", ISO_8859_1.INSTANCE);
+            map.put("us-ascii", US_ASCII.INSTANCE);
             map.put("utf-16", java.nio.charset.StandardCharsets.UTF_16);
             map.put("utf-16be", java.nio.charset.StandardCharsets.UTF_16BE);
             map.put("utf-16le", java.nio.charset.StandardCharsets.UTF_16LE);
@@ -122,15 +122,19 @@
     private Charset lookup(String charsetName) {
         init();
 
-        // By checking these built-ins we can avoid initializing Aliases and
-        // Classes eagerly during bootstrap
+        // By checking these built-ins we can avoid initializing Aliases,
+        // Classes and Cache eagerly during bootstrap.
+        //
+        // Initialization of java.nio.charset.StandardCharsets should be
+        // avoided here to minimize time spent in System.initPhase1, as it
+        // may delay initialization of performance critical VM subsystems.
         String csn;
         if (charsetName.equals("UTF-8")) {
-            return java.nio.charset.StandardCharsets.UTF_8;
+            return UTF_8.INSTANCE;
         } else if (charsetName.equals("US-ASCII")) {
-            return java.nio.charset.StandardCharsets.US_ASCII;
+            return US_ASCII.INSTANCE;
         } else if (charsetName.equals("ISO-8859-1")) {
-            return java.nio.charset.StandardCharsets.ISO_8859_1;
+            return ISO_8859_1.INSTANCE;
         } else {
             csn = canonicalize(toLower(charsetName));
         }
--- a/src/java.base/share/classes/sun/nio/cs/US_ASCII.java	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/sun/nio/cs/US_ASCII.java	Tue Apr 10 16:16:34 2018 +0200
@@ -36,6 +36,8 @@
     extends Charset
     implements HistoricallyNamedCharset
 {
+    public static final US_ASCII INSTANCE = new US_ASCII();
+
     public US_ASCII() {
         super("US-ASCII", StandardCharsets.aliases_US_ASCII());
     }
--- a/src/java.base/share/classes/sun/nio/cs/UTF_8.java	Tue Apr 10 11:02:09 2018 +0800
+++ b/src/java.base/share/classes/sun/nio/cs/UTF_8.java	Tue Apr 10 16:16:34 2018 +0200
@@ -55,6 +55,9 @@
  */
 
 public final class UTF_8 extends Unicode {
+
+    public static final UTF_8 INSTANCE = new UTF_8();
+
     public UTF_8() {
         super("UTF-8", StandardCharsets.aliases_UTF_8());
     }