RFR (S) 8131782: C1 Class.cast optimization breaks when Class is loaded from static final

John Rose john.r.rose at oracle.com
Mon Jul 20 21:14:59 UTC 2015


On Jul 20, 2015, at 6:52 AM, Aleksey Shipilev <aleksey.shipilev at oracle.com> wrote:
> 
> Hi,
> 
> On the road from Unsafe to VarHandles lies a small deficiency in C1
> Class.cast/isInstance optimization: the canonicalizer folds constant
> class perfectly when it is coming from "inlined" constant, but not from
> static final, because the constant "shapes" are different:
>  https://bugs.openjdk.java.net/browse/JDK-8131782
> 
> And here is the fix:
>  http://cr.openjdk.java.net/~shade/8131782/webrev.01/
> 
> (There is another ClassConstant shape, which is, AFAIU, the constant
> "receiver" class as discovered within the static method. It does not
> seem to appear in current java.lang.Class, and there seems to be no way
> for users to stumble upon such a pattern. Which also means I can't do a
> targeted test for it.)
> 
> Testing:
>  * JPRT -testset hotspot on all open platforms;
>  * Targeted benchmarks (see JIRA ticket)

I suggest a deeper fix, to the factory that produces the oddly formatted constant.
That may help with other, similar constant folding problems.

— John

diff --git a/src/share/vm/c1/c1_ValueType.cpp b/src/share/vm/c1/c1_ValueType.cpp
--- a/src/share/vm/c1/c1_ValueType.cpp
+++ b/src/share/vm/c1/c1_ValueType.cpp
@@ -153,7 +153,19 @@
     case T_FLOAT  : return new FloatConstant (value.as_float ());
     case T_DOUBLE : return new DoubleConstant(value.as_double());
     case T_ARRAY  : // fall through (ciConstant doesn't have an array accessor)
-    case T_OBJECT : return new ObjectConstant(value.as_object());
+    case T_OBJECT : {
+      // FIXME: use common code with GraphBuilder::load_constant
+      ciObject* obj = value.as_object();
+      if (obj->is_null_object())
+        return objectNull;
+      if (obj->is_loaded()) {
+        if (obj->is_array())
+          return new ArrayConstant(obj->as_array());
+        else if (obj->is_instance())
+          return new InstanceConstant(obj->as_instance());
+      }
+      return new ObjectConstant(obj);
+    }
   }
   ShouldNotReachHere();
   return illegalType;



More information about the hotspot-compiler-dev mailing list