On Tue, 30 May 2023 08:31:08 GMT, SUN Guoyun <d...@openjdk.org> wrote:

> command: make test CONF=fastdebug JTREG="VM_OPTIONS=-Xcomp" 
> TEST=gc/TestAllocHumongousFragment.java
> error info: 
> 
> Caused by: java.lang.NullPointerException: Cannot invoke 
> "sun.util.locale.BaseLocale.getVariant()" because "base" is null
> at java.base/java.util.Locale.forLanguageTag(Locale.java:1802)
> at 
> java.base/sun.util.cldr.CLDRBaseLocaleDataMetaInfo.<clinit>(CLDRBaseLocaleDataMetaInfo.java:41)
> ... 24 more
> 
> Note that the test runs with -XX:ShenandoahGCHeuristics=aggressive 
> -XX:+ShenandoahOOMDuringEvacALot and SoftReferences are involved 
> (LocaleObjectCache uses SoftReferences, used by printf method called in 
> getRandomInstance(Utils.java:511)).
> 
> Maybe we have to deal with the case where the getBaseLocale() return value is 
> null. the call stack is:
> 
>       at 
> java.base/sun.util.locale.LocaleObjectCache.get(LocaleObjectCache.java:64)
>       at java.base/sun.util.locale.BaseLocale.getInstance(BaseLocale.java:169)
>       at 
> java.base/sun.util.locale.InternalLocaleBuilder.getBaseLocale(InternalLocaleBuilder.java:524)
>       at java.base/java.util.Locale.forLanguageTag(Locale.java:1874)
> 
> in LocaleObjectCache.java:64
> 
>        62             if (key == null || newVal == null) {                    
>             
>        63                 // subclass must return non-null key/value object   
>             
>        64                 return null; // run here
>        65             }

Jtreg tier1 can trigger the same error with vmoptions:"-Xcomp 
-XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive 
-XX:+ShenandoahOOMDuringEvacALot
I found the GC occurs between when the soft reference is assigned and when it 
is used.
<pre><code class="shell">
         private BaseLocale getBaseLocale() {
-            return (holder == null) ? holderRef.get() : holder;
+//            return (holder == null) ? holderRef.get() : holder;
+            if (holder == null) {
+              System.out.println("getBaseLocale this=" + this + "  
SoftReference=" + holderRef.get()); // null
+              return holderRef.get();
+            } else {
+              System.out.println("getBaseLocale return holder");
+              return holder;
+            }
         }
</code></pre>

The following modification verifies this.
<pre><code class="shell">
--- a/src/java.base/share/classes/sun/util/locale/BaseLocale.java
+++ b/src/java.base/share/classes/sun/util/locale/BaseLocale.java

@@ -257,19 +261,21 @@ public final class BaseLocale {

         private final boolean normalized;
         private final int hash;
-
+        private BaseLocale locale;    // make locale to a member variable
         private Key(String language, String script, String region,
                     String variant, boolean normalize) {
-            BaseLocale locale = new BaseLocale(language, script, region, 
variant, normalize);
+            locale = new BaseLocale(language, script, region, variant, 
normalize);
             this.normalized = normalize;
</code></pre>
But this should not be a reasonable solution. I think I should to find a better 
solution.

-------------

PR Comment: https://git.openjdk.org/jdk/pull/14211#issuecomment-1569881913

Reply via email to