# HG changeset patch # User Tom Rodriguez # Date 1393978338 28800 # Node ID 516eeabb4c625ff19054f0c1768fd0e9af2a14b6 # Parent 6b8e10e585df9bea473ff3da6e24ac91c84be189 avoid deadlock in clinit of HotSpotResolvedJavaField diff -r 6b8e10e585df -r 516eeabb4c62 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Mon Mar 03 20:40:23 2014 -0800 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java Tue Mar 04 16:12:18 2014 -0800 @@ -119,42 +119,47 @@ return false; } - private static final List notEmbeddable = new ArrayList<>(); + static class Embeddable { - private static void addResolvedToSet(Field field) { - MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); - notEmbeddable.add(metaAccess.lookupJavaField(field)); - } + // Return true if it's ok to embed the value of a field. + public static boolean test(HotSpotResolvedJavaField field) { + return !ImmutableCode.getValue() || !fields.contains(field); + } - static { - try { - addResolvedToSet(Boolean.class.getDeclaredField("TRUE")); - addResolvedToSet(Boolean.class.getDeclaredField("FALSE")); + private static final List fields = new ArrayList<>(); + static { + // Make this initialization lazy so that we don't create cycles between clinit and other + // locks that could lead to deadlock. + try { + MetaAccessProvider metaAccess = runtime().getHostProviders().getMetaAccess(); + fields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("TRUE"))); + fields.add(metaAccess.lookupJavaField(Boolean.class.getDeclaredField("FALSE"))); - Class characterCacheClass = Character.class.getDeclaredClasses()[0]; - assert "java.lang.Character$CharacterCache".equals(characterCacheClass.getName()); - addResolvedToSet(characterCacheClass.getDeclaredField("cache")); + Class characterCacheClass = Character.class.getDeclaredClasses()[0]; + assert "java.lang.Character$CharacterCache".equals(characterCacheClass.getName()); + fields.add(metaAccess.lookupJavaField(characterCacheClass.getDeclaredField("cache"))); - Class byteCacheClass = Byte.class.getDeclaredClasses()[0]; - assert "java.lang.Byte$ByteCache".equals(byteCacheClass.getName()); - addResolvedToSet(byteCacheClass.getDeclaredField("cache")); + Class byteCacheClass = Byte.class.getDeclaredClasses()[0]; + assert "java.lang.Byte$ByteCache".equals(byteCacheClass.getName()); + fields.add(metaAccess.lookupJavaField(byteCacheClass.getDeclaredField("cache"))); - Class shortCacheClass = Short.class.getDeclaredClasses()[0]; - assert "java.lang.Short$ShortCache".equals(shortCacheClass.getName()); - addResolvedToSet(shortCacheClass.getDeclaredField("cache")); + Class shortCacheClass = Short.class.getDeclaredClasses()[0]; + assert "java.lang.Short$ShortCache".equals(shortCacheClass.getName()); + fields.add(metaAccess.lookupJavaField(shortCacheClass.getDeclaredField("cache"))); - Class integerCacheClass = Integer.class.getDeclaredClasses()[0]; - assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName()); - addResolvedToSet(integerCacheClass.getDeclaredField("cache")); + Class integerCacheClass = Integer.class.getDeclaredClasses()[0]; + assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName()); + fields.add(metaAccess.lookupJavaField(integerCacheClass.getDeclaredField("cache"))); - Class longCacheClass = Long.class.getDeclaredClasses()[0]; - assert "java.lang.Long$LongCache".equals(longCacheClass.getName()); - addResolvedToSet(longCacheClass.getDeclaredField("cache")); + Class longCacheClass = Long.class.getDeclaredClasses()[0]; + assert "java.lang.Long$LongCache".equals(longCacheClass.getName()); + fields.add(metaAccess.lookupJavaField(longCacheClass.getDeclaredField("cache"))); - addResolvedToSet(Throwable.class.getDeclaredField("UNASSIGNED_STACK")); - addResolvedToSet(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL")); - } catch (SecurityException | NoSuchFieldException e) { - throw new GraalInternalError(e); + fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("UNASSIGNED_STACK"))); + fields.add(metaAccess.lookupJavaField(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"))); + } catch (SecurityException | NoSuchFieldException e) { + throw new GraalInternalError(e); + } } } @@ -162,10 +167,7 @@ * in AOT mode, some fields should never be embedded even for snippets/replacements. */ private boolean isEmbeddable() { - if (ImmutableCode.getValue() && notEmbeddable.contains(this)) { - return false; - } - return true; + return Embeddable.test(this); } private static final String SystemClassName = "Ljava/lang/System;";