changeset 13049:ed323fd47c0f mvt

8183111: [MVT] java.lang.Class::isAssignableFrom() C2 intrinsic does not support value types Reviewed-by: roland
author thartmann
date Mon, 17 Jul 2017 13:13:15 +0200
parents ed8f8e678b03
children 314ea36f0728
files src/share/vm/opto/cfgnode.cpp src/share/vm/opto/compile.cpp src/share/vm/opto/graphKit.cpp src/share/vm/opto/library_call.cpp src/share/vm/opto/memnode.cpp src/share/vm/opto/type.cpp src/share/vm/opto/type.hpp test/compiler/valhalla/valuetypes/ValueTypeTestBench.java test/runtime/valhalla/valuetypes/DeriveValueTypeCreation.java test/runtime/valhalla/valuetypes/MVTComboTier1.java test/runtime/valhalla/valuetypes/ValueOops.java test/runtime/valhalla/valuetypes/VboxUnbox.java
diffstat 12 files changed, 124 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/cfgnode.cpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/cfgnode.cpp	Mon Jul 17 13:13:15 2017 +0200
@@ -944,15 +944,10 @@
   const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
   const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL;
   bool is_intf = false;
-  if (ttip != NULL) {
-    ciKlass* k = ttip->klass();
-    if (k->is_loaded() && k->is_interface())
-      is_intf = true;
-  }
-  if (ttkp != NULL) {
-    ciKlass* k = ttkp->klass();
-    if (k->is_loaded() && k->is_interface())
-      is_intf = true;
+  if (ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) {
+    is_intf = true;
+  } else if (ttkp != NULL && ttkp->is_loaded() && ttkp->klass()->is_interface()) {
+    is_intf = true;
   }
 
   // Default case: merge all inputs
@@ -1009,9 +1004,9 @@
     // be 'I' or 'j/l/O'.  Thus we'll pick 'j/l/O'.  If this then flows
     // into a Phi which "knows" it's an Interface type we'll have to
     // uplift the type.
-    if (!t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface()) {
+    if (!t->empty() && ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) {
       assert(ft == _type, ""); // Uplift to interface
-    } else if (!t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface()) {
+    } else if (!t->empty() && ttkp != NULL && ttkp->is_loaded() && ttkp->klass()->is_interface()) {
       assert(ft == _type, ""); // Uplift to interface
     } else {
       // We also have to handle 'evil cases' of interface- vs. class-arrays
--- a/src/share/vm/opto/compile.cpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/compile.cpp	Mon Jul 17 13:13:15 2017 +0200
@@ -1540,7 +1540,7 @@
     }
 
     ciKlass* klass = tk->klass();
-    if( klass->is_obj_array_klass() ) {
+    if (klass != NULL && klass->is_obj_array_klass()) {
       ciKlass* k = TypeAryPtr::OOPS->klass();
       if( !k || !k->is_loaded() )                  // Only fails for some -Xcomp runs
         k = TypeInstPtr::BOTTOM->klass();
@@ -2728,7 +2728,7 @@
     r->init_req(1, excp);
     mem_phi->init_req(1, out_mem);
     io_phi->init_req(1, out_io);
-      
+
     frc._visited.set(norm->_idx);
     frc._visited.set(excp->_idx);
 
@@ -4163,11 +4163,11 @@
 // (2) subklass does not overlap with superklass => always fail
 // (3) superklass has NO subtypes and we can check with a simple compare.
 int Compile::static_subtype_check(ciKlass* superk, ciKlass* subk) {
-  if (StressReflectiveCode) {
+  if (StressReflectiveCode || superk == NULL || subk == NULL) {
     return SSC_full_test;       // Let caller generate the general case.
   }
 
-  if (superk == env()->Object_klass()) {
+  if (!EnableMVT && !EnableValhalla && superk == env()->Object_klass()) {
     return SSC_always_true;     // (0) this test cannot fail
   }
 
--- a/src/share/vm/opto/graphKit.cpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/graphKit.cpp	Mon Jul 17 13:13:15 2017 +0200
@@ -2565,7 +2565,7 @@
   // types load from the super-class display table which is immutable.
   m = mem->memory_at(C->get_alias_index(gvn->type(p2)->is_ptr()));
   Node *kmem = might_be_cache ? m : C->immutable_memory();
-  Node *nkls = gvn->transform(LoadKlassNode::make(*gvn, NULL, kmem, p2, gvn->type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL));
+  Node *nkls = gvn->transform(LoadKlassNode::make(*gvn, NULL, kmem, p2, gvn->type(p2)->is_ptr(), TypeKlassPtr::BOTTOM));
 
   // Compile speed common case: ARE a subtype and we canNOT fail
   if( superklass == nkls )
@@ -2917,6 +2917,7 @@
                               Node* *failure_control) {
   kill_dead_locals();           // Benefit all the uncommon traps
   const TypeKlassPtr *tk = _gvn.type(superklass)->is_klassptr();
+  assert(tk->is_loaded(), "must be loaded");
   const Type *toop = TypeOopPtr::make_from_klass(tk->klass());
 
   // Fast cutout:  Check the case that the cast is vacuously true.
@@ -3223,6 +3224,7 @@
   const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
   if (!StressReflectiveCode && inst_klass != NULL) {
     ciKlass* klass = inst_klass->klass();
+    assert(klass != NULL, "klass should not be NULL");
     bool    xklass = inst_klass->klass_is_exact();
     if (xklass || klass->is_array_klass()) {
       jint lhelper = klass->layout_helper();
--- a/src/share/vm/opto/library_call.cpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/library_call.cpp	Mon Jul 17 13:13:15 2017 +0200
@@ -3586,7 +3586,7 @@
       phi->add_req(makecon(TypeInstPtr::make(env()->Object_klass()->java_mirror())));
     // If we fall through, it's a plain class.  Get its _super.
     p = basic_plus_adr(kls, in_bytes(Klass::super_offset()));
-    kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::OBJECT_OR_NULL));
+    kls = _gvn.transform(LoadKlassNode::make(_gvn, NULL, immutable_memory(), p, TypeRawPtr::BOTTOM, TypeKlassPtr::BOTTOM));
     null_ctl = top();
     kls = null_check_oop(kls, &null_ctl);
     if (null_ctl != top()) {
@@ -3728,7 +3728,7 @@
   record_for_igvn(region);
 
   const TypePtr* adr_type = TypeRawPtr::BOTTOM;   // memory type of loads
-  const TypeKlassPtr* kls_type = TypeKlassPtr::OBJECT_OR_NULL;
+  const TypeKlassPtr* kls_type = TypeKlassPtr::BOTTOM;
   int class_klass_offset = java_lang_Class::klass_offset_in_bytes();
 
   // First null-check both mirrors and load each mirror's klass metaobject.
--- a/src/share/vm/opto/memnode.cpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/memnode.cpp	Mon Jul 17 13:13:15 2017 +0200
@@ -1753,6 +1753,7 @@
   } else if (tp->base() == Type::KlassPtr) {
     assert( off != Type::OffsetBot ||
             // arrays can be cast to Objects
+            tp->is_klassptr()->klass() == NULL ||
             tp->is_klassptr()->klass()->is_java_lang_Object() ||
             // also allow array-loading from the primary supertype
             // array during subtype checks
@@ -1764,7 +1765,7 @@
   const TypeKlassPtr *tkls = tp->isa_klassptr();
   if (tkls != NULL && !StressReflectiveCode) {
     ciKlass* klass = tkls->klass();
-    if (klass->is_loaded() && tkls->klass_is_exact()) {
+    if (tkls->is_loaded() && tkls->klass_is_exact()) {
       // We are loading a field from a Klass metaobject whose identity
       // is known at compile time (the type is "exact" or "precise").
       // Check for fields we know are maintained as constants by the VM.
@@ -1797,7 +1798,7 @@
     // We can still check if we are loading from the primary_supers array at a
     // shallow enough depth.  Even though the klass is not exact, entries less
     // than or equal to its super depth are correct.
-    if (klass->is_loaded() ) {
+    if (tkls->is_loaded()) {
       ciType *inner = klass;
       while( inner->is_obj_array_klass() )
         inner = inner->as_obj_array_klass()->base_element_type();
@@ -2128,9 +2129,10 @@
   // Check for loading klass from an array klass
   const TypeKlassPtr *tkls = tp->isa_klassptr();
   if (tkls != NULL && !StressReflectiveCode) {
+    if (!tkls->is_loaded()) {
+      return _type;             // Bail out if not loaded
+    }
     ciKlass* klass = tkls->klass();
-    if( !klass->is_loaded() )
-      return _type;             // Bail out if not loaded
     if( klass->is_obj_array_klass() &&
         tkls->offset() == in_bytes(ObjArrayKlass::element_klass_offset())) {
       ciKlass* elem = klass->as_obj_array_klass()->element_klass();
--- a/src/share/vm/opto/type.cpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/type.cpp	Mon Jul 17 13:13:15 2017 +0200
@@ -645,6 +645,7 @@
 
   TypeKlassPtr::OBJECT = TypeKlassPtr::make(TypePtr::NotNull, current->env()->Object_klass(), Offset(0) );
   TypeKlassPtr::OBJECT_OR_NULL = TypeKlassPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), Offset(0) );
+  TypeKlassPtr::BOTTOM = (EnableValhalla | EnableMVT) ? TypeKlassPtr::make(TypePtr::BotPTR, NULL, Offset(0)) : TypeKlassPtr::OBJECT_OR_NULL;
 
   const Type **fi2c = TypeTuple::fields(2);
   fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // Method*
@@ -5248,6 +5249,7 @@
 // Not-null object klass or below
 const TypeKlassPtr *TypeKlassPtr::OBJECT;
 const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL;
+const TypeKlassPtr* TypeKlassPtr::BOTTOM;
 
 //------------------------------TypeKlassPtr-----------------------------------
 TypeKlassPtr::TypeKlassPtr( PTR ptr, ciKlass* klass, Offset offset )
@@ -5257,27 +5259,21 @@
 //------------------------------make-------------------------------------------
 // ptr to klass 'k', if Constant, or possibly to a sub-klass if not a Constant
 const TypeKlassPtr* TypeKlassPtr::make(PTR ptr, ciKlass* k, Offset offset) {
-  assert( k != NULL, "Expect a non-NULL klass");
-  assert(k->is_instance_klass() || k->is_array_klass(), "Incorrect type of klass oop");
-  TypeKlassPtr *r =
-    (TypeKlassPtr*)(new TypeKlassPtr(ptr, k, offset))->hashcons();
-
-  return r;
+  assert(k == NULL || k->is_instance_klass() || k->is_array_klass(), "Incorrect type of klass oop");
+  return (TypeKlassPtr*)(new TypeKlassPtr(ptr, k, offset))->hashcons();
 }
 
 //------------------------------eq---------------------------------------------
 // Structural equality check for Type representations
 bool TypeKlassPtr::eq( const Type *t ) const {
   const TypeKlassPtr *p = t->is_klassptr();
-  return
-    klass()->equals(p->klass()) &&
-    TypePtr::eq(p);
+  return klass() == p->klass() && TypePtr::eq(p);
 }
 
 //------------------------------hash-------------------------------------------
 // Type-specific hashing function.
 int TypeKlassPtr::hash(void) const {
-  return java_add(klass()->hash(), TypePtr::hash());
+  return java_add(klass() != NULL ? klass()->hash() : 0, TypePtr::hash());
 }
 
 //------------------------------singleton--------------------------------------
@@ -5298,7 +5294,7 @@
   const TypeKlassPtr* ktkp = kills->isa_klassptr();
 
   if (ft->empty()) {
-    if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface())
+    if (!empty() && ktkp != NULL && ktkp->is_loaded() && ktkp->klass()->is_interface())
       return kills;             // Uplift to interface
 
     return Type::TOP;           // Canonical empty value
@@ -5432,6 +5428,7 @@
 // It will be NotNull, and exact if and only if the klass type is exact.
 const TypeOopPtr* TypeKlassPtr::as_instance_type() const {
   ciKlass* k = klass();
+  assert(k != NULL, "klass should not be NULL");
   bool    xk = klass_is_exact();
   //return TypeInstPtr::make(TypePtr::NotNull, k, xk, NULL, 0);
   const TypeOopPtr* toop = TypeOopPtr::make_from_klass_raw(k);
@@ -5516,6 +5513,14 @@
     Offset  off  = meet_offset(tkls->offset());
     PTR  ptr     = meet_ptr(tkls->ptr());
 
+    if (klass() == NULL || tkls->klass() == NULL) {
+      ciKlass* k = NULL;
+      if (ptr == Constant) {
+        k = (klass() == NULL) ? tkls->klass() : klass();
+      }
+      return make(ptr, k, off);
+    }
+
     // Check for easy case; klasses are equal (and perhaps not loaded!)
     // If we have constants, then we created oops so classes are loaded
     // and we can handle the constants further down.  This case handles
@@ -5606,11 +5611,11 @@
     st->print("precise ");
   case NotNull:
     {
-      const char *name = klass()->name()->as_utf8();
-      if( name ) {
+      if (klass() != NULL) {
+        const char* name = klass()->name()->as_utf8();
         st->print("klass %s: " INTPTR_FORMAT, name, p2i(klass()));
       } else {
-        ShouldNotReachHere();
+        st->print("klass BOTTOM");
       }
     }
   case BotPTR:
--- a/src/share/vm/opto/type.hpp	Mon Jul 17 13:09:35 2017 +0200
+++ b/src/share/vm/opto/type.hpp	Mon Jul 17 13:13:15 2017 +0200
@@ -1411,15 +1411,10 @@
   bool          _klass_is_exact;
 
 public:
-  ciSymbol* name()  const { return klass()->name(); }
-
   ciKlass* klass() const { return  _klass; }
   bool klass_is_exact()    const { return _klass_is_exact; }
 
-  bool  is_loaded() const { return klass()->is_loaded(); }
-
-  // Make a generic (unclassed) pointer to metadata.
-  static const TypeKlassPtr* make(PTR ptr, Offset offset);
+  bool  is_loaded() const { return klass() != NULL && klass()->is_loaded(); }
 
   // ptr to klass 'k'
   static const TypeKlassPtr* make(ciKlass* k) { return make( TypePtr::Constant, k, Offset(0)); }
@@ -1444,6 +1439,7 @@
   // Convenience common pre-built types.
   static const TypeKlassPtr* OBJECT; // Not-null object klass or below
   static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same
+  static const TypeKlassPtr* BOTTOM;
 #ifndef PRODUCT
   virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
 #endif
--- a/test/compiler/valhalla/valuetypes/ValueTypeTestBench.java	Mon Jul 17 13:09:35 2017 +0200
+++ b/test/compiler/valhalla/valuetypes/ValueTypeTestBench.java	Mon Jul 17 13:13:15 2017 +0200
@@ -2605,6 +2605,84 @@
         Asserts.assertEQ(result, 0L);
     }
 
+    // Test correctness of the Class::isAssignableFrom intrinsic
+    @Test()
+    public boolean test94(Class<?> supercls, Class<?> subcls) {
+        return supercls.isAssignableFrom(subcls);
+    }
+
+    public void test94_verifier(boolean warmup) {
+        Asserts.assertTrue(test94(__Value.class, MyValue1.class), "test94_1 failed");
+        Asserts.assertTrue(test94(MyValue1.class, MyValue1.class), "test94_2 failed");
+        Asserts.assertTrue(test94(Object.class, java.util.ArrayList.class), "test94_3 failed");
+        Asserts.assertTrue(test94(java.util.ArrayList.class, java.util.ArrayList.class), "test94_4 failed");
+        Asserts.assertTrue(!test94(Object.class, MyValue1.class), "test94_5 failed");
+        Asserts.assertTrue(!test94(__Value.class, java.util.ArrayList.class), "test94_6 failed");
+    }
+
+    // Verify that Class::isAssignableFrom checks with statically known classes are folded
+    @Test(failOn = LOADK)
+    public boolean test95() {
+        boolean check1 = java.util.AbstractList.class.isAssignableFrom(java.util.ArrayList.class);
+        boolean check2 = MyValue1.class.isAssignableFrom(MyValue1.class);
+        boolean check3 = Object.class.isAssignableFrom(java.util.ArrayList.class);
+        boolean check4 = java.lang.__Value.class.isAssignableFrom(MyValue1.class);
+        boolean check5 = !Object.class.isAssignableFrom(MyValue1.class);
+        boolean check6 = !MyValue1.class.isAssignableFrom(Object.class);
+        return check1 && check2 && check3 && check4 && check5 && check6;
+    }
+
+    public void test95_verifier(boolean warmup) {
+        Asserts.assertTrue(test95(), "test95 failed");
+    }
+
+    // Test correctness of the Class::getSuperclass intrinsic
+    @Test()
+    public Class<?> test96(Class<?> cls) {
+        return cls.getSuperclass();
+    }
+
+    public void test96_verifier(boolean warmup) {
+        Asserts.assertTrue(test96(__Value.class) == null, "test94_1 failed");
+        Asserts.assertTrue(test96(Object.class) == null, "test94_2 failed");
+        Asserts.assertTrue(test96(MyValue1.class) == __Value.class, "test94_3 failed");
+        Asserts.assertTrue(test96(Class.class) == Object.class, "test94_4 failed");
+    }
+
+    // Verify that Class::getSuperclass checks with statically known classes are folded
+    @Test(failOn = LOADK)
+    public boolean test97() {
+        boolean check1 = __Value.class.getSuperclass() == null;
+        boolean check2 = Object.class.getSuperclass() == null;
+        boolean check3 = MyValue1.class.getSuperclass() == __Value.class;
+        boolean check4 = Class.class.getSuperclass() == Object.class;
+        return check1 && check2 && check3 && check4;
+    }
+
+    public void test97_verifier(boolean warmup) {
+        Asserts.assertTrue(test97(), "test97 failed");
+    }
+
+    // Test Class::cast intrinsic
+    @Test()
+    public Object test98(Class<?> cls, Object o) throws ClassCastException {
+        return cls.cast(o);
+    }
+
+    public void test98_verifier(boolean warmup) {
+        try {
+            test98(ValueCapableClass1.class, vcc);
+        } catch (ClassCastException e) {
+            throw new RuntimeException("test98_1 failed");
+        }
+        try {
+            test98(__Value.class, new Object());
+            throw new RuntimeException("test98_2 failed");
+        } catch (ClassCastException e) {
+            // Expected
+        }
+    }
+
     // ========== Test infrastructure ==========
 
     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
@@ -2634,6 +2712,7 @@
     private static final String ALLOCA = "(.*precise klass \\[Qcompiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_array_Java" + END;
     private static final String LOAD   = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
     private static final String LOADP  = START + "Load(P|N)" + MID + "valuetype\\*" + END;
+    private static final String LOADK  = START + "LoadK" + MID + END;
     private static final String STORE  = START + "Store(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
     private static final String STOREP = START + "Store(P|N)" + MID + "valuetype\\*" + END;
     private static final String LOOP   = START + "Loop" + MID + "" + END;
--- a/test/runtime/valhalla/valuetypes/DeriveValueTypeCreation.java	Mon Jul 17 13:09:35 2017 +0200
+++ b/test/runtime/valhalla/valuetypes/DeriveValueTypeCreation.java	Mon Jul 17 13:13:15 2017 +0200
@@ -44,9 +44,7 @@
  * @modules java.base/jdk.internal.org.objectweb.asm
  * @build runtime.valhalla.valuetypes.ValueCapableClass
  * @run main/othervm -Xint -noverify -XX:+EnableMVT runtime.valhalla.valuetypes.DeriveValueTypeCreation
- * @run main/othervm -Xcomp -noverify -XX:+EnableMVT
- *                   -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
- *                   runtime.valhalla.valuetypes.DeriveValueTypeCreation
+ * @run main/othervm -Xcomp -noverify -XX:+EnableMVT runtime.valhalla.valuetypes.DeriveValueTypeCreation
  */
 public class DeriveValueTypeCreation {
 
--- a/test/runtime/valhalla/valuetypes/MVTComboTier1.java	Mon Jul 17 13:09:35 2017 +0200
+++ b/test/runtime/valhalla/valuetypes/MVTComboTier1.java	Mon Jul 17 13:13:15 2017 +0200
@@ -38,9 +38,7 @@
  * @build jdk.test.lib.combo.ComboTestHelper
  * @run main/othervm -noverify -Xint -XX:+EnableMVT runtime.valhalla.valuetypes.MVTComboTier1 3
  * @run main/othervm -noverify -Xint -XX:+EnableMVT runtime.valhalla.valuetypes.MVTComboTier1 -reducetypes 6
- * @run main/othervm -noverify -Xcomp -XX:+EnableMVT
-  *                  -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
-  *                  runtime.valhalla.valuetypes.MVTComboTier1 -reducetypes 5
+ * @run main/othervm -noverify -Xcomp -XX:+EnableMVT runtime.valhalla.valuetypes.MVTComboTier1 -reducetypes 5
  */
 public class MVTComboTier1 {
 
--- a/test/runtime/valhalla/valuetypes/ValueOops.java	Mon Jul 17 13:09:35 2017 +0200
+++ b/test/runtime/valhalla/valuetypes/ValueOops.java	Mon Jul 17 13:13:15 2017 +0200
@@ -55,19 +55,15 @@
  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   runtime.valhalla.valuetypes.ValueOops
  * @run main/othervm -Xcomp -noverify -XX:+UseSerialGC -Xmx128m -XX:+EnableMVT
- *                   -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   runtime.valhalla.valuetypes.ValueOops
  * @run main/othervm -Xcomp -noverify -XX:+UseG1GC -Xmx128m -XX:+EnableMVT
- *                   -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   runtime.valhalla.valuetypes.ValueOops
  * @run main/othervm -Xcomp -noverify -XX:+UseParallelGC -Xmx128m -XX:+EnableMVT
- *                   -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   runtime.valhalla.valuetypes.ValueOops
  * @run main/othervm -Xcomp -noverify -XX:+UseConcMarkSweepGC -Xmx128m -XX:+EnableMVT
- *                   -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   runtime.valhalla.valuetypes.ValueOops
  */
--- a/test/runtime/valhalla/valuetypes/VboxUnbox.java	Mon Jul 17 13:09:35 2017 +0200
+++ b/test/runtime/valhalla/valuetypes/VboxUnbox.java	Mon Jul 17 13:13:15 2017 +0200
@@ -33,9 +33,7 @@
  * @library /test/lib
  * @build runtime.valhalla.valuetypes.ValueCapableClass
  * @run main/othervm -Xint -noverify -XX:+EnableMVT runtime.valhalla.valuetypes.VboxUnbox
- * @run main/othervm -Xcomp -noverify -XX:+EnableMVT
- *                   -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_isAssignableFrom
- *                   runtime.valhalla.valuetypes.VboxUnbox
+ * @run main/othervm -Xcomp -noverify -XX:+EnableMVT runtime.valhalla.valuetypes.VboxUnbox
  */
 public class VboxUnbox {