# HG changeset patch # User Tom Rodriguez # Date 1420768759 28800 # Node ID 95249d5e794f46c0c03d942080392e6c8681446c # Parent 650934ca71578571600d2932171ba0dc8813bf9d Only embed boxed primitives when the box is cached by the JDK Contributed-by: Igor Veresov diff -r 650934ca7157 -r 95249d5e794f graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestConstantReflectionProvider.java --- 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))); diff -r 650934ca7157 -r 95249d5e794f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- 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());