< prev index next >

src/java.base/share/classes/sun/util/locale/BaseLocale.java

Print this page
rev 54380 : 8221701: Archive constant BaseLocales
Reviewed-by: naoto

@@ -30,18 +30,68 @@
  *******************************************************************************
  */
 
 package sun.util.locale;
 
+import jdk.internal.misc.VM;
+import jdk.internal.vm.annotation.Stable;
+
 import java.lang.ref.SoftReference;
 import java.util.StringJoiner;
 
 public final class BaseLocale {
 
-    public static final String SEP = "_";
+    public static @Stable BaseLocale[] constantBaseLocales;
+    public static final byte ENGLISH = 0,
+            FRENCH = 1,
+            GERMAN = 2,
+            ITALIAN = 3,
+            JAPANESE = 4,
+            KOREAN = 5,
+            CHINESE = 6,
+            SIMPLIFIED_CHINESE = 7,
+            TRADITIONAL_CHINESE = 8,
+            FRANCE = 9,
+            GERMANY = 10,
+            ITALY = 11,
+            JAPAN = 12,
+            KOREA = 13,
+            UK = 14,
+            US = 15,
+            CANADA = 16,
+            CANADA_FRENCH = 17,
+            ROOT = 18,
+            NUM_CONSTANTS = 19;
+    static {
+        VM.initializeFromArchive(BaseLocale.class);
+        BaseLocale[] baseLocales = constantBaseLocales;
+        if (baseLocales == null) {
+            baseLocales = new BaseLocale[NUM_CONSTANTS];
+            baseLocales[ENGLISH] = createInstance("en", "");
+            baseLocales[FRENCH] = createInstance("fr", "");
+            baseLocales[GERMAN] = createInstance("de", "");
+            baseLocales[ITALIAN] = createInstance("it", "");
+            baseLocales[JAPANESE] = createInstance("ja", "");
+            baseLocales[KOREAN] = createInstance("ko", "");
+            baseLocales[CHINESE] = createInstance("zh", "");
+            baseLocales[SIMPLIFIED_CHINESE] = createInstance("zh", "CN");
+            baseLocales[TRADITIONAL_CHINESE] = createInstance("zh", "TW");
+            baseLocales[FRANCE] = createInstance("fr", "FR");
+            baseLocales[GERMANY] = createInstance("de", "DE");
+            baseLocales[ITALY] = createInstance("it", "IT");
+            baseLocales[JAPAN] = createInstance("ja", "JP");
+            baseLocales[KOREA] = createInstance("ko", "KR");
+            baseLocales[UK] = createInstance("en", "GB");
+            baseLocales[US] = createInstance("en", "US");
+            baseLocales[CANADA] = createInstance("en", "CA");
+            baseLocales[CANADA_FRENCH] = createInstance("fr", "CA");
+            baseLocales[ROOT] = createInstance("", "");
+            constantBaseLocales = baseLocales;
+        }
+    }
 
-    private static final Cache CACHE = new Cache();
+    public static final String SEP = "_";
 
     private final String language;
     private final String script;
     private final String region;
     private final String variant;

@@ -65,32 +115,57 @@
         }
     }
 
     // Called for creating the Locale.* constants. No argument
     // validation is performed.
-    public static BaseLocale createInstance(String language, String region) {
-        BaseLocale base = new BaseLocale(language, "", region, "", false);
-        CACHE.put(new Key(base), base);
-        return base;
+    private static BaseLocale createInstance(String language, String region) {
+        return new BaseLocale(language, "", region, "", false);
     }
 
     public static BaseLocale getInstance(String language, String script,
                                          String region, String variant) {
+
+        if (script == null) {
+            script = "";
+        }
+        if (region == null) {
+            region = "";
+        }
+        if (language == null) {
+            language = null;
+        }
+        if (variant == null) {
+            variant = "";
+        }
+
+        // Non-allocating for most uses
+        language = LocaleUtils.toLowerString(language);
+        region = LocaleUtils.toUpperString(region);
+
+        // Check for constant base locales first
+        if (script.isEmpty() && variant.isEmpty()) {
+            for (BaseLocale baseLocale : constantBaseLocales) {
+                if (baseLocale.getLanguage().equals(language)
+                        && baseLocale.getRegion().equals(region)) {
+                    return baseLocale;
+                }
+            }
+        }
+
         // JDK uses deprecated ISO639.1 language codes for he, yi and id
-        if (language != null) {
-            if (LocaleUtils.caseIgnoreMatch(language, "he")) {
+        if (!language.isEmpty()) {
+            if (language.equals("he")) {
                 language = "iw";
-            } else if (LocaleUtils.caseIgnoreMatch(language, "yi")) {
+            } else if (language.equals("yi")) {
                 language = "ji";
-            } else if (LocaleUtils.caseIgnoreMatch(language, "id")) {
+            } else if (language.equals("id")) {
                 language = "in";
             }
         }
 
         Key key = new Key(language, script, region, variant, false);
-        BaseLocale baseLocale = CACHE.get(key);
-        return baseLocale;
+        return Cache.CACHE.get(key);
     }
 
     public String getLanguage() {
         return language;
     }

@@ -169,50 +244,12 @@
         private final BaseLocale holder;
 
         private final boolean normalized;
         private final int hash;
 
-        /**
-         * Creates a Key. language and region must be normalized
-         * (intern'ed in the proper case).
-         */
-        private Key(BaseLocale locale) {
-            this.holder = locale;
-            this.holderRef = null;
-            this.normalized = true;
-            String language = locale.getLanguage();
-            String region = locale.getRegion();
-            assert LocaleUtils.toLowerString(language).intern() == language
-                    && LocaleUtils.toUpperString(region).intern() == region
-                    && locale.getVariant() == ""
-                    && locale.getScript() == "";
-
-            int h = language.hashCode();
-            if (region != "") {
-                int len = region.length();
-                for (int i = 0; i < len; i++) {
-                    h = 31 * h + LocaleUtils.toLower(region.charAt(i));
-                }
-            }
-            hash = h;
-        }
-
         private Key(String language, String script, String region,
                     String variant, boolean normalize) {
-            if (language == null) {
-                language = "";
-            }
-            if (script == null) {
-                script = "";
-            }
-            if (region == null) {
-                region = "";
-            }
-            if (variant == null) {
-                variant = "";
-            }
-
             BaseLocale locale = new BaseLocale(language, script, region, variant, normalize);
             this.normalized = normalize;
             if (normalized) {
                 this.holderRef = new SoftReference<>(locale);
                 this.holder = null;

@@ -289,10 +326,12 @@
         }
     }
 
     private static class Cache extends LocaleObjectCache<Key, BaseLocale> {
 
+        private static final Cache CACHE = new Cache();
+
         public Cache() {
         }
 
         @Override
         protected Key normalizeKey(Key key) {
< prev index next >