Mercurial > hg > truffle
changeset 14050:516eeabb4c62
avoid deadlock in clinit of HotSpotResolvedJavaField
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Tue, 04 Mar 2014 16:12:18 -0800 |
parents | 6b8e10e585df |
children | e85575f63b60 |
files | graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java |
diffstat | 1 files changed, 34 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- 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<ResolvedJavaField> 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<ResolvedJavaField> 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;";