changeset 18801:95249d5e794f

Only embed boxed primitives when the box is cached by the JDK Contributed-by: Igor Veresov <igor.veresov@oracle.com>
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Thu, 08 Jan 2015 17:59:19 -0800
parents 650934ca7157
children 71e372cae32e
files graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java
diffstat 2 files changed, 31 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java	Thu Jan 08 17:56:37 2015 -0800
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java	Thu Jan 08 17:59:19 2015 -0800
@@ -75,7 +75,7 @@
         }
 
         assertEquals(Long.valueOf(42), snippetReflection.asObject(Long.class, constantReflection.boxPrimitive(JavaConstant.forLong(42))));
-        assertEquals(Integer.valueOf(666), snippetReflection.asObject(Integer.class, constantReflection.boxPrimitive(JavaConstant.forInt(666))));
+        assertEquals(Integer.valueOf(66), snippetReflection.asObject(Integer.class, constantReflection.boxPrimitive(JavaConstant.forInt(66))));
         assertEquals(Byte.valueOf((byte) 123), snippetReflection.asObject(Byte.class, constantReflection.boxPrimitive(JavaConstant.forByte((byte) 123))));
         assertSame(Boolean.TRUE, snippetReflection.asObject(Boolean.class, constantReflection.boxPrimitive(JavaConstant.forBoolean(true))));
 
@@ -93,7 +93,7 @@
         }
 
         assertEquals(JavaConstant.forLong(42), constantReflection.unboxPrimitive(snippetReflection.forObject(Long.valueOf(42))));
-        assertEquals(JavaConstant.forInt(666), constantReflection.unboxPrimitive(snippetReflection.forObject(Integer.valueOf(666))));
+        assertEquals(JavaConstant.forInt(66), constantReflection.unboxPrimitive(snippetReflection.forObject(Integer.valueOf(66))));
         assertEquals(JavaConstant.forByte((byte) 123), constantReflection.unboxPrimitive(snippetReflection.forObject(Byte.valueOf((byte) 123))));
         assertSame(JavaConstant.forBoolean(true), constantReflection.unboxPrimitive(snippetReflection.forObject(Boolean.TRUE)));
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Thu Jan 08 17:56:37 2015 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Thu Jan 08 17:59:19 2015 -0800
@@ -120,9 +120,37 @@
         }
     }
 
+    /**
+     * Check if the constant is a boxed value that is guaranteed to be cached by the platform.
+     * Otherwise the generated code might be the only reference to the boxed value and since object
+     * references from nmethods are weak this can cause GC problems.
+     *
+     * @param source
+     * @return true if the box is cached
+     */
+    private static boolean isBoxCached(JavaConstant source) {
+        switch (source.getKind()) {
+            case Boolean:
+                return true;
+            case Char:
+                return source.asInt() <= 127;
+            case Byte:
+            case Short:
+            case Int:
+                return source.asInt() >= -128 && source.asInt() <= 127;
+            case Long:
+                return source.asLong() >= -128 && source.asLong() <= 127;
+            case Float:
+            case Double:
+                return false;
+            default:
+                throw new IllegalArgumentException("unexpected kind " + source.getKind());
+        }
+    }
+
     @Override
     public JavaConstant boxPrimitive(JavaConstant source) {
-        if (!source.getKind().isPrimitive()) {
+        if (!source.getKind().isPrimitive() || !isBoxCached(source)) {
             return null;
         }
         return HotSpotObjectConstantImpl.forObject(source.asBoxedPrimitive());