changeset 49450:e008cad90214 lworld

[lworld] Compiler cleanups part 2
author thartmann
date Fri, 23 Mar 2018 16:27:17 +0100
parents a07d36b876f6
children 513403560750
files src/hotspot/share/ci/bcEscapeAnalyzer.cpp src/hotspot/share/opto/arraycopynode.cpp src/hotspot/share/opto/macro.cpp src/hotspot/share/opto/parse.hpp src/hotspot/share/opto/parse2.cpp src/hotspot/share/opto/parseHelper.cpp src/hotspot/share/opto/type.cpp src/hotspot/share/opto/type.hpp src/hotspot/share/opto/valuetypenode.cpp test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestBasicFunctionality.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestCallingConvention.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestIntrinsics.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestMethodHandles.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestOnStackReplacement.java test/hotspot/jtreg/compiler/valhalla/valuetypes/ValueTypeTest.java test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeDensity.java
diffstat 18 files changed, 123 insertions(+), 136 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/ci/bcEscapeAnalyzer.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/ci/bcEscapeAnalyzer.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -559,21 +559,12 @@
         set_global_escape(state.apop());
         state.spop();
         ArgumentMap arr = state.apop();
+        // If the array is flattened, a larger part of it is modified than
+        // the size of a reference. However, if OFFSET_ANY is given as
+        // parameter to set_modified(), size is not taken into account.
         set_modified(arr, OFFSET_ANY, type2size[T_OBJECT]*HeapWordSize);
         break;
       }
-//      the vastore case below should be refactored to the aastore case above
-//      case Bytecodes::_vastore:
-//      {
-//        set_global_escape(state.apop());
-//        state.spop();
-//        ArgumentMap arr = state.apop();
-//        // If the array is flattened, a larger part of it is modified than
-//        // the size of a reference. However, if OFFSET_ANY is given as
-//        // parameter to set_modified(), size is not taken into account.
-//        set_modified(arr, OFFSET_ANY, type2size[T_VALUETYPE]*HeapWordSize);
-//        break;
-//      }
       case Bytecodes::_pop:
         state.raw_pop();
         break;
--- a/src/hotspot/share/opto/arraycopynode.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/arraycopynode.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -369,6 +369,7 @@
       Node* off  = kit.MakeConX(off_in_vt + i * vak->element_byte_size());
       ciType* ft = field->type();
       BasicType bt = type2field[ft->basic_type()];
+      assert(!field->is_flattened(), "flattened field encountered");
       if (bt == T_VALUETYPE) {
         bt = T_OBJECT;
       }
--- a/src/hotspot/share/opto/macro.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/macro.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -577,6 +577,13 @@
 
   int alias_idx = C->get_alias_index(adr_t);
   int offset = adr_t->offset();
+  if (adr_t->isa_aryptr()) {
+    int field_offset = adr_t->isa_aryptr()->field_offset().get();
+    if (field_offset != Type::OffsetBot) {
+      // Increment offset by the field offset for flattened value type arrays
+      offset += field_offset;
+    }
+  }
   Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
   Node *alloc_ctrl = alloc->in(TypeFunc::Control);
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
@@ -691,6 +698,7 @@
         bt = T_NARROWOOP;
       }
       value = value_from_mem(mem, ctl, bt, ft, adr_type, alloc);
+      assert(value != NULL, "field value should not be null");
       if (ft->isa_narrowoop()) {
         assert(UseCompressedOops, "unexpected narrow oop");
         value = transform_later(new DecodeNNode(value, value->get_ptr_type()));
@@ -864,6 +872,10 @@
       basic_elem_type = elem_type->basic_type();
       array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
       element_size = type2aelembytes(basic_elem_type);
+      if (klass->is_value_array_klass()) {
+        // Flattened value type array
+        element_size = klass->as_value_array_klass()->element_byte_size();
+      }
     }
   }
   //
--- a/src/hotspot/share/opto/parse.hpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/parse.hpp	Fri Mar 23 16:27:17 2018 +0100
@@ -464,7 +464,7 @@
   void do_one_bytecode();
 
   // helper function to generate array store check
-  void array_store_check(bool target_is_valuetypearray = false);
+  void array_store_check();
   // Helper function to generate array load
   void array_load(BasicType etype);
   // Helper function to generate array store
--- a/src/hotspot/share/opto/parse2.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/parse2.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -55,17 +55,20 @@
 void Parse::array_load(BasicType elem_type) {
   const Type* elem = Type::TOP;
   Node* adr = array_addressing(elem_type, 0, &elem);
-  if (stopped())  return;     // guaranteed null or range check
-  Node* idx   = pop();   // Get from stack without popping
-  Node* ary   = pop();   // in case of exception
-  //dec_sp(2);                  // Pop array and index
-  const TypeAryPtr* arytype = _gvn.type(ary)->is_aryptr();
-  if (arytype->klass()->is_value_array_klass()) {
-    ciValueArrayKlass* vak = arytype->klass()->as_value_array_klass();
-    ValueTypeNode* vt = ValueTypeNode::make_from_flattened(this, vak->element_klass()->as_value_klass(), ary, adr);
+  if (stopped()) return; // guaranteed null or range check
+  Node* idx = pop();
+  Node* ary = pop();
+
+  if (elem->isa_valuetype() != NULL) {
+    // Load from flattened value type array
+    ciValueKlass* vk = elem->is_valuetype()->value_klass();
+    ValueTypeNode* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr);
     push(vt);
     return;
   }
+  if (elem->make_valuetypeptr() != NULL) {
+    elem_type = T_VALUETYPE;
+  }
   const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(elem_type);
   Node* ld = make_load(control(), adr, elem, elem_type, adr_type, MemNode::unordered);
   push(ld);
@@ -1743,28 +1746,6 @@
   case Bytecodes::_iastore: array_store(T_INT);   break;
   case Bytecodes::_sastore: array_store(T_SHORT); break;
   case Bytecodes::_fastore: array_store(T_FLOAT); break;
-//  The vastore case has to merged into the aastore case
-//  case Bytecodes::_vastore: {
-//    d = array_addressing(T_OBJECT, 1);
-//    if (stopped())  return;     // guaranteed null or range check
-//    array_store_check(true);
-//    c = pop();                  // Oop to store
-//    b = pop();                  // index (already used)
-//    a = pop();                  // the array itself
-//    const TypeAryPtr* arytype = _gvn.type(a)->is_aryptr();
-//    const Type* elemtype = arytype->elem();
-//
-//    if (elemtype->isa_valuetype()) {
-//      c->as_ValueType()->store_flattened(this, a, d);
-//      break;
-//    }
-//
-//    const TypeAryPtr* adr_type = TypeAryPtr::OOPS;
-//    Node* oop = c->as_ValueType()->allocate(this)->get_oop();
-//    Node* store = store_oop_to_array(control(), a, d, adr_type, oop, elemtype->make_oopptr(), T_OBJECT,
-//                                     StoreNode::release_if_reference(T_OBJECT));
-//    break;
-//  }
   case Bytecodes::_aastore: {
     d = array_addressing(T_OBJECT, 1);
     if (stopped())  return;     // guaranteed null or range check
@@ -1772,10 +1753,15 @@
     c = pop();                  // Oop to store
     b = pop();                  // index (already used)
     a = pop();                  // the array itself
-    const TypeOopPtr* elemtype  = _gvn.type(a)->is_aryptr()->elem()->make_oopptr();
-    const TypeAryPtr* adr_type = TypeAryPtr::OOPS;
-    Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT,
-                                     StoreNode::release_if_reference(T_OBJECT));
+    const Type* elemtype  = _gvn.type(a)->is_aryptr()->elem();
+    if (elemtype->isa_valuetype()) {
+      // Store to flattened value type array
+      c->as_ValueType()->store_flattened(this, a, d);
+    } else {
+      const TypeAryPtr* adr_type = TypeAryPtr::OOPS;
+      store_oop_to_array(control(), a, d, adr_type, c, elemtype->make_oopptr(), T_OBJECT,
+                         StoreNode::release_if_reference(T_OBJECT));
+    }
     break;
   }
   case Bytecodes::_lastore: {
--- a/src/hotspot/share/opto/parseHelper.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/parseHelper.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -140,7 +140,7 @@
 
 //------------------------------array_store_check------------------------------
 // pull array from stack and check that the store is valid
-void Parse::array_store_check(bool target_is_valuetypearray) {
+void Parse::array_store_check() {
 
   // Shorthand access to array store elements without popping them.
   Node *obj = peek(0);
@@ -233,17 +233,15 @@
   Node* a_e_klass = _gvn.transform(LoadKlassNode::make(_gvn, always_see_exact_class ? control() : NULL,
                                                        immutable_memory(), p2, tak));
 
-  if (target_is_valuetypearray) {
-    ciKlass* target_elem_klass = gvn().type(a_e_klass)->is_klassptr()->klass();
-    ciKlass* source_klass = gvn().type(obj)->is_valuetype()->value_klass();
-    if (!target_elem_klass->equals(source_klass)) {
-      Node* slow_ctl = type_check(a_e_klass, TypeKlassPtr::make(source_klass), 1.0);
-      {
-        PreserveJVMState pjvms(this);
-        set_control(slow_ctl);
-        builtin_throw(Deoptimization::Reason_class_check);
-      }
-    }
+  const Type* elemtype = _gvn.type(ary)->is_aryptr()->elem();
+  if (elemtype->isa_valuetype()) {
+    // Flattened value type array: types must match
+    ciValueKlass* source_klass = _gvn.type(obj)->is_valuetype()->value_klass();
+    ciValueKlass* elem_klass = elemtype->is_valuetype()->value_klass();
+    assert(source_klass->equals(elem_klass), "type mismatch");
+  } else if (elemtype->make_valuetypeptr() != NULL) {
+    // Non-flattened value type array
+    // TODO do we need a checkcast here?
   } else {
     // Check (the hard way) and throw if not a subklass.
     // Result is ignored, we just need the CFG effects.
--- a/src/hotspot/share/opto/type.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/type.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -642,6 +642,7 @@
   // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert.
   TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL;
   TypeAryPtr::_array_body_type[T_OBJECT]  = TypeAryPtr::OOPS;
+  TypeAryPtr::_array_body_type[T_VALUETYPE] = TypeAryPtr::OOPS;
   TypeAryPtr::_array_body_type[T_ARRAY]   = TypeAryPtr::OOPS; // arrays are stored in oop arrays
   TypeAryPtr::_array_body_type[T_VALUETYPEPTR] = NULL;
   TypeAryPtr::_array_body_type[T_BYTE]    = TypeAryPtr::BYTES;
--- a/src/hotspot/share/opto/type.hpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/type.hpp	Fri Mar 23 16:27:17 2018 +0100
@@ -358,6 +358,10 @@
   // Asserts if the underlying type is not an oopptr or narrowoop.
   const TypeOopPtr* make_oopptr() const;
 
+  // Returns this valuetypeptr type or the equivalent valuetypeptr type for this compressed pointer.
+  // Asserts if the underlying type is not a valuetypeptr or narrow valuetypeptr.
+  const TypeValueTypePtr* make_valuetypeptr() const;
+
   // Returns this compressed pointer or the equivalent compressed version
   // of this pointer type.
   const TypeNarrowOop* make_narrowoop() const;
@@ -1834,6 +1838,10 @@
   return (_base == NarrowOop) ? is_narrowoop()->get_ptrtype()->isa_oopptr() : isa_oopptr();
 }
 
+inline const TypeValueTypePtr* Type::make_valuetypeptr() const {
+  return (_base == NarrowOop) ? is_narrowoop()->get_ptrtype()->isa_valuetypeptr() : isa_valuetypeptr();
+}
+
 inline const TypeNarrowOop* Type::make_narrowoop() const {
   return (_base == NarrowOop) ? is_narrowoop() :
                                 (isa_ptr() ? TypeNarrowOop::make(is_ptr()) : NULL);
--- a/src/hotspot/share/opto/valuetypenode.cpp	Fri Mar 23 10:23:09 2018 +0100
+++ b/src/hotspot/share/opto/valuetypenode.cpp	Fri Mar 23 16:27:17 2018 +0100
@@ -767,14 +767,18 @@
     PhaseIterGVN* igvn = phase->is_IterGVN();
 
     if (is_default(*phase)) {
-      // Search for allocations of the default value type
+      // Search for users of the default value type
       for (DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++) {
-        AllocateNode* alloc = fast_out(i)->isa_Allocate();
+        Node* user = fast_out(i);
+        AllocateNode* alloc = user->isa_Allocate();
         if (alloc != NULL && alloc->result_cast() != NULL && alloc->in(AllocateNode::ValueNode) == this) {
-          // Replace allocation be pre-allocated oop
+          // Replace allocation by pre-allocated oop
           Node* res = alloc->result_cast();
           Node* oop = load_default_oop(*phase, value_klass());
           igvn->replace_node(res, oop);
+        } else if (user->is_ValueType()) {
+          // Add value type user to worklist to give it a chance to get optimized as well
+          igvn->_worklist.push(user);
         }
       }
     }
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestArrays.java	Fri Mar 23 16:27:17 2018 +0100
@@ -31,8 +31,7 @@
  * @library /testlibrary /test/lib /compiler/whitebox /
  * @requires os.simpleArch == "x64"
  * @compile -XDenableValueTypes TestArrays.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main ClassFileInstaller jdk.test.lib.Platform
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
@@ -77,7 +76,7 @@
     }
 
     // Test value type array creation and initialization
-    @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOAD))
+    @Test(valid = ValueTypeArrayFlattenOff, failOn = LOAD)
     @Test(valid = ValueTypeArrayFlattenOn)
     public MyValue1[] test1(int len) {
         MyValue1[] va = new MyValue1[len];
@@ -97,8 +96,7 @@
     }
 
     // Test creation of a value type array and element access
-    @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOOP + TRAP))
-    @Test(valid = ValueTypeArrayFlattenOn, failOn = (ALLOC + ALLOCA + LOOP + LOAD + LOADP + STORE + TRAP))
+    @Test(failOn = ALLOC + ALLOCA + LOOP + LOAD + LOADP + STORE + TRAP)
     public long test2() {
         MyValue1[] va = new MyValue1[1];
         va[0] = MyValue1.createWithFieldsInline(rI, rL);
@@ -113,7 +111,7 @@
 
     // Test receiving a value type array from the interpreter,
     // updating its elements in a loop and computing a hash.
-    @Test(failOn = (ALLOCA))
+    @Test(failOn = ALLOCA)
     public long test3(MyValue1[] va) {
         long result = 0;
         for (int i = 0; i < 10; ++i) {
@@ -199,8 +197,7 @@
     }
 
     // Test creation of value type array with single element
-    @Test(valid = ValueTypeArrayFlattenOff, failOn = (LOAD + LOOP + TRAP))
-    @Test(valid = ValueTypeArrayFlattenOn, failOn = (ALLOCA + LOAD + LOOP + TRAP))
+    @Test(failOn = ALLOCA + LOOP + LOAD + TRAP)
     public MyValue1 test6() {
         MyValue1[] va = new MyValue1[1];
         return va[0];
@@ -244,7 +241,7 @@
     static MyValue1[] test9_va;
 
     // Test that value type array loaded from field has correct type
-    @Test(failOn = (LOOP))
+    @Test(failOn = LOOP)
     public long test9() {
         return test9_va[0].hash();
     }
@@ -457,7 +454,7 @@
     }
 
     // clone() as stub call
-    @Test()
+    @Test
     public MyValue1[] test18(MyValue1[] va) {
         return va.clone();
     }
@@ -477,7 +474,8 @@
 
     // clone() as series of loads/stores
     static MyValue1[] test19_orig = null;
-    @Test()
+
+    @Test
     public MyValue1[] test19() {
         MyValue1[] va = new MyValue1[8];
         for (int i = 0; i < va.length; ++i) {
@@ -497,7 +495,7 @@
     }
 
     // arraycopy() of value type array with oop fields
-    @Test()
+    @Test
     public void test20(MyValue1[] src, MyValue1[] dst) {
         System.arraycopy(src, 0, dst, 0, src.length);
     }
@@ -517,7 +515,7 @@
     }
 
     // arraycopy() of value type array with no oop field
-    @Test()
+    @Test
     public void test21(MyValue2[] src, MyValue2[] dst) {
         System.arraycopy(src, 0, dst, 0, src.length);
     }
@@ -538,7 +536,7 @@
 
     // arraycopy() of value type array with oop field and tightly
     // coupled allocation as dest
-    @Test()
+    @Test
     public MyValue1[] test22(MyValue1[] src) {
         MyValue1[] dst = new MyValue1[src.length];
         System.arraycopy(src, 0, dst, 0, src.length);
@@ -560,7 +558,7 @@
 
     // arraycopy() of value type array with oop fields and tightly
     // coupled allocation as dest
-    @Test()
+    @Test
     public MyValue1[] test23(MyValue1[] src) {
         MyValue1[] dst = new MyValue1[src.length + 10];
         System.arraycopy(src, 0, dst, 5, src.length);
@@ -581,7 +579,7 @@
     }
 
     // arraycopy() of value type array passed as Object
-    @Test()
+    @Test
     public void test24(MyValue1[] src, Object dst) {
         System.arraycopy(src, 0, dst, 0, src.length);
     }
@@ -601,7 +599,7 @@
     }
 
     // short arraycopy() with no oop field
-    @Test()
+    @Test
     public void test25(MyValue2[] src, MyValue2[] dst) {
         System.arraycopy(src, 0, dst, 0, 8);
     }
@@ -620,7 +618,7 @@
     }
 
     // short arraycopy() with oop fields
-    @Test()
+    @Test
     public void test26(MyValue1[] src, MyValue1[] dst) {
         System.arraycopy(src, 0, dst, 0, 8);
     }
@@ -639,7 +637,7 @@
     }
 
     // short arraycopy() with oop fields and offsets
-    @Test()
+    @Test
     public void test27(MyValue1[] src, MyValue1[] dst) {
         System.arraycopy(src, 1, dst, 2, 6);
     }
@@ -658,7 +656,7 @@
     }
 
     // non escaping allocations
-    @Test()
+    @Test(failOn = ALLOCA + LOOP + LOAD + LOADP + TRAP)
     public MyValue2 test28() {
         MyValue2[] src = new MyValue2[10];
         src[0] = MyValue2.createWithFieldsInline(rI, false);
@@ -674,7 +672,7 @@
     }
 
     // non escaping allocations
-    @Test()
+    @Test(failOn = ALLOCA + LOOP + LOAD + LOADP + TRAP)
     public MyValue2 test29(MyValue2[] src) {
         MyValue2[] dst = new MyValue2[10];
         System.arraycopy(src, 0, dst, 0, 10);
@@ -693,7 +691,7 @@
 
     // non escaping allocation with uncommon trap that needs
     // eliminated value type array element as debug info
-    @Test()
+    @Test
     @Warmup(10000)
     public MyValue2 test30(MyValue2[] src, boolean flag) {
         MyValue2[] dst = new MyValue2[10];
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestBasicFunctionality.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestBasicFunctionality.java	Fri Mar 23 16:27:17 2018 +0100
@@ -31,8 +31,7 @@
  * @library /testlibrary /test/lib /compiler/whitebox /
  * @requires os.simpleArch == "x64"
  * @compile -XDenableValueTypes TestBasicFunctionality.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main ClassFileInstaller jdk.test.lib.Platform
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
@@ -705,31 +704,10 @@
         Asserts.assertEQ(vt.i, (int)staticVal3.c);
     }
 
-    // Test passing a value type as an Object argument
-    @DontInline
-    public Object test34_callee(Object vt) {
-        return vt;
-    }
-
-    @Test()
-    public Object test34(boolean b, Object vt) throws Throwable {
-        if (b) {
-            return test34_callee(vt);
-        } else {
-            return MyValue1.createWithFieldsInline(rI + 1, rL + 1);
-        }
-    }
-
-    @DontCompile
-    public void test34_verifier(boolean warmup) throws Throwable {
-        test34(true, MyValue1.createWithFieldsInline(rI, rL));
-        test34(false, MyValue1.createWithFieldsInline(rI, rL));
-    }
-
     // Verify that the default value type is never allocated.
     // C2 code should load and use the default oop from the java mirror.
     @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP)
-    public MyValue3 test35(MyValue3[] va) {
+    public MyValue3 test34(MyValue3[] va) {
         // Explicitly create default value
         MyValue3 vt = MyValue3.createDefault();
         va[0] = vt;
@@ -745,12 +723,12 @@
     }
 
     @DontCompile
-    public void test35_verifier(boolean warmup) {
+    public void test34_verifier(boolean warmup) {
         MyValue3 vt = MyValue3.createDefault();
         MyValue3[] va = new MyValue3[2];
         va[0] = MyValue3.create();
         va[1] = MyValue3.create();
-        MyValue3 res = test35(va);
+        MyValue3 res = test34(va);
         res.verify(vt);
         staticVal3.verify(vt);
         staticVal3_copy.verify(vt);
@@ -760,7 +738,7 @@
 
     // Same as above but manually initialize value type fields to default.
     @Test(failOn = ALLOC + ALLOCA + LOAD + STORE + LOOP + TRAP)
-    public MyValue3 test36(MyValue3 vt, MyValue3[] va) {
+    public MyValue3 test35(MyValue3 vt, MyValue3[] va) {
         vt = MyValue3.setC(vt, (char)0);
         vt = MyValue3.setBB(vt, (byte)0);
         vt = MyValue3.setS(vt, (short)0);
@@ -781,11 +759,11 @@
     }
 
     @DontCompile
-    public void test36_verifier(boolean warmup) {
+    public void test35_verifier(boolean warmup) {
         MyValue3 vt = MyValue3.createDefault();
         MyValue3[] va = new MyValue3[1];
         va[0] = MyValue3.create();
-        MyValue3 res = test36(va[0], va);
+        MyValue3 res = test35(va[0], va);
         res.verify(vt);
         staticVal3.verify(vt);
         va[0].verify(vt);
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestCallingConvention.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestCallingConvention.java	Fri Mar 23 16:27:17 2018 +0100
@@ -33,8 +33,7 @@
  * @library /testlibrary /test/lib /compiler/whitebox /
  * @requires os.simpleArch == "x64"
  * @compile -XDenableValueTypes TestCallingConvention.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main ClassFileInstaller jdk.test.lib.Platform
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestIntrinsics.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestIntrinsics.java	Fri Mar 23 16:27:17 2018 +0100
@@ -31,8 +31,7 @@
  * @library /testlibrary /test/lib /compiler/whitebox /
  * @requires os.simpleArch == "x64"
  * @compile -XDenableValueTypes TestIntrinsics.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main ClassFileInstaller jdk.test.lib.Platform
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla
  *                               compiler.valhalla.valuetypes.TestIntrinsics
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestMethodHandles.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestMethodHandles.java	Fri Mar 23 16:27:17 2018 +0100
@@ -40,8 +40,7 @@
  *          java.base/jdk.experimental.value
  *          java.base/jdk.internal.misc:+open
  * @compile -XDenableValueTypes TestMethodHandles.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main ClassFileInstaller jdk.test.lib.Platform
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestOnStackReplacement.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestOnStackReplacement.java	Fri Mar 23 16:27:17 2018 +0100
@@ -31,8 +31,7 @@
  * @library /testlibrary /test/lib /compiler/whitebox /
  * @requires os.simpleArch == "x64"
  * @compile -XDenableValueTypes TestOnStackReplacement.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main ClassFileInstaller jdk.test.lib.Platform
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                   -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+AlwaysIncrementalInline
  *                   -XX:+EnableValhalla -XX:+ValueTypePassFieldsAsArgs -XX:+ValueTypeReturnedAsFields -XX:+ValueArrayFlatten
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/ValueTypeTest.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/ValueTypeTest.java	Fri Mar 23 16:27:17 2018 +0100
@@ -91,7 +91,7 @@
     // User defined settings
     private static final boolean PRINT_GRAPH = true;
     private static final boolean PRINT_TIMES = Boolean.parseBoolean(System.getProperty("PrintTimes", "false"));
-    private static final boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true"));
+    private static       boolean VERIFY_IR = Boolean.parseBoolean(System.getProperty("VerifyIR", "true"));
     private static final boolean VERIFY_VM = Boolean.parseBoolean(System.getProperty("VerifyVM", "false"));
     private static final String TESTLIST = System.getProperty("Testlist", "");
     private static final String EXCLUDELIST = System.getProperty("Exclude", "");
@@ -140,7 +140,6 @@
     protected static final String MID = ".*)+\\t===.*";
     protected static final String END = ")|";
     protected static final String ALLOC  = "(.*precise klass compiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_instance_Java" + END;
-    // FIXME check if this still works for value array allocations
     protected static final String ALLOCA = "(.*precise klass \\[Lcompiler/valhalla/valuetypes/MyValue.*\\R(.*(nop|spill).*\\R)*.*_new_array_Java" + END;
     protected static final String LOAD   = START + "Load(B|S|I|L|F|D)" + MID + "valuetype\\*" + END;
     protected static final String LOADP  = START + "Load(P|N)" + MID + "valuetype\\*" + END;
@@ -189,7 +188,24 @@
     private void execute_vm() throws Throwable {
         Asserts.assertFalse(tests.isEmpty(), "no tests to execute");
         ArrayList<String> args = new ArrayList<String>(defaultFlags);
+        String[] vmInputArgs = InputArguments.getVmInputArgs();
         if (VERIFY_IR) {
+            // Check if the JVM supports the default arguments from the test's run command
+            for (String arg : vmInputArgs) {
+                if (arg.startsWith("-XX:+")) {
+                    Boolean value = (Boolean)WHITE_BOX.getVMFlag(arg.substring(5));
+                    if (!value) {
+                        System.out.println("WARNING: could not enable " + arg.substring(5) + ". Skipping IR verification.");
+                        VERIFY_IR = false;
+                    }
+                } else if (arg.startsWith("-XX:-")) {
+                    Boolean value = (Boolean)WHITE_BOX.getVMFlag(arg.substring(5));
+                    if (value) {
+                        System.out.println("WARNING: could not disable " + arg.substring(5) + ". Skipping IR verification.");
+                        VERIFY_IR = false;
+                    }
+                }
+            }
             // Always trap for exception throwing to not confuse IR verification
             args.add("-XX:-OmitStackTraceInFastThrow");
         }
@@ -200,7 +216,6 @@
         args.add(getClass().getName());
         args.add("run");
         // Spawn process with default JVM options from the test's run command
-        String[] vmInputArgs = InputArguments.getVmInputArgs();
         String[] cmds = Arrays.copyOf(vmInputArgs, vmInputArgs.length + args.size());
         System.arraycopy(args.toArray(), 0, cmds, vmInputArgs.length, args.size());
         OutputAnalyzer oa = ProcessTools.executeTestJvm(cmds);
@@ -208,7 +223,7 @@
         String output = oa.getOutput();
         oa.shouldHaveExitValue(0);
         if (VERIFY_IR) {
-            if (output.contains("PrintIdeal enabled") && !output.contains("ValueTypePassFieldsAsArgs is not supported on this platform")) {
+            if (output.contains("PrintIdeal enabled")) {
                 parseOutput(output);
             } else {
                 System.out.println(output);
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java	Fri Mar 23 16:27:17 2018 +0100
@@ -41,7 +41,6 @@
  * @library /test/lib
  * @compile -XDenableValueTypes Person.java
  * @compile -XDenableValueTypes ValueOops.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xint -XX:+UseSerialGC -Xmx128m -XX:+EnableValhalla
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeDensity.java	Fri Mar 23 10:23:09 2018 +0100
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeDensity.java	Fri Mar 23 16:27:17 2018 +0100
@@ -32,7 +32,7 @@
  * @summary Heap density test for ValueTypes
  * @library /test/lib
  * @compile -XDenableValueTypes ValueTypeDensity.java
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  * @run main/othervm -Xint -XX:+EnableValhalla -XX:+ValueArrayFlatten
  *                   -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
  *                    -XX:+WhiteBoxAPI ValueTypeDensity
@@ -87,9 +87,9 @@
 
         public static LocalDateValue create(int year, short month, short day) {
             LocalDateValue localDate = __MakeDefault LocalDateValue();
-	    localDate = __WithField(localDate.year, year);
-	    localDate = __WithField(localDate.month, month);
-	    localDate = __WithField(localDate.day, day);
+            localDate = __WithField(localDate.year, year);
+            localDate = __WithField(localDate.month, month);
+            localDate = __WithField(localDate.day, day);
             return localDate;
         }
     }
@@ -114,10 +114,10 @@
 
         public static LocalTimeValue create(byte hour, byte minute, byte second, int nano) {
             LocalTimeValue localTime = __MakeDefault LocalTimeValue();
-	    localTime = __WithField(localTime.hour, hour);
-	    localTime = __WithField(localTime.minute, minute);
-	    localTime = __WithField(localTime.second, second);
-	    localTime = __WithField(localTime.nano, nano);
+            localTime = __WithField(localTime.hour, hour);
+            localTime = __WithField(localTime.minute, minute);
+            localTime = __WithField(localTime.second, second);
+            localTime = __WithField(localTime.nano, nano);
             return localTime;
         }
     }
@@ -143,8 +143,8 @@
 
         public static LocalDateTimeValue create(LocalDateValue date, LocalTimeValue time) {
             LocalDateTimeValue localDateTime = __MakeDefault LocalDateTimeValue();
-	    localDateTime = __WithField(localDateTime.date, date);
-	    localDateTime = __WithField(localDateTime.time, time);
+            localDateTime = __WithField(localDateTime.date, date);
+            localDateTime = __WithField(localDateTime.time, time);
             return localDateTime;
         }
     }