changeset 10066:295ef03139f4

HotSpotResolvedJavaField: be more precise about fields that are not embeddable (GRAAL-290)
author Bernhard Urban <bernhard.urban@jku.at>
date Sun, 16 Jun 2013 23:55:22 +0200
parents 5ba3763d6986
children 0d378ea2b822
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java
diffstat 1 files changed, 37 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Sun Jun 16 23:55:22 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Sun Jun 16 23:55:22 2013 +0200
@@ -29,6 +29,7 @@
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
+import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
@@ -106,20 +107,45 @@
         return false;
     }
 
-    private static final String SystemClassName = MetaUtil.toInternalName(System.class.getName());
-    private static final String IntegerCacheClassName = "Ljava/lang/Integer$IntegerCache;";
-    private static final String LongCacheClassName = "Ljava/lang/Long$LongCache;";
-    private static final String BooleanCacheName = MetaUtil.toInternalName(Boolean.class.getName());
-    private static final String ThrowableClassName = MetaUtil.toInternalName(Throwable.class.getName());
+    private static final Set<ResolvedJavaField> notEmbeddable = new HashSet<>();
+
+    private static void addResolvedToSet(Field field) {
+        HotSpotRuntime runtime = graalRuntime().getRuntime();
+        notEmbeddable.add(runtime.lookupJavaField(field));
+    }
+
+    static {
+        try {
+            addResolvedToSet(Boolean.class.getDeclaredField("TRUE"));
+            addResolvedToSet(Boolean.class.getDeclaredField("FALSE"));
+
+            Class<?> integerCacheClass = Integer.class.getDeclaredClasses()[0];
+            assert "java.lang.Integer$IntegerCache".equals(integerCacheClass.getName());
+            addResolvedToSet(integerCacheClass.getDeclaredField("cache"));
 
-    private boolean isConstantCache() {
-        if (AOTCompilation.getValue()) {
-            String n = holder.getName();
-            return n.equals(IntegerCacheClassName) || n.equals(LongCacheClassName) || n.equals(BooleanCacheName) || n.equals(ThrowableClassName);
+            Class<?> longCacheClass = Long.class.getDeclaredClasses()[0];
+            assert "java.lang.Long$LongCache".equals(longCacheClass.getName());
+            addResolvedToSet(longCacheClass.getDeclaredField("cache"));
+
+            addResolvedToSet(Throwable.class.getDeclaredField("UNASSIGNED_STACK"));
+            addResolvedToSet(Throwable.class.getDeclaredField("SUPPRESSED_SENTINEL"));
+        } catch (SecurityException | NoSuchFieldException e) {
+            throw new GraalInternalError(e);
         }
-        return false;
     }
 
+    /**
+     * in AOT mode, some fields should never be embedded even for snippets/replacements.
+     */
+    private boolean isEmbeddable() {
+        if (AOTCompilation.getValue() && notEmbeddable.contains(this)) {
+            return false;
+        }
+        return true;
+    }
+
+    private static final String SystemClassName = MetaUtil.toInternalName(System.class.getName());
+
     @Override
     public Constant readConstantValue(Constant receiver) {
         assert !AOTCompilation.getValue() || isCalledForSnippets();
@@ -127,7 +153,7 @@
         if (receiver == null) {
             assert Modifier.isStatic(flags);
             if (constant == null) {
-                if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && !isConstantCache()) {
+                if (holder.isInitialized() && !holder.getName().equals(SystemClassName) && isEmbeddable()) {
                     if (Modifier.isFinal(getModifiers())) {
                         constant = readValue(receiver);
                     }