changeset 55886:da373189c4ed lworld

8223351: [lworld] Primary mirror and nullable mirror for inline type Reviewed-by: rriggs, acorn, hseigel
author mchung
date Thu, 06 Jun 2019 13:45:40 -0700
parents ed828b1f718d
children 46a46d8679df
files src/hotspot/share/ci/ciInstance.cpp src/hotspot/share/ci/ciMethodType.cpp src/hotspot/share/ci/ciValueKlass.cpp src/hotspot/share/ci/ciValueKlass.hpp src/hotspot/share/classfile/javaClasses.cpp src/hotspot/share/classfile/javaClasses.hpp src/hotspot/share/classfile/vmSymbols.cpp src/hotspot/share/classfile/vmSymbols.hpp src/hotspot/share/oops/valueKlass.hpp src/hotspot/share/opto/c2compiler.cpp src/hotspot/share/opto/graphKit.cpp src/hotspot/share/opto/library_call.cpp src/hotspot/share/opto/memnode.cpp src/hotspot/share/prims/jni.cpp src/hotspot/share/prims/methodHandles.cpp src/hotspot/share/runtime/reflection.cpp src/hotspot/share/runtime/signature.cpp src/hotspot/share/utilities/accessFlags.hpp src/java.base/share/classes/java/io/ObjectOutputStream.java src/java.base/share/classes/java/io/ObjectStreamClass.java src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java src/java.base/share/classes/java/lang/invoke/LambdaFormBuilder.java src/java.base/share/classes/java/lang/invoke/MemberName.java src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java src/java.base/share/classes/java/lang/invoke/MethodHandles.java src/java.base/share/classes/java/lang/invoke/ValueBootstrapMethods.java src/java.base/share/classes/java/lang/invoke/VarHandle.java src/java.base/share/classes/java/lang/invoke/VarHandles.java src/java.base/share/classes/java/lang/reflect/AccessibleObject.java src/java.base/share/classes/java/lang/reflect/Constructor.java src/java.base/share/classes/java/lang/reflect/Field.java src/java.base/share/classes/java/lang/reflect/Method.java src/java.base/share/classes/java/lang/reflect/Modifier.java src/java.base/share/classes/java/lang/reflect/Proxy.java src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java src/java.base/share/classes/jdk/experimental/value/MethodHandleBuilder.java src/java.base/share/classes/jdk/internal/misc/Unsafe.java src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java src/java.base/share/classes/jdk/internal/reflect/AccessorGenerator.java src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorImpl.java src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java src/java.base/share/classes/sun/invoke/util/VerifyAccess.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestIntrinsics.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestMethodHandles.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNativeClone.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNullableValueTypes.java test/hotspot/jtreg/runtime/valhalla/valuetypes/Ifacmp.java test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java test/jdk/valhalla/valuetypes/MethodHandleTest.java test/jdk/valhalla/valuetypes/NonFlattenValue.java test/jdk/valhalla/valuetypes/ObjectMethods.java test/jdk/valhalla/valuetypes/QTypeDescriptorTest.java test/jdk/valhalla/valuetypes/Reflection.java test/jdk/valhalla/valuetypes/ValueArray.java test/jdk/valhalla/valuetypes/ValueBootstrapMethods.java test/langtools/tools/javac/valhalla/lworld-values/ValueBootstrapMethodsTest.java
diffstat 60 files changed, 704 insertions(+), 590 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/ci/ciInstance.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/ci/ciInstance.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -53,7 +53,7 @@
     Klass* k = java_lang_Class::as_Klass(m);
     assert(k != NULL, "");
     if (is_val_type != NULL) {
-      *is_val_type = k->is_value() && !java_lang_Class::is_box_type(m);
+      *is_val_type = k->is_value() && !java_lang_Class::is_indirect_type(m);
     }
     return CURRENT_THREAD_ENV->get_klass(k);
   }
--- a/src/hotspot/share/ci/ciMethodType.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/ci/ciMethodType.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -41,7 +41,7 @@
 ciType* ciMethodType::rtype(bool& never_null) const {
   GUARDED_VM_ENTRY(
     oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
-    never_null = (java_lang_Class::value_mirror(rtype) == rtype);
+    never_null = (java_lang_Class::inline_type_mirror(rtype) == rtype);
     return class_to_citype(rtype);
   )
 }
@@ -57,7 +57,7 @@
 ciType* ciMethodType::ptype_at(int index, bool& never_null) const {
   GUARDED_VM_ENTRY(
     oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
-    never_null = (java_lang_Class::value_mirror(ptype) == ptype);
+    never_null = (java_lang_Class::inline_type_mirror(ptype) == ptype);
     return class_to_citype(ptype);
   )
 }
--- a/src/hotspot/share/ci/ciValueKlass.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/ci/ciValueKlass.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -109,17 +109,17 @@
   )
 }
 
-ciInstance* ciValueKlass::value_mirror_instance() const {
+ciInstance* ciValueKlass::inline_mirror_instance() const {
   GUARDED_VM_ENTRY(
     oop value_mirror = to_ValueKlass()->value_mirror();
     return CURRENT_ENV->get_instance(value_mirror);
   )
 }
 
-ciInstance* ciValueKlass::box_mirror_instance() const {
+ciInstance* ciValueKlass::indirect_mirror_instance() const {
   GUARDED_VM_ENTRY(
-    oop box_mirror = to_ValueKlass()->box_mirror();
-    return CURRENT_ENV->get_instance(box_mirror);
+    oop mirror = to_ValueKlass()->indirect_mirror();
+    return CURRENT_ENV->get_instance(mirror);
   )
 }
 
--- a/src/hotspot/share/ci/ciValueKlass.hpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/ci/ciValueKlass.hpp	Thu Jun 06 13:45:40 2019 -0700
@@ -83,8 +83,8 @@
   int value_arg_slots();
   int default_value_offset() const;
   ciInstance* default_value_instance() const;
-  ciInstance* value_mirror_instance() const;
-  ciInstance* box_mirror_instance() const;
+  ciInstance* inline_mirror_instance() const;
+  ciInstance* indirect_mirror_instance() const;
   bool contains_oops() const;
   Array<SigEntry>* extended_sig() const;
   address pack_handler() const;
--- a/src/hotspot/share/classfile/javaClasses.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -929,17 +929,19 @@
         assert(element_klass->is_value(), "Must be value type component");
         ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(element_klass));
         comp_mirror = Handle(THREAD, vk->value_mirror());
-      }
-      else if (k->is_typeArray_klass()) {
+      } else if (k->is_typeArray_klass()) {
         BasicType type = TypeArrayKlass::cast(k)->element_type();
         comp_mirror = Handle(THREAD, Universe::java_mirror(type));
       } else {
         assert(k->is_objArray_klass(), "Must be");
         Klass* element_klass = ObjArrayKlass::cast(k)->element_klass();
         assert(element_klass != NULL, "Must have an element klass");
-        if (element_klass->is_value() && k->name()->is_Q_array_signature()) {
+        if (element_klass->is_value()) {
           ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(element_klass));
-          comp_mirror = Handle(THREAD, vk->value_mirror());
+          assert(vk->java_mirror() == vk->value_mirror(), "primary mirror is the value mirror");
+          assert(vk->indirect_mirror() != NULL, "must have an indirect class mirror");
+          comp_mirror = k->name()->is_Q_array_signature() ? Handle(THREAD, vk->value_mirror())
+                                                          : Handle(THREAD, vk->indirect_mirror());
         } else {
           comp_mirror = Handle(THREAD, element_klass->java_mirror());
         }
@@ -984,10 +986,10 @@
     }
 
     if (k->is_value()) {
-      // create the secondary mirror for value class
-      oop value_mirror_oop = create_value_mirror(k, mirror, CHECK);
-      set_box_mirror(mirror(), mirror());
-      set_value_mirror(mirror(), value_mirror_oop);
+      // create the secondary mirror for an inline class
+      oop indirect_mirror_oop = create_indirect_type_mirror(k, mirror, CHECK);
+      set_inline_type_mirror(mirror(), mirror());
+      set_indirect_type_mirror(mirror(), indirect_mirror_oop);
     }
   } else {
     assert(fixup_mirror_list() != NULL, "fixup_mirror_list not initialized");
@@ -995,31 +997,26 @@
   }
 }
 
-// Create the secondary mirror for value type. Sets all the fields of this java.lang.Class
-// instance with the same value as the primary mirror except signers.
-// Class::setSigners and getSigners will use the primary mirror when passed to the JVM.
-oop java_lang_Class::create_value_mirror(Klass* k, Handle mirror, TRAPS) {
-    // Allocate mirror (java.lang.Class instance)
-    oop mirror_oop = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
-    Handle value_mirror(THREAD, mirror_oop);
-
-    java_lang_Class::set_klass(value_mirror(), k);
-    java_lang_Class::set_static_oop_field_count(value_mirror(), static_oop_field_count(mirror()));
-    // ## do we need to set init lock?
-    java_lang_Class::set_init_lock(value_mirror(), init_lock(mirror()));
-
-    if (k->is_array_klass()) {
-      assert(component_mirror(mirror()) != NULL, "must have a mirror");
-      set_component_mirror(value_mirror(), component_mirror(mirror()));
-    }
-
-    set_protection_domain(value_mirror(), protection_domain(mirror()));
-    set_class_loader(value_mirror(), class_loader(mirror()));
-    // ## handle if java.base is not yet defined
-    set_module(value_mirror(), module(mirror()));
-    set_box_mirror(value_mirror(), mirror());
-    set_value_mirror(value_mirror(), value_mirror());
-    return value_mirror();
+// Create the secondary mirror for inline class. Sets all the fields of this java.lang.Class
+// instance with the same value as the primary mirror
+oop java_lang_Class::create_indirect_type_mirror(Klass* k, Handle mirror, TRAPS) {
+  assert(k->is_value(), "inline class");
+  // Allocate mirror (java.lang.Class instance)
+  oop mirror_oop = InstanceMirrorKlass::cast(SystemDictionary::Class_klass())->allocate_instance(k, CHECK_0);
+  Handle indirect_mirror(THREAD, mirror_oop);
+
+  java_lang_Class::set_klass(indirect_mirror(), k);
+  java_lang_Class::set_static_oop_field_count(indirect_mirror(), static_oop_field_count(mirror()));
+  // ## do we need to set init lock?
+  java_lang_Class::set_init_lock(indirect_mirror(), init_lock(mirror()));
+
+  set_protection_domain(indirect_mirror(), protection_domain(mirror()));
+  set_class_loader(indirect_mirror(), class_loader(mirror()));
+  // ## handle if java.base is not yet defined
+  set_module(indirect_mirror(), module(mirror()));
+  set_inline_type_mirror(indirect_mirror(), mirror());
+  set_indirect_type_mirror(indirect_mirror(), indirect_mirror());
+  return indirect_mirror();
 }
 
 #if INCLUDE_CDS_JAVA_HEAP
@@ -1429,24 +1426,24 @@
   java_class->obj_field_put(_source_file_offset, source_file);
 }
 
-oop java_lang_Class::value_mirror(oop java_class) {
-  assert(_value_mirror_offset != 0, "must be set");
-  return java_class->obj_field(_value_mirror_offset);
-}
-
-void java_lang_Class::set_value_mirror(oop java_class, oop mirror) {
-  assert(_value_mirror_offset != 0, "must be set");
-  java_class->obj_field_put(_value_mirror_offset, mirror);
-}
-
-oop java_lang_Class::box_mirror(oop java_class) {
-  assert(_box_mirror_offset != 0, "must be set");
-  return java_class->obj_field(_box_mirror_offset);
-}
-
-void java_lang_Class::set_box_mirror(oop java_class, oop mirror) {
-  assert(_box_mirror_offset != 0, "must be set");
-  java_class->obj_field_put(_box_mirror_offset, mirror);
+oop java_lang_Class::inline_type_mirror(oop java_class) {
+  assert(_inline_mirror_offset != 0, "must be set");
+  return java_class->obj_field(_inline_mirror_offset);
+}
+
+void java_lang_Class::set_inline_type_mirror(oop java_class, oop mirror) {
+  assert(_inline_mirror_offset != 0, "must be set");
+  java_class->obj_field_put(_inline_mirror_offset, mirror);
+}
+
+oop java_lang_Class::indirect_type_mirror(oop java_class) {
+  assert(_indirect_mirror_offset != 0, "must be set");
+  return java_class->obj_field(_indirect_mirror_offset);
+}
+
+void java_lang_Class::set_indirect_type_mirror(oop java_class, oop mirror) {
+  assert(_indirect_mirror_offset != 0, "must be set");
+  java_class->obj_field_put(_indirect_mirror_offset, mirror);
 }
 
 oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
@@ -1507,7 +1504,7 @@
     return;
   }
   if (is_instance)  {
-    if (is_value && (java_class == value_mirror(java_class))) {
+    if (is_value && (java_class == inline_type_mirror(java_class))) {
       st->print("Q");
     } else {
       st->print("L");
@@ -1535,7 +1532,7 @@
       ResourceMark rm;
       const char* sigstr;
       if (k->is_value()) {
-        char c = (java_class == value_mirror(java_class)) ? 'Q' : 'L';
+        char c = (java_class == inline_type_mirror(java_class)) ? 'Q' : 'L';
         sigstr = InstanceKlass::cast(k)->signature_name_of(c);
       } else {
         sigstr = k->signature_name();
@@ -1625,8 +1622,8 @@
   macro(_component_mirror_offset,   k, "componentType",       class_signature,       false); \
   macro(_module_offset,             k, "module",              module_signature,      false); \
   macro(_name_offset,               k, "name",                string_signature,      false); \
-  macro(_box_mirror_offset,         k, "boxType",             class_signature,       false); \
-  macro(_value_mirror_offset,       k, "valueType",           class_signature,       false); \
+  macro(_inline_mirror_offset,      k, "inlineType",          class_signature,       false); \
+  macro(_indirect_mirror_offset,    k, "indirectType",        class_signature,       false); \
 
 void java_lang_Class::compute_offsets() {
   if (offsets_computed) {
@@ -4158,8 +4155,8 @@
 int java_lang_Class::_module_offset;
 int java_lang_Class::_protection_domain_offset;
 int java_lang_Class::_component_mirror_offset;
-int java_lang_Class::_box_mirror_offset;
-int java_lang_Class::_value_mirror_offset;
+int java_lang_Class::_inline_mirror_offset;
+int java_lang_Class::_indirect_mirror_offset;
 int java_lang_Class::_init_lock_offset;
 int java_lang_Class::_signers_offset;
 int java_lang_Class::_name_offset;
--- a/src/hotspot/share/classfile/javaClasses.hpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Jun 06 13:45:40 2019 -0700
@@ -251,8 +251,8 @@
   static int _component_mirror_offset;
   static int _name_offset;
   static int _source_file_offset;
-  static int _box_mirror_offset;
-  static int _value_mirror_offset;
+  static int _inline_mirror_offset;
+  static int _indirect_mirror_offset;
 
   static bool offsets_computed;
   static int classRedefinedCount_offset;
@@ -275,7 +275,7 @@
                             Handle protection_domain, TRAPS);
   static void fixup_mirror(Klass* k, TRAPS);
   static oop  create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
-  static oop  create_value_mirror(Klass* k, Handle mirror, TRAPS);
+  static oop  create_indirect_type_mirror(Klass* k, Handle mirror, TRAPS);
 
   // Archiving
   static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
@@ -309,7 +309,7 @@
   // compiler support for class operations
   static int klass_offset_in_bytes()                { return _klass_offset; }
   static int array_klass_offset_in_bytes()          { return _array_klass_offset; }
-  static int value_mirror_offset_in_bytes()         { return _value_mirror_offset; }
+  static int inline_mirror_offset_in_bytes()        { return _inline_mirror_offset; }
   static int component_mirror_offset_in_bytes()     { return _component_mirror_offset; }
   // Support for classRedefinedCount field
   static int classRedefinedCount(oop the_class_mirror);
@@ -326,14 +326,14 @@
   static void set_module(oop java_class, oop module);
   static oop module(oop java_class);
 
-  static void set_box_mirror(oop java_class, oop mirror);
-  static oop box_mirror(oop java_class);
-  static bool is_box_type(oop java_class) { // Must match "Class.isBoxType()"
-    return box_mirror(java_class) == NULL || oopDesc::equals(box_mirror(java_class), java_class);
+  static void set_indirect_type_mirror(oop java_class, oop mirror);
+  static oop indirect_type_mirror(oop java_class);
+  static bool is_indirect_type(oop java_class) { // Must match "Class.isIndirectType()"
+    return indirect_type_mirror(java_class) == NULL || oopDesc::equals(indirect_type_mirror(java_class), java_class);
   }
 
-  static void set_value_mirror(oop java_class, oop mirror);
-  static oop value_mirror(oop java_class);
+  static void set_inline_type_mirror(oop java_class, oop mirror);
+  static oop inline_type_mirror(oop java_class);
 
   static oop name(Handle java_class, TRAPS);
 
--- a/src/hotspot/share/classfile/vmSymbols.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/classfile/vmSymbols.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -552,8 +552,8 @@
   }
 
   switch (id) {
-  case vmIntrinsics::_asValueType:
-  case vmIntrinsics::_asBoxType:
+  case vmIntrinsics::_asPrimaryType:
+  case vmIntrinsics::_asIndirectType:
   case vmIntrinsics::_isInstance:
   case vmIntrinsics::_isAssignableFrom:
   case vmIntrinsics::_getModifiers:
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Thu Jun 06 13:45:40 2019 -0700
@@ -863,10 +863,10 @@
    do_signature(currentThread_signature,                         "()Ljava/lang/Thread;")                                \
                                                                                                                         \
   /* reflective intrinsics, for java/lang/Class, etc. */                                                                \
-  do_intrinsic(_asValueType,              java_lang_Class,        asValueType_name, void_class_signature,        F_R)   \
-   do_name(     asValueType_name,                                "asValueType")                                         \
-  do_intrinsic(_asBoxType,                java_lang_Class,        asBoxType_name, void_class_signature,          F_R)   \
-   do_name(     asBoxType_name,                                  "asBoxType")                                           \
+  do_intrinsic(_asPrimaryType,           java_lang_Class,         asPrimaryType_name, void_class_signature,     F_R)    \
+   do_name(     asPrimaryType_name,                              "asPrimaryType")                                       \
+  do_intrinsic(_asIndirectType,          java_lang_Class,         asIndirectType_name, void_class_signature,    F_R)    \
+   do_name(     asIndirectType_name,                             "asIndirectType")                                      \
   do_intrinsic(_isAssignableFrom,         java_lang_Class,        isAssignableFrom_name, class_boolean_signature, F_RN) \
    do_name(     isAssignableFrom_name,                           "isAssignableFrom")                                    \
   do_intrinsic(_isInstance,               java_lang_Class,        isInstance_name, object_boolean_signature,     F_RN)  \
--- a/src/hotspot/share/oops/valueKlass.hpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/oops/valueKlass.hpp	Thu Jun 06 13:45:40 2019 -0700
@@ -137,8 +137,9 @@
   // Type testing
   bool is_value_slow() const        { return true; }
 
-  oop value_mirror() const { return java_lang_Class::value_mirror(java_mirror()); }
-  oop   box_mirror() const { return java_lang_Class::box_mirror(java_mirror()); }
+  // value_mirror is the primary mirror
+  oop value_mirror() const    { return java_lang_Class::inline_type_mirror(java_mirror()); }
+  oop indirect_mirror() const { return java_lang_Class::indirect_type_mirror(java_mirror()); }
 
   // Casting from Klass*
   static ValueKlass* cast(Klass* k) {
@@ -249,7 +250,7 @@
 
   void set_default_value(oop val) {
     java_mirror()->obj_field_put(default_value_offset(), val);
-    value_mirror()->obj_field_put(default_value_offset(), val);
+    indirect_mirror()->obj_field_put(default_value_offset(), val);
   }
 
   oop default_value() {
--- a/src/hotspot/share/opto/c2compiler.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/opto/c2compiler.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -602,8 +602,8 @@
   case vmIntrinsics::_longBitsToDouble:
   case vmIntrinsics::_Reference_get:
   case vmIntrinsics::_Class_cast:
-  case vmIntrinsics::_asValueType:
-  case vmIntrinsics::_asBoxType:
+  case vmIntrinsics::_asPrimaryType:
+  case vmIntrinsics::_asIndirectType:
   case vmIntrinsics::_aescrypt_encryptBlock:
   case vmIntrinsics::_aescrypt_decryptBlock:
   case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
--- a/src/hotspot/share/opto/graphKit.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/opto/graphKit.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -3408,10 +3408,10 @@
     Node* array_type_mirror = load_mirror_from_klass(load_object_klass(ary));
     Node* elem_mirror_adr = basic_plus_adr(array_type_mirror, java_lang_Class::component_mirror_offset_in_bytes());
     Node* elem_mirror = access_load_at(array_type_mirror, elem_mirror_adr, _gvn.type(elem_mirror_adr)->is_ptr(), TypeInstPtr::MIRROR, T_OBJECT, IN_HEAP);
-    Node* value_mirror_adr = basic_plus_adr(elem_mirror, java_lang_Class::value_mirror_offset_in_bytes());
-    Node* value_mirror = access_load_at(elem_mirror, value_mirror_adr, _gvn.type(value_mirror_adr)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
-    // Deoptimize if elem_mirror == value_mirror => null-free array
-    Node* cmp = _gvn.transform(new CmpPNode(elem_mirror, value_mirror));
+    Node* inline_mirror_adr = basic_plus_adr(elem_mirror, java_lang_Class::inline_mirror_offset_in_bytes());
+    Node* inline_mirror = access_load_at(elem_mirror, inline_mirror_adr, _gvn.type(inline_mirror_adr)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
+    // Deoptimize if elem_mirror == inline_mirror => null-free array
+    Node* cmp = _gvn.transform(new CmpPNode(elem_mirror, inline_mirror));
     Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne));
     { BuildCutout unless(this, bol, PROB_MAX);
       inc_sp(nargs);
@@ -4057,9 +4057,9 @@
     Node* flat      = MakeConX(ArrayStorageProperties::flattened_and_null_free.encode<NOT_LP64(jint) LP64_ONLY(jlong)>(props_shift));
 
     // Check if element mirror is a value mirror
-    Node* p = basic_plus_adr(elem_mirror, java_lang_Class::value_mirror_offset_in_bytes());
-    Node* value_mirror = access_load_at(elem_mirror, p, _gvn.type(p)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
-    Node* cmp = _gvn.transform(new CmpPNode(elem_mirror, value_mirror));
+    Node* p = basic_plus_adr(elem_mirror, java_lang_Class::inline_mirror_offset_in_bytes());
+    Node* inline_mirror = access_load_at(elem_mirror, p, _gvn.type(p)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
+    Node* cmp = _gvn.transform(new CmpPNode(elem_mirror, inline_mirror));
     Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::eq));
     IfNode* iff = create_and_map_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
 
--- a/src/hotspot/share/opto/library_call.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/opto/library_call.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -799,8 +799,8 @@
   case vmIntrinsics::_getSuperclass:
   case vmIntrinsics::_getClassAccessFlags:      return inline_native_Class_query(intrinsic_id());
 
-  case vmIntrinsics::_asValueType:
-  case vmIntrinsics::_asBoxType:                return inline_value_Class_conversion(intrinsic_id());
+  case vmIntrinsics::_asPrimaryType:
+  case vmIntrinsics::_asIndirectType:           return inline_value_Class_conversion(intrinsic_id());
 
   case vmIntrinsics::_floatToRawIntBits:
   case vmIntrinsics::_floatToIntBits:
@@ -3516,8 +3516,8 @@
 }
 
 //-------------------------inline_value_Class_conversion-------------------
-// public Class<T> java.lang.Class.asBoxType();
-// public Class<T> java.lang.Class.asValueType()
+// public Class<T> java.lang.Class.asPrimaryType();
+// public Class<T> java.lang.Class.asIndirectType()
 bool LibraryCallKit::inline_value_Class_conversion(vmIntrinsics::ID id) {
   Node* mirror = argument(0); // Receiver Class
   const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr();
@@ -3529,10 +3529,10 @@
   ciType* tm = mirror_con->java_mirror_type(&is_val_type);
   if (tm != NULL && tm->is_valuetype()) {
     Node* result = mirror;
-    if (id == vmIntrinsics::_asValueType && !is_val_type) {
-      result = _gvn.makecon(TypeInstPtr::make(tm->as_value_klass()->value_mirror_instance()));
-    } else if (id == vmIntrinsics::_asBoxType && is_val_type) {
-      result = _gvn.makecon(TypeInstPtr::make(tm->as_value_klass()->box_mirror_instance()));
+    if (id == vmIntrinsics::_asPrimaryType && !is_val_type) {
+      result = _gvn.makecon(TypeInstPtr::make(tm->as_value_klass()->inline_mirror_instance()));
+    } else if (id == vmIntrinsics::_asIndirectType && is_val_type) {
+      result = _gvn.makecon(TypeInstPtr::make(tm->as_value_klass()->indirect_mirror_instance()));
     }
     set_result(result);
     return true;
@@ -3620,11 +3620,11 @@
   if (!stopped()) {
     // TODO move this into do_checkcast?
     if (EnableValhalla && !obj->is_ValueType() && !is_val_type) {
-      // Check if (mirror == value_mirror && obj == null)
+      // Check if (mirror == inline_mirror && obj == null)
       RegionNode* r = new RegionNode(3);
-      Node* p = basic_plus_adr(mirror, java_lang_Class::value_mirror_offset_in_bytes());
-      Node* value_mirror = access_load_at(mirror, p, _gvn.type(p)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
-      Node* cmp = _gvn.transform(new CmpPNode(mirror, value_mirror));
+      Node* p = basic_plus_adr(mirror, java_lang_Class::inline_mirror_offset_in_bytes());
+      Node* inline_mirror = access_load_at(mirror, p, _gvn.type(p)->is_ptr(), TypeInstPtr::MIRROR->cast_to_ptr_type(TypePtr::BotPTR), T_OBJECT, IN_HEAP);
+      Node* cmp = _gvn.transform(new CmpPNode(mirror, inline_mirror));
       Node* bol = _gvn.transform(new BoolNode(cmp, BoolTest::ne));
       Node* if_ne = generate_fair_guard(bol, NULL);
       r->init_req(1, if_ne);
--- a/src/hotspot/share/opto/memnode.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/opto/memnode.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -1855,14 +1855,14 @@
     // Fold component and value mirror loads
     ciInstanceKlass* ik = tinst->klass()->as_instance_klass();
     if (ik == phase->C->env()->Class_klass() && (off == java_lang_Class::component_mirror_offset_in_bytes() ||
-                                                 off == java_lang_Class::value_mirror_offset_in_bytes())) {
+                                                 off == java_lang_Class::inline_mirror_offset_in_bytes())) {
       ciType* mirror_type = tinst->java_mirror_type();
       if (mirror_type != NULL) {
         const Type* const_oop = TypePtr::NULL_PTR;
         if (mirror_type->is_array_klass()) {
           const_oop = TypeInstPtr::make(mirror_type->as_array_klass()->component_mirror_instance());
         } else if (mirror_type->is_valuetype()) {
-          const_oop = TypeInstPtr::make(mirror_type->as_value_klass()->value_mirror_instance());
+          const_oop = TypeInstPtr::make(mirror_type->as_value_klass()->inline_mirror_instance());
         }
         return (bt == T_NARROWOOP) ? const_oop->make_narrowoop() : const_oop;
       }
--- a/src/hotspot/share/prims/jni.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/prims/jni.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -58,6 +58,7 @@
 #include "oops/symbol.hpp"
 #include "oops/typeArrayKlass.hpp"
 #include "oops/typeArrayOop.inline.hpp"
+#include "oops/valueKlass.hpp"
 #include "prims/jniCheck.hpp"
 #include "prims/jniExport.hpp"
 #include "prims/jniFastGetField.hpp"
@@ -578,7 +579,15 @@
   assert(sub_klass != NULL && super_klass != NULL, "invalid arguments to jni_IsAssignableFrom");
   jboolean ret = sub_klass->is_subtype_of(super_klass) ?
                    JNI_TRUE : JNI_FALSE;
-
+  if (sub_klass == super_klass && sub_klass->is_value()) {
+    // for inline class, V <: V?
+    ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(sub_klass));
+    if (sub_mirror == super_mirror || (sub_mirror == vk->value_mirror() && super_mirror == vk->indirect_mirror())) {
+      ret = JNI_TRUE;
+    } else {
+      ret = JNI_FALSE;
+    }
+  }
   HOTSPOT_JNI_ISASSIGNABLEFROM_RETURN(ret);
   return ret;
 JNI_END
--- a/src/hotspot/share/prims/methodHandles.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/prims/methodHandles.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -340,7 +340,7 @@
   int flags = (jushort)( fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
   flags |= IS_FIELD | ((fd.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
   if (fd.is_flattenable()) {
-    flags |= JVM_ACC_FLATTENABLE;
+    flags |= JVM_ACC_FIELD_FLATTENABLE;
   }
     if (fd.is_flattened()) {
     flags |= JVM_ACC_FIELD_FLATTENED;
--- a/src/hotspot/share/runtime/reflection.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/runtime/reflection.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -344,7 +344,7 @@
     if (k->is_array_klass() && ArrayKlass::cast(k)->dimension() >= MAX_DIM) {
       THROW_0(vmSymbols::java_lang_IllegalArgumentException());
     }
-    if (java_lang_Class::is_box_type(element_mirror)) {
+    if (java_lang_Class::is_indirect_type(element_mirror)) {
       return oopFactory::new_objArray(k, length, THREAD);
     } else {
       return oopFactory::new_valueArray(k, length, THREAD);
@@ -760,9 +760,9 @@
 // Returns Q-mirror if qtype_if_value is true and k is a ValueKlass;
 // otherwise returns java_mirror or L-mirror for ValueKlass
 static oop java_mirror(Klass* k, jboolean qtype_if_value) {
-  if (qtype_if_value && k->is_value()) {
+  if (k->is_value()) {
     ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(k));
-    return vk->value_mirror();
+    return qtype_if_value ? vk->value_mirror() : vk->indirect_mirror();
   } else {
     return k->java_mirror();
   }
@@ -952,7 +952,9 @@
   // Note the ACC_ANNOTATION bit, which is a per-class access flag, is never set here.
   int modifiers = fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS;
   if (fd->is_flattenable()) {
-    modifiers |= JVM_ACC_FLATTENABLE;
+    modifiers |= JVM_ACC_FIELD_FLATTENABLE;
+    // JVM_ACC_FLATTENABLE should not be set in LWorld.  set_is_flattenable should be re-examined.
+    modifiers &= ~JVM_ACC_FLATTENABLE;
   }
   if (fd->is_flattened()) {
     modifiers |= JVM_ACC_FIELD_FLATTENED;
@@ -1232,7 +1234,7 @@
   BasicType rtype;
   if (java_lang_Class::is_primitive(return_type_mirror)) {
     rtype = basic_type_mirror_to_basic_type(return_type_mirror, CHECK_NULL);
-  } else if (java_lang_Class::value_mirror(return_type_mirror) == return_type_mirror) {
+  } else if (java_lang_Class::inline_type_mirror(return_type_mirror) == return_type_mirror) {
     rtype = T_VALUETYPE;
   } else {
     rtype = T_OBJECT;
--- a/src/hotspot/share/runtime/signature.cpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/runtime/signature.cpp	Thu Jun 06 13:45:40 2019 -0700
@@ -417,7 +417,13 @@
     return Universe::java_mirror(type());
   Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
   if (klass == NULL)  return NULL;
-  return _type == T_VALUETYPE ? ValueKlass::cast(InstanceKlass::cast(klass))->value_mirror() : klass->java_mirror();
+  if (klass->is_value()) {
+    ValueKlass* vk = ValueKlass::cast(InstanceKlass::cast(klass));
+    return _type == T_VALUETYPE ? vk->value_mirror() : vk->indirect_mirror();
+  } else {
+    assert(_type != T_VALUETYPE, "must not be value type");
+    return klass->java_mirror();
+  }
 }
 
 Symbol* SignatureStream::as_symbol_or_null() {
--- a/src/hotspot/share/utilities/accessFlags.hpp	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/hotspot/share/utilities/accessFlags.hpp	Thu Jun 06 13:45:40 2019 -0700
@@ -85,8 +85,8 @@
   JVM_ACC_FIELD_STABLE                    = 0x00000020, // @Stable field, same as JVM_ACC_SYNCHRONIZED and JVM_ACC_SUPER
   JVM_ACC_FIELD_INITIALIZED_FINAL_UPDATE  = 0x00000200, // (static) final field updated outside (class) initializer, same as JVM_ACC_NATIVE
   JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE     = 0x00000800, // field has generic signature
-  /* JVM_ACC_FLATTENABLE                     = 0x00000100, */ // To be enabled when ACC_FLATTENABLE is removed from java.base
-  JVM_ACC_FIELD_FLATTENED                 = 0x00008000, // flattened value field
+  JVM_ACC_FIELD_FLATTENABLE               = 0x00004000, // flattenable field
+  JVM_ACC_FIELD_FLATTENED                 = 0x00008000, // flattened field
 
   JVM_ACC_FIELD_INTERNAL_FLAGS       = JVM_ACC_FIELD_ACCESS_WATCHED |
                                        JVM_ACC_FIELD_MODIFICATION_WATCHED |
@@ -94,6 +94,7 @@
                                        JVM_ACC_FIELD_STABLE |
                                        JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE |
                                        JVM_ACC_FLATTENABLE |
+                                       JVM_ACC_FIELD_FLATTENABLE |
                                        JVM_ACC_FIELD_FLATTENED,
 
                                                     // flags accepted by set_field_flags()
--- a/src/java.base/share/classes/java/io/ObjectOutputStream.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java	Thu Jun 06 13:45:40 2019 -0700
@@ -1171,7 +1171,7 @@
             // remaining cases
             if (obj instanceof String) {
                 writeString((String) obj, unshared);
-            } else if (cl.isValue()) {
+            } else if (cl.isInlineClass()) {
                 throw new NotSerializableException(cl.getName());
             } else if (cl.isArray()) {
                 writeArray(obj, desc, unshared);
--- a/src/java.base/share/classes/java/io/ObjectStreamClass.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java	Thu Jun 06 13:45:40 2019 -0700
@@ -474,7 +474,7 @@
         name = cl.getName();
         isProxy = Proxy.isProxyClass(cl);
         isEnum = Enum.class.isAssignableFrom(cl);
-        boolean isInlineClass = cl.isValue();
+        boolean isInlineClass = cl.isInlineClass();
         serializable = Serializable.class.isAssignableFrom(cl);
         externalizable = Externalizable.class.isAssignableFrom(cl);
 
--- a/src/java.base/share/classes/java/lang/Class.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java	Thu Jun 06 13:45:40 2019 -0700
@@ -62,8 +62,6 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.StringJoiner;
-import java.util.stream.Stream;
 import java.util.stream.Collectors;
 
 import jdk.internal.HotSpotIntrinsicCandidate;
@@ -197,9 +195,9 @@
      * @return a string representation of this class object.
      */
     public String toString() {
-        return (isValue() ? "inline " : "")
+        return (isInlineClass() ? "inline " : "")
                + (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
-               + getName() + (isValue() && isBoxType() ? "?" : "");
+               + getName() + (isInlineClass() && isIndirectType() ? "?" : "");
     }
 
     /**
@@ -260,8 +258,8 @@
                 if (isAnnotation()) {
                     sb.append('@');
                 }
-                if (isValue()) {
-                    sb.append("value");
+                if (isInlineClass()) {
+                    sb.append("inline");
                     sb.append(' ');
                 }
                 if (isInterface()) { // Note: all annotation types are interfaces
@@ -361,10 +359,6 @@
      * <p> If {@code name} denotes an array class, the component type of
      * the array class is loaded but not initialized.
      *
-     * <p> If {@code name} denotes a value class, this method returns
-     * the {@code Class} object representing the
-     * {@linkplain #asBoxType() box value type}.
-     *
      * <p> For example, in an instance method the expression:
      *
      * <blockquote>
@@ -445,10 +439,6 @@
      * the given name is a class defined in a different module, this method
      * returns {@code null} after the class is loaded. </p>
      *
-     * <p> If {@code name} denotes a value class, this method returns
-     * the {@code Class} object representing the
-     * {@linkplain #asBoxType() box value type}. </p>
-     *
      * <p> This method does not check whether the requested class is
      * accessible to its caller. </p>
      *
@@ -511,70 +501,92 @@
 
 
     /**
-     * Returns {@code true} if this class is a value class.
-     *
-     * @return {@code true} if this class is a value class.
+     * Returns {@code true} if this class is an inline class.
+     *
+     * @return {@code true} if this class is an inline class.
      */
-    public boolean isValue() {
-        int mods = this.getModifiers();
-        if ((mods & VALUE_TYPE) != 0) {
-            if ((mods & (Modifier.INTERFACE | Modifier.ABSTRACT)) != 0) {
-                throw new InternalError("inline class can't have ACC_INTERFACE or ACC_ABSTRACT set");
-            }
-            if (getSuperclass() != Object.class) {
-                throw new InternalError("Super class of an inline class must be java.lang.Object");
-            }
-            return true;
-        }
-        return false;
+    public boolean isInlineClass() {
+        return (this.getModifiers() & VALUE_TYPE) != 0;
     }
 
     /**
-     * Returns a {@code Class} object representing the <em>box type</em>
-     * of this class if this class is a {@linkplain #isValue() value class};
-     * otherwise, returns this class.
-     *
-     * <p> A value class has two {@code Class} representations,
-     * a null-free type or a nullable box type, that can be obtained
-     * by calling {@link #asValueType()} or {@link #asBoxType()} method
-     * for conversion.
-     *
-     * @return the box type of this class if this class is a value class;
-     *         otherwise, this class.
+     * Returns a {@code Class} object representing the primary type of
+     * this class.
+     *
+     * <p> For class {@code C}, {@code C.class} is the primary type of {@code C}.
+     * For a primitive type, the {@code Class} instance representing
+     * that primitive type is its primary type, for example {@code int.class}.
+     *
+     * @return the {@code Class} object representing the primary type of
+     *         this class
      */
     @HotSpotIntrinsicCandidate
-    public Class<T> asBoxType() {
-        return isValue() ? boxType : this;
+    public Class<T> asPrimaryType() {
+        return isInlineClass() ? inlineType : this;
     }
 
     /**
-     * Returns a {@code Class} object representing the <em>null-free value type</em>
-     * of this class if this class is a {@linkplain #isValue() value class};
-     * otherwise, returns {@code null}.
-     *
-     * <p> A value class has two {@code Class} representations,
-     * a null-free type or a nullable box type, that can be obtained
-     * by calling {@link #asValueType()} or {@link #asBoxType()} method
-     * for conversion.
-     *
-     * @return the unbox value type of this class if this class is a value class;
-     *         otherwise, {@code null}.
+     * Returns a {@code Class} object representing the <em>indirect projection</em>
+     * type if this class is an {@linkplain #isInlineClass() inline class};
+     * otherwise, returns this class.
+     *
+     * <p> An inline class, {@code V}, has two {@code Class} representations,
+     * {@code V.class} and its {@linkplain #asIndirectType() indirect projection
+     * type}.  The indirect projection type is always
+     * {@linkplain #isNullableType() nullable}.
+     * The indirect projection type of a zero-default inline class
+     * is also its nullable projection type.
+     *
+     * @return the {@code Class} object representing the indirect projection type of
+     *         this class if this class is an inline class; otherwise, this class.
      */
     @HotSpotIntrinsicCandidate
-    public Class<T> asValueType() {
-        return isValue() ? valueType : null;
+    public Class<T> asIndirectType() {
+        return isInlineClass() ? indirectType : this;
     }
 
-    /*
-     * Returns true if this class is a non-value class or a box value class.
+    /**
+     * Returns a {@code Class} object representing the <em>nullable projection</em>
+     * type if this class is an {@linkplain #isInlineClass() inline class};
+     * otherwise, returns this class.
+     *
+     * <p> An inline class, {@code V}, has two {@code Class} representations,
+     * {@code V.class} and its {@linkplain #asIndirectType() indirect projection
+     * type}.  The indirect projection type is always
+     * {@linkplain #isNullableType() nullable}.
+     * The indirect projection type of a zero-default inline class
+     * is also its nullable projection type.
+     *
+     * @return the {@code Class} object representing the nullable projection type of
+     *         this class if this class is an inline class; otherwise, this class.
      */
-    boolean isBoxType() {
-        return boxType == null || this == boxType;
+    public Class<T> asNullableType() {
+        return asIndirectType();
     }
 
-    // set by VM if this class is a value type
-    private transient Class<T> boxType;
-    private transient Class<T> valueType;
+    /**
+     * Returns {@code true} if this class is an indirect type.
+     * An indirect type is always {@linkplain #isNullableType() nullable}.
+     *
+     * @return {@code true} if this class is an indirect type.
+     */
+    public boolean isIndirectType() {
+        return indirectType == null || this == indirectType;
+    }
+
+    /**
+     * Returns {@code true} if this class is a nullable type.
+     *
+     * @return {@code true} if this class is a nullable type.
+     */
+    public boolean isNullableType() {
+        return isIndirectType();
+    }
+
+    // set by VM if this class is an inline type
+    // otherwise, these two fields are null
+    private transient Class<T> inlineType;
+    private transient Class<T> indirectType;
 
     /**
      * Creates a new instance of the class represented by this {@code Class}
@@ -634,7 +646,7 @@
     public T newInstance()
         throws InstantiationException, IllegalAccessException
     {
-        if (this.isValue()) {
+        if (this.isInlineClass()) {
             throw new IllegalAccessException(
                 "cannot create new instance of an inline class " + this.getName());
         }
@@ -854,7 +866,7 @@
      * <tr><th scope="row"> char         <td style="text-align:center"> C
      * <tr><th scope="row"> class or interface
      *                                   <td style="text-align:center"> L<i>classname</i>;
-     * <tr><th scope="row"> {@linkplain #asValueType() regular value class}
+     * <tr><th scope="row"> non-nullable {@linkplain #isInlineClass() inline class}
      *                                   <td style="text-align:center"> Q<i>classname</i>;
      * <tr><th scope="row"> double       <td style="text-align:center"> D
      * <tr><th scope="row"> float        <td style="text-align:center"> F
@@ -874,11 +886,13 @@
      * byte.class.getName()
      *     returns "byte"
      * Point.class.getName()
-     *     returns "p.Point"
+     *     returns "Point"
      * (new Object[3]).getClass().getName()
      *     returns "[Ljava.lang.Object;"
      * (new Point[3]).getClass().getName()
      *     returns "[QPoint;"
+     * (new Point?[3][4]).getClass().getName()
+     *     returns "[[LPoint;"
      * (new int[3][4][5][6][7][8][9]).getClass().getName()
      *     returns "[[[[[[[I"
      * </pre></blockquote>
@@ -1297,7 +1311,7 @@
      * @since   1.1
      */
     public Object[] getSigners() {
-        Class<?> c = (isValue() && !isBoxType()) ? asBoxType() : this;
+        Class<?> c = isInlineClass() && isIndirectType() ? asPrimaryType() : this;
         return c.getSigners0();
     }
 
@@ -1307,7 +1321,7 @@
      * Set the signers of this class.
      */
     void setSigners(Object[] signers) {
-        Class<?> c = (isValue() && !isBoxType()) ? asBoxType() : this;
+        Class<?> c = isInlineClass() && isIndirectType() ? asPrimaryType() : this;
         c.setSigners0(signers);
     }
 
@@ -1649,9 +1663,6 @@
      * component type with "[]" appended.  In particular the simple
      * name of an array whose component type is anonymous is "[]".
      *
-     * <p>The simple name of a value type is the simple name of
-     * this class with {@code ".box"} appended.
-     *
      * @return the simple name of the underlying class
      * @since 1.5
      */
@@ -1673,7 +1684,7 @@
             simpleName = getName();
             simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1); // strip the package name
         }
-        return isValue() && isBoxType() ? simpleName + ".box" : simpleName;
+        return simpleName;
     }
 
     /**
@@ -1694,8 +1705,7 @@
                 return cl.getTypeName() + "[]".repeat(dimensions);
             } catch (Throwable e) { /*FALLTHRU*/ }
         }
-        // ## append "/box" to box value type instead?
-        return isBoxType() ? getName() : getName() + "/val";
+        return toTypeName();
     }
 
     /**
@@ -3520,10 +3530,18 @@
                 ((argTypes == null || argTypes.length == 0) ?
                 "()" :
                 Arrays.stream(argTypes)
-                        .map(c -> c == null ? "null" : c.getName())
+                        .map(c -> c == null ? "null" : c.toTypeName())
                         .collect(Collectors.joining(",", "(", ")")));
     }
 
+    /*
+     * Returns the class name appended with "?" if it is the nullable projection
+     * of an inline class.
+     */
+    private String toTypeName() {
+        return isInlineClass() && isIndirectType() ? getName() + "?" : getName();
+    }
+
     /** use serialVersionUID from JDK 1.1 for interoperability */
     private static final long serialVersionUID = 3206093459760846163L;
 
@@ -3698,16 +3716,16 @@
      *
      * @throws ClassCastException if the object is not
      * {@code null} and is not assignable to the type T.
-     * @throws NullPointerException if this class is a {@linkplain #asValueType()
-     * null-free value class} and the object is {@code null}
+     * @throws NullPointerException if this is not a {@linkplain #isNullableType()
+     * nullable type} and the object is {@code null}
      *
      * @since 1.5
      */
     @SuppressWarnings("unchecked")
     @HotSpotIntrinsicCandidate
     public T cast(Object obj) {
-        if (isValue() && !isBoxType() && obj == null)
-            throw new NullPointerException(getName() + " is non-nullable value class");
+        if (!isNullableType() && obj == null)
+            throw new NullPointerException(getName() + " is an inline class");
 
         if (obj != null && !isInstance(obj))
             throw new ClassCastException(cannotCastMsg(obj));
--- a/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java	Thu Jun 06 13:45:40 2019 -0700
@@ -78,7 +78,7 @@
         if (!member.isStatic()) {
             if (!member.getDeclaringClass().isAssignableFrom(refc) || member.isConstructor())
                 throw new InternalError(member.toString());
-            mtype = mtype.insertParameterTypes(0, refc.isValue() ? refc.asValueType() : refc);
+            mtype = mtype.insertParameterTypes(0, refc.isInlineClass() ? refc.asPrimaryType() : refc);
         }
         if (!member.isField()) {
             // refKind reflects the original type of lookup via findSpecial or
@@ -111,13 +111,13 @@
             if (member.isStatic()) {
                 long offset = MethodHandleNatives.staticFieldOffset(member);
                 Object base = MethodHandleNatives.staticFieldBase(member);
-                return member.isValue() ? new StaticValueAccessor(mtype, lform, member, base, offset)
-                                        : new StaticAccessor(mtype, lform, member, base, offset);
+                return member.isInlineable() ? new StaticValueAccessor(mtype, lform, member, base, offset)
+                                                  : new StaticAccessor(mtype, lform, member, base, offset);
             } else {
                 long offset = MethodHandleNatives.objectFieldOffset(member);
                 assert(offset == (int)offset);
-                return  member.isValue() ? new ValueAccessor(mtype, lform, member, (int)offset)
-                                         : new Accessor(mtype, lform, member, (int)offset);
+                return  member.isInlineable() ? new ValueAccessor(mtype, lform, member, (int)offset)
+                                                   : new Accessor(mtype, lform, member, (int)offset);
 
             }
         }
@@ -136,8 +136,8 @@
     private static DirectMethodHandle makeAllocator(MemberName ctor) {
         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
         Class<?> instanceClass = ctor.getDeclaringClass();
-        if (instanceClass.isValue())
-            instanceClass = instanceClass.asValueType();  // convert to Q-Type
+        if (instanceClass.isInlineClass())
+            instanceClass = instanceClass.asPrimaryType();  // convert to Q-Type
         ctor = ctor.asConstructor();
         assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
@@ -667,12 +667,12 @@
         }
         if (shouldBeInitialized(m)) {
             // precompute the barrier-free version:
-            preparedFieldLambdaForm(formOp, m.isVolatile(), m.isValue(), m.isFlattened(), ftype);
+            preparedFieldLambdaForm(formOp, m.isVolatile(), m.isInlineable(), m.isFlattened(), ftype);
             assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
                    (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
             formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
         }
-        LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isValue(), m.isFlattened(), ftype);
+        LambdaForm lform = preparedFieldLambdaForm(formOp, m.isVolatile(), m.isInlineable(), m.isFlattened(), ftype);
         maybeCompile(lform, m);
         assert(lform.methodType().dropParameterTypes(0, 1)
                 .equals(m.getInvocationType().basicType()))
--- a/src/java.base/share/classes/java/lang/invoke/LambdaFormBuilder.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaFormBuilder.java	Thu Jun 06 13:45:40 2019 -0700
@@ -407,7 +407,7 @@
                 }
             }
             if (InvokerBytecodeGenerator.isStaticallyNameable(cls)) {
-                if (cls.isValue()) {
+                if (cls.isInlineClass()) {
                     checkvaluecast(cls);
                 } else {
                     checkcast(cls);
--- a/src/java.base/share/classes/java/lang/invoke/MemberName.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MemberName.java	Thu Jun 06 13:45:40 2019 -0700
@@ -191,7 +191,7 @@
      */
     public MethodType getInvocationType() {
         MethodType itype = getMethodOrFieldType();
-        Class<?> c = clazz.isValue() ? clazz.asValueType() : clazz;
+        Class<?> c = clazz.isInlineClass() ? clazz.asPrimaryType() : clazz;
         if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial)
             return itype.changeReturnType(c);
         if (!isStatic())
@@ -428,7 +428,7 @@
     /** Utility method to query the modifier flags of this member. */
     public boolean isFinal() {
         // all fields declared in a value type are effectively final
-        assert(!clazz.isValue() || !isField() || Modifier.isFinal(flags));
+        assert(!clazz.isInlineClass() || !isField() || Modifier.isFinal(flags));
         return Modifier.isFinal(flags);
     }
     /** Utility method to query whether this member or its defining class is final. */
@@ -473,11 +473,11 @@
     /** Query whether this member is a flattened field */
     public boolean isFlattened() { return (flags & FLATTENED) == FLATTENED; }
 
-    /** Query whether this member is a field of normal value type. */
-    public boolean isValue()  {
+    /** Query whether this member is a field of an inline class. */
+    public boolean isInlineable()  {
         if (isField()) {
             Class<?> type = getFieldType();
-            return type == type.asValueType();
+            return type.isInlineClass() && type == type.asPrimaryType();
         }
         return false;
     }
@@ -942,10 +942,19 @@
     }
     private static String getName(Object obj) {
         if (obj instanceof Class<?>)
-            return ((Class<?>)obj).getName();
+            return toTypeName((Class<?>)obj);
         return String.valueOf(obj);
     }
 
+    /*
+     * Returns the class name appended with "?" if it is the nullable projection
+     * of an inline class.
+     */
+    private static String toTypeName(Class<?> type) {
+        return type.isInlineClass() && type.isIndirectType() ? type.getName() + "?" : type.getName();
+    }
+
+
     public IllegalAccessException makeAccessException(String message, Object from) {
         message = message + ": "+ toString();
         if (from != null)  {
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java	Thu Jun 06 13:45:40 2019 -0700
@@ -153,8 +153,7 @@
     public int getReferenceKind();
 
     /**
-     * Returns the {@code Class} object representing {@linkplain Class#asBoxType() the box type}
-     * of the class in which the cracked method handle's underlying member was defined.
+     * Returns the class in which the cracked method handle's underlying member was defined.
      * @return the declaring class of the underlying member
      */
     public Class<?> getDeclaringClass();
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java	Thu Jun 06 13:45:40 2019 -0700
@@ -2655,7 +2655,7 @@
      */
     public static
     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
-        if (arrayClass.isValue()) {
+        if (arrayClass.isInlineClass()) {
             throw new UnsupportedOperationException();
         }
         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
@@ -3432,7 +3432,7 @@
         Objects.requireNonNull(type);
         if (type.isPrimitive()) {
             return zero(Wrapper.forPrimitiveType(type), type);
-        } else if (type.isValue()) {
+        } else if (type.isInlineClass()) {
             throw new UnsupportedOperationException();
         } else {
             return zero(Wrapper.OBJECT, type);
--- a/src/java.base/share/classes/java/lang/invoke/ValueBootstrapMethods.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/ValueBootstrapMethods.java	Thu Jun 06 13:45:40 2019 -0700
@@ -107,7 +107,7 @@
         }
 
         static MethodHandle[] getters(Lookup lookup, Comparator<MethodHandle> comparator) {
-            Class<?> type = lookup.lookupClass().asValueType();
+            Class<?> type = lookup.lookupClass().asPrimaryType();
             // filter static fields and synthetic fields
             Stream<MethodHandle> s = Arrays.stream(type.getDeclaredFields())
                 .filter(f -> !Modifier.isStatic(f.getModifiers()) && !f.isSynthetic())
@@ -173,8 +173,8 @@
          * of the given value class are substitutable.
          */
         static MethodHandle valueEquals(Class<?> c) {
-            assert c.isValue();
-            Class<?> type = c.asValueType();
+            assert c.isInlineClass();
+            Class<?> type = c.asPrimaryType();
             MethodType mt = methodType(boolean.class, type, type);
             MethodHandles.Lookup lookup = new MethodHandles.Lookup(type);
             MethodHandle[] getters = getters(lookup, TYPE_SORTER);
@@ -217,7 +217,7 @@
         private static boolean isSameValueClass(Object a, Object b) {
             if (a == null || b == null)
                 return false;
-            return a.getClass().isValue() && a.getClass().asBoxType() == b.getClass().asBoxType();
+            return a.getClass().isInlineClass() && a.getClass().asNullableType() == b.getClass().asNullableType();
         }
 
         private static boolean valueEq(Object a, Object b) {
@@ -348,7 +348,7 @@
      * Produces a method handle that computes the hashcode
      */
     private static MethodHandle hashCodeInvoker(Lookup lookup, String name, MethodType mt) {
-        Class<?> type = lookup.lookupClass().asValueType();
+        Class<?> type = lookup.lookupClass().asPrimaryType();
         MethodHandle target = dropArguments(constant(int.class, SALT), 0, type);
         MethodHandle cls = dropArguments(constant(Class.class, type),0, type);
         MethodHandle classHashCode = filterReturnValue(cls, hashCodeForType(Class.class));
@@ -376,7 +376,7 @@
      * Produces a method handle that invokes the toString method of a value object.
      */
     private static MethodHandle toStringInvoker(Lookup lookup, String name, MethodType mt) {
-        Class<?> type = lookup.lookupClass().asValueType();
+        Class<?> type = lookup.lookupClass().asPrimaryType();
         MethodHandle[] getters = MethodHandleBuilder.getters(lookup);
         int length = getters.length;
         StringBuilder format = new StringBuilder();
@@ -412,7 +412,7 @@
      * Produces a method handle that tests if two arguments are equals.
      */
     private static MethodHandle equalsInvoker(Lookup lookup, String name, MethodType mt) {
-        Class<?> type = lookup.lookupClass().asValueType();
+        Class<?> type = lookup.lookupClass().asPrimaryType();
         // MethodHandle to compare all fields of two value objects
         MethodHandle[] getters = MethodHandleBuilder.getters(lookup, TYPE_SORTER);
         MethodHandle accumulator = dropArguments(TRUE, 0, type, type);
@@ -528,9 +528,10 @@
             System.out.println("substitutable " + a + " vs " + b);
         }
         try {
-            Class<?> type = a.getClass().isValue() ? a.getClass().asValueType() : a.getClass();
+            Class<?> type = a.getClass().isInlineClass() ? a.getClass().asPrimaryType() : a.getClass();
             return (boolean) substitutableInvoker(type).invoke(a, b);
         } catch (Error|RuntimeException e) {
+            if (VERBOSE) e.printStackTrace();
             throw e;
         } catch (Throwable e) {
             if (VERBOSE) e.printStackTrace();
@@ -574,7 +575,7 @@
         if (type.isInterface() || type == Object.class)
             return MethodHandleBuilder.interfaceEquals(type);
 
-        if (type.isValue())
+        if (type.isInlineClass())
             return SUBST_TEST_METHOD_HANDLES.get(type);
 
         return MethodHandleBuilder.referenceEquals(type);
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu Jun 06 13:45:40 2019 -0700
@@ -1554,8 +1554,8 @@
             // the field type (value) is mapped to the return type of MethodType
             // the receiver type is mapped to a parameter type of MethodType
             // So use the value type as receiver may be a box type.
-            if (receiver != null && receiver.isValue())
-                receiver = receiver.asValueType();
+            if (receiver != null && receiver.isInlineClass())
+                receiver = receiver.asPrimaryType();
             switch (this) {
                 case GET:
                     ps = allocateParameters(0, receiver, intermediate);
--- a/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandles.java	Thu Jun 06 13:45:40 2019 -0700
@@ -43,7 +43,7 @@
                 } else {
                     return f.isFinal() && !isWriteAllowedOnFinalFields
                        ? new VarHandleReferences.FieldInstanceReadOnly(refc, foffset, type)
-                       : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type, f.isValue());
+                       : new VarHandleReferences.FieldInstanceReadWrite(refc, foffset, type, f.isInlineable());
                 }
             }
             else if (type == boolean.class) {
@@ -106,7 +106,7 @@
                 assert(!f.isFlattened());   // static field is not flattened
                 return f.isFinal() && !isWriteAllowedOnFinalFields
                        ? new VarHandleReferences.FieldStaticReadOnly(base, foffset, type)
-                       : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type, f.isValue());
+                       : new VarHandleReferences.FieldStaticReadWrite(base, foffset, type, f.isInlineable());
             }
             else if (type == boolean.class) {
                 return f.isFinal() && !isWriteAllowedOnFinalFields
@@ -200,7 +200,7 @@
             // the redundant componentType.isValue() check is there to
             // minimize the performance impact to non-value array.
             // It should be removed when Unsafe::isFlattenedArray is intrinsified.
-            return componentType.isValue() && UNSAFE.isFlattenedArray(arrayClass)
+            return componentType.isInlineClass() && UNSAFE.isFlattenedArray(arrayClass)
                 ? new VarHandleReferences.ValueArray(aoffset, ashift, arrayClass)
                 : new VarHandleReferences.Array(aoffset, ashift, arrayClass);
         }
--- a/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java	Thu Jun 06 13:45:40 2019 -0700
@@ -300,7 +300,7 @@
 
         // does not allow to suppress access check for Value class's
         // constructor or field
-        if (declaringClass.isValue()) {
+        if (declaringClass.isInlineClass()) {
             if (this instanceof Constructor) return false;
             if (this instanceof Field && Modifier.isFinal(modifiers)) return false;
         }
--- a/src/java.base/share/classes/java/lang/reflect/Constructor.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Constructor.java	Thu Jun 06 13:45:40 2019 -0700
@@ -180,7 +180,7 @@
         AccessibleObject.checkPermission();
 
         if (flag) {
-            if (clazz.isValue()) {
+            if (clazz.isInlineClass()) {
                 throw new InaccessibleObjectException(
                     "Unable to make an inline class constructor \"" + this + "\" accessible");
             }
@@ -210,8 +210,7 @@
     }
 
     /**
-     * Returns the {@code Class} object representing
-     * {@linkplain Class#asBoxType() the box type} of the class that
+     * Returns the {@code Class} object representing the class that
      * declares the constructor represented by this object.
      */
     @Override
@@ -483,7 +482,7 @@
         throws InstantiationException, IllegalAccessException,
                IllegalArgumentException, InvocationTargetException
     {
-        if (clazz.isValue()) {
+        if (clazz.isInlineClass()) {
             throw new IllegalAccessException(
                 "cannot create new instance of an inline class " + clazz.getName());
         }
--- a/src/java.base/share/classes/java/lang/reflect/Field.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Field.java	Thu Jun 06 13:45:40 2019 -0700
@@ -168,7 +168,7 @@
     public void setAccessible(boolean flag) {
         AccessibleObject.checkPermission();
 
-        if (clazz.isValue()) {
+        if (clazz.isInlineClass()) {
             throw new InaccessibleObjectException("cannot make a field accessible of inline class "
                     + clazz.getName());
         }
@@ -184,8 +184,7 @@
     }
 
     /**
-     * Returns the {@code Class} object representing
-     * {@linkplain Class#asBoxType() the box type} of the class or interface
+     * Returns the {@code Class} object representing the class or interface
      * that declares the field represented by this {@code Field} object.
      */
     @Override
@@ -1107,7 +1106,7 @@
      * Ensure the declaring class is not an inline class.
      */
     private void ensureNotValueClass() throws IllegalAccessException {
-        if (clazz.isValue()) {
+        if (clazz.isInlineClass()) {
             throw new IllegalAccessException("cannot set field \"" + this + "\" of inline class "
                 + clazz.getName());
         }
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Thu Jun 06 13:45:40 2019 -0700
@@ -214,8 +214,7 @@
     }
 
     /**
-     * Returns the {@code Class} object representing
-     * {@linkplain Class#asBoxType() the box type} of the class or interface
+     * Returns the {@code Class} object representing the class or interface
      * that declares the method represented by this object.
      *
      */
--- a/src/java.base/share/classes/java/lang/reflect/Modifier.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Modifier.java	Thu Jun 06 13:45:40 2019 -0700
@@ -340,7 +340,6 @@
     static final int ANNOTATION  = 0x00002000;
     static final int ENUM        = 0x00004000;
     static final int MANDATED    = 0x00008000;
-    static final int FLATTENABLE = 0x00000100;
     static final int FLATTENED   = 0x00008000;      // HotSpot-specific bit
     static boolean isSynthetic(int mod) {
       return (mod & SYNTHETIC) != 0;
--- a/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu Jun 06 13:45:40 2019 -0700
@@ -849,11 +849,12 @@
         private static void ensureVisible(ClassLoader ld, Class<?> c) {
             Class<?> type = null;
             try {
+                if (c.isInlineClass() && c.isIndirectType())
+                    c = c.asPrimaryType();
                 type = Class.forName(c.getName(), false, ld);
             } catch (ClassNotFoundException e) {
             }
-            // use box type to do visibility check
-            if (type != c.asBoxType()) {
+            if (type != c) {
                 throw new IllegalArgumentException(c.getName() +
                         " referenced from a method is not visible from class loader");
             }
--- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Thu Jun 06 13:45:40 2019 -0700
@@ -1426,11 +1426,11 @@
             "java/lang/Class",
             "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
 
-        if (cl.isValue() && cl == cl.asValueType()) {
+        if (cl.isInlineClass() && cl == cl.asPrimaryType()) {
             out.writeByte(opc_invokevirtual);
             out.writeShort(cp.getMethodRef(
                 "java/lang/Class",
-                "asValueType", "()Ljava/lang/Class;"));
+                "asPrimaryType", "()Ljava/lang/Class;"));
         }
     }
 
@@ -1495,8 +1495,12 @@
              */
             return type.getName().replace('.', '/');
         } else {
-            char prefix = type.isValue() && type == type.asValueType() ? 'Q' : 'L';
-            return prefix + dotToSlash(type.getName()) + ";";
+            if (type.isInlineClass()) {
+                Class<?> primary = type.asPrimaryType();
+                return (type == primary ? 'Q' : 'L' ) + dotToSlash(primary.getName()) + ";";
+            } else {
+                return 'L' + dotToSlash(type.getName()) + ";";
+            }
         }
     }
 
--- a/src/java.base/share/classes/jdk/experimental/value/MethodHandleBuilder.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/jdk/experimental/value/MethodHandleBuilder.java	Thu Jun 06 13:45:40 2019 -0700
@@ -174,14 +174,14 @@
                 if (aClass.isArray()) {
                     return classToInternalName(aClass);
                 } else {
-                    return (aClass.isValue() ? "Q" : "L") + classToInternalName(aClass) + ";";
+                    return (aClass.isInlineClass() ? "Q" : "L") + classToInternalName(aClass) + ";";
                 }
             }
 
             @Override
             public boolean isValue(String desc) {
                 Class<?> aClass = symbol(desc);
-                return aClass != null && aClass.isValue();
+                return aClass != null && aClass.isInlineClass();
             }
 
             @Override
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Thu Jun 06 13:45:40 2019 -0700
@@ -177,13 +177,6 @@
     @HotSpotIntrinsicCandidate
     public native void putInt(Object o, long offset, int x);
 
-    /**
-     * Returns true if the given class is a regular value type.
-     */
-    public boolean isValueType(Class<?> c) {
-        return c.isValue() && c == c.asValueType();
-    }
-
     private static final int JVM_ACC_FLATTENED = 0x00008000; // HotSpot-specific bit
 
     /**
@@ -234,7 +227,7 @@
      * @param offset indication of where the variable resides in a Java heap
      *        object, if any, else a memory address locating the variable
      *        statically
-     * @param vc value class
+     * @param vc inline class
      * @param <V> the type of a value
      * @return the value fetched from the indicated Java variable
      * @throws RuntimeException No defined exceptions are thrown, not even
@@ -254,7 +247,7 @@
      * @param offset indication of where the variable resides in a Java heap
      *        object, if any, else a memory address locating the variable
      *        statically
-     * @param vc value class
+     * @param vc inline class
      * @param v the value to store into the indicated Java variable
      * @param <V> the type of a value
      * @throws RuntimeException No defined exceptions are thrown, not even
@@ -266,14 +259,14 @@
     /**
      * Fetches a reference value of type {@code vc} from a given Java variable.
      * This method can return a reference to a value or a null reference
-     * for a boxed value type.
+     * for a nullable-projection of an inline type.
      *
-     * @param vc value class
+     * @param vc inline class
      */
     public Object getReference(Object o, long offset, Class<?> vc) {
         Object ref = getReference(o, offset);
-        if (ref == null && isValueType(vc)) {
-            // If the type of the returned reference is a normal value type
+        if (ref == null && vc.isInlineClass() && !vc.isIndirectType()) {
+            // If the type of the returned reference is a regular inline type
             // return an uninitialized default value if null
             ref = uninitializedDefaultValue(vc);
         }
@@ -282,8 +275,8 @@
 
     public Object getReferenceVolatile(Object o, long offset, Class<?> vc) {
         Object ref = getReferenceVolatile(o, offset);
-        if (ref == null && isValueType(vc)) {
-            // If the type of the returned reference is a normal value type
+        if (ref == null && vc.isInlineClass() && !vc.isIndirectType()) {
+            // If the type of the returned reference is a regular inline type
             // return an uninitialized default value if null
             ref = uninitializedDefaultValue(vc);
         }
@@ -291,7 +284,7 @@
     }
 
     /**
-     * Returns an uninitialized default value of the given value class.
+     * Returns an uninitialized default value of the given inline class.
      */
     public native <V> V uninitializedDefaultValue(Class<?> vc);
 
@@ -316,11 +309,11 @@
     public native <V> V finishPrivateBuffer(V value);
 
     /**
-     * Returns the header size of the given value class
+     * Returns the header size of the given inline class
      *
-     * @param vc Value class
+     * @param vc inline class
      * @param <V> value clas
-     * @return the header size of the value class
+     * @return the header size of the inline class
      */
     public native <V> long valueHeaderSize(Class<V> vc);
 
@@ -2172,8 +2165,8 @@
 
     /**
      * Global lock for atomic and volatile strength access to any value of
-     * a value type.  This is a temporary workaround until better localized
-     * atomic access mechanisms are supported for value types.
+     * an inline type.  This is a temporary workaround until better localized
+     * atomic access mechanisms are supported for inline types.
      */
     private static final Object valueLock = new Object();
 
--- a/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/org/objectweb/asm/Type.java	Thu Jun 06 13:45:40 2019 -0700
@@ -59,6 +59,7 @@
 package jdk.internal.org.objectweb.asm;
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 /**
@@ -667,13 +668,11 @@
             stringBuilder.append(descriptor);
         } else {
             String name = currentClass.getName();
-            // Workarounds nasgen build that depends on ASM but compiled with
-            // the bootstrap JDK.  Can't use Class::isValue and Class::asValueType
-            int index = currentClass.getTypeName().lastIndexOf("/val");
-            if (index > 0) {
+            if (Helper.isIndirectType(currentClass)) {
+                stringBuilder.append('L');
+            } else {
                 stringBuilder.append('Q');
-            } else {
-                stringBuilder.append('L');
+
             }
             int nameLength = name.length();
             for (int i = 0; i < nameLength; ++i) {
@@ -684,6 +683,34 @@
         }
     }
 
+    // Workarounds nasgen build that depends on ASM but compiled with
+    // the bootstrap JDK.  Can't reference Class::isIndirectType
+    static class Helper {
+        static final Method isIndirectTypeMethod = isIndirectTypeMethod();
+        static Method isIndirectTypeMethod() {
+            try {
+                return Class.class.getMethod("isIndirectType");
+            } catch (NoSuchMethodException e) {
+                return null;
+            }
+        }
+
+        static boolean isIndirectType(Class<?> clazz) {
+            int mods = clazz.getModifiers();
+            if ((mods & 0x00000100) != 0) {            // inline class
+                assert isIndirectTypeMethod != null;
+                try {
+                    return (boolean) isIndirectTypeMethod.invoke(clazz);
+                } catch (InvocationTargetException e) {
+                    throw new InternalError(e.getCause());
+                } catch (IllegalAccessException e) {
+                    throw new InternalError(e);
+                }
+            }
+            return true;
+        }
+    }
+
     // -----------------------------------------------------------------------------------------------
     // Methods to get the sort, dimension, size, and opcodes corresponding to a Type or descriptor.
     // -----------------------------------------------------------------------------------------------
--- a/src/java.base/share/classes/jdk/internal/reflect/AccessorGenerator.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/reflect/AccessorGenerator.java	Thu Jun 06 13:45:40 2019 -0700
@@ -420,11 +420,17 @@
             return "[" + getClassName(c.getComponentType(), true);
         } else {
             if (addPrefixAndSuffixForNonPrimitiveTypes) {
-                if (unsafe.isValueType(c)) {
-                    return internalize('Q' + c.getName() + ";");
+                final String desc;
+                if (c.isInlineClass()) {
+                    if (c == c.asPrimaryType()) {
+                        desc = 'Q' + c.getName() + ";";
+                    } else {
+                        desc = 'L' + c.asPrimaryType().getName() + ";";
+                    }
                 } else {
-                    return internalize('L' + c.getName() + ";");
+                    desc = 'L' + c.getName() + ";";
                 }
+                return internalize(desc);
             } else {
                 return internalize(c.getName());
             }
--- a/src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorImpl.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/jdk/internal/reflect/UnsafeFieldAccessorImpl.java	Thu Jun 06 13:45:40 2019 -0700
@@ -64,7 +64,7 @@
     }
 
     protected boolean canBeNull() {
-        return field.getType() == field.getType().asBoxType();
+        return field.getType().isNullableType();
     }
 
     protected Object checkValue(Object value) {
--- a/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/sun/invoke/util/BytecodeDescriptor.java	Thu Jun 06 13:45:40 2019 -0700
@@ -93,7 +93,7 @@
                 Class<?> clz = (loader == null)
                                     ? Class.forName(name, false, null)
                                     : loader.loadClass(name);
-                return c == 'Q' ? clz.asValueType() : clz.asBoxType();
+                return c == 'Q' ? clz.asPrimaryType() : clz.asIndirectType();
             } catch (ClassNotFoundException ex) {
                 throw new TypeNotPresentException(name, ex);
             }
@@ -158,7 +158,7 @@
             sb.append("Ljava/lang/Object;");
         } else {
             boolean lsemi = (!t.isArray());
-            if (t == t.asValueType())
+            if (!t.isIndirectType())
                 c = 'Q';
             if (lsemi)  sb.append(c);
             sb.append(t.getName().replace('.', '/'));
--- a/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java	Thu Jun 06 13:45:40 2019 -0700
@@ -236,7 +236,8 @@
      * @param refc the class attempting to make the reference
      */
     public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
-        if (type.asBoxType() == refc.asBoxType()) {
+        // FIXME: should use asPrimaryType after intrinsified method is updated.
+        if (type.asIndirectType() == refc.asIndirectType()) {
             return true;  // easy check
         }
         while (type.isArray())  type = type.getComponentType();
@@ -284,6 +285,10 @@
         // that differs from "type"; this happens once due to JVM system dictionary
         // memoization.  And the caller never gets to look at the alternate type binding
         // ("res"), whether it exists or not.
+
+        if (type.isInlineClass()) {
+            type = type.asPrimaryType();
+        }
         final String name = type.getName();
         Class<?> res = java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedAction<>() {
@@ -295,7 +300,7 @@
                         }
                     }
             });
-        return (type.asBoxType() == res);
+        return (type == res);
     }
 
     /**
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestIntrinsics.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestIntrinsics.java	Thu Jun 06 13:45:40 2019 -0700
@@ -26,6 +26,7 @@
 import java.lang.reflect.Array;
 import java.lang.reflect.Field;
 import java.util.Arrays;
+import java.util.List;
 
 import jdk.test.lib.Asserts;
 import jdk.internal.misc.Unsafe;
@@ -67,30 +68,32 @@
 
     public void test1_verifier(boolean warmup) {
         Asserts.assertTrue(test1(java.util.AbstractList.class, java.util.ArrayList.class), "test1_1 failed");
-        Asserts.assertTrue(test1(MyValue1.class.asBoxType(), MyValue1.class.asBoxType()), "test1_2 failed");
-        Asserts.assertTrue(test1(MyValue1.class.asValueType(), MyValue1.class.asValueType()), "test1_3 failed");
-        Asserts.assertTrue(test1(MyValue1.class.asBoxType(), MyValue1.class.asValueType()), "test1_4 failed");
-        Asserts.assertTrue(test1(MyValue1.class.asValueType(), MyValue1.class.asBoxType()), "test1_5 failed");
+        Asserts.assertTrue(test1(MyValue1.class.asIndirectType(), MyValue1.class.asIndirectType()), "test1_2 failed");
+        Asserts.assertTrue(test1(MyValue1.class, MyValue1.class), "test1_3 failed");
+        Asserts.assertTrue(test1(MyValue1.class.asIndirectType(), MyValue1.class), "test1_4 failed");
+        // enable the following test case  when JDK-8225317 is fixed
+        // Asserts.assertFalse(test1(MyValue1.class, MyValue1.class.asIndirectType()), "test1_5 failed");
         Asserts.assertTrue(test1(Object.class, java.util.ArrayList.class), "test1_6 failed");
-        Asserts.assertTrue(test1(Object.class, MyValue1.class.asBoxType()), "test1_7 failed");
-        Asserts.assertTrue(test1(Object.class, MyValue1.class.asValueType()), "test1_8 failed");
-        Asserts.assertTrue(!test1(MyValue1.class.asBoxType(), Object.class), "test1_9 failed");
-        Asserts.assertTrue(!test1(MyValue1.class.asValueType(), Object.class), "test1_10 failed");
+        Asserts.assertTrue(test1(Object.class, MyValue1.class.asIndirectType()), "test1_7 failed");
+        Asserts.assertTrue(test1(Object.class, MyValue1.class), "test1_8 failed");
+        Asserts.assertTrue(!test1(MyValue1.class.asIndirectType(), Object.class), "test1_9 failed");
+        Asserts.assertTrue(!test1(MyValue1.class, Object.class), "test1_10 failed");
     }
 
     // Verify that Class::isAssignableFrom checks with statically known classes are folded
     @Test(failOn = LOADK)
     public boolean test2() {
         boolean check1 = java.util.AbstractList.class.isAssignableFrom(java.util.ArrayList.class);
-        boolean check2 = MyValue1.class.asBoxType().isAssignableFrom(MyValue1.class.asBoxType());
-        boolean check3 = MyValue1.class.asValueType().isAssignableFrom(MyValue1.class.asValueType());
-        boolean check4 = MyValue1.class.asBoxType().isAssignableFrom(MyValue1.class.asValueType());
-        boolean check5 = MyValue1.class.asValueType().isAssignableFrom(MyValue1.class.asBoxType());
+        boolean check2 = MyValue1.class.asIndirectType().isAssignableFrom(MyValue1.class.asIndirectType());
+        boolean check3 = MyValue1.class.isAssignableFrom(MyValue1.class);
+        boolean check4 = MyValue1.class.asIndirectType().isAssignableFrom(MyValue1.class);
+        // enable the following test case when JDK-8225317 is fixed
+        boolean check5 = true; // !MyValue1.class.isAssignableFrom(MyValue1.class.asIndirectType());
         boolean check6 = Object.class.isAssignableFrom(java.util.ArrayList.class);
-        boolean check7 = Object.class.isAssignableFrom(MyValue1.class.asBoxType());
-        boolean check8 = Object.class.isAssignableFrom(MyValue1.class.asValueType());
-        boolean check9 = !MyValue1.class.asBoxType().isAssignableFrom(Object.class);
-        boolean check10 = !MyValue1.class.asValueType().isAssignableFrom(Object.class);
+        boolean check7 = Object.class.isAssignableFrom(MyValue1.class.asIndirectType());
+        boolean check8 = Object.class.isAssignableFrom(MyValue1.class);
+        boolean check9 = !MyValue1.class.asIndirectType().isAssignableFrom(Object.class);
+        boolean check10 = !MyValue1.class.isAssignableFrom(Object.class);
         return check1 && check2 && check3 && check4 && check5 && check6 && check7 && check8 && check9 && check10;
     }
 
@@ -106,8 +109,8 @@
 
     public void test3_verifier(boolean warmup) {
         Asserts.assertTrue(test3(Object.class) == null, "test3_1 failed");
-        Asserts.assertTrue(test3(MyValue1.class.asBoxType()) == Object.class, "test3_2 failed");
-        Asserts.assertTrue(test3(MyValue1.class.asValueType()) == Object.class, "test3_3 failed");
+        Asserts.assertTrue(test3(MyValue1.class.asIndirectType()) == Object.class, "test3_2 failed");
+        Asserts.assertTrue(test3(MyValue1.class.asPrimaryType()) == Object.class, "test3_3 failed");
         Asserts.assertTrue(test3(Class.class) == Object.class, "test3_4 failed");
     }
 
@@ -115,8 +118,8 @@
     @Test(failOn = LOADK)
     public boolean test4() {
         boolean check1 = Object.class.getSuperclass() == null;
-        boolean check2 = MyValue1.class.asBoxType().getSuperclass() == Object.class;
-        boolean check3 = MyValue1.class.asValueType().getSuperclass() == Object.class;
+        boolean check2 = MyValue1.class.asIndirectType().getSuperclass() == Object.class;
+        boolean check3 = MyValue1.class.asPrimaryType().getSuperclass() == Object.class;
         boolean check4 = Class.class.getSuperclass() == Object.class;
         return check1 && check2 && check3 && check4;
     }
@@ -161,7 +164,7 @@
     public void test7_verifier(boolean warmup) {
         int len = Math.abs(rI) % 42;
         long hash = MyValue1.createDefaultDontInline().hashPrimitive();
-        Object[] va = test7(MyValue1.class.asValueType(), len);
+        Object[] va = test7(MyValue1.class, len);
         for (int i = 0; i < len; ++i) {
             Asserts.assertEQ(((MyValue1)va[i]).hashPrimitive(), hash);
         }
@@ -176,9 +179,9 @@
     @DontCompile
     public void test8_verifier(boolean warmup) {
         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
-        boolean result = test8(MyValue1.class.asValueType(), vt);
+        boolean result = test8(MyValue1.class, vt);
         Asserts.assertTrue(result);
-        result = test8(MyValue1.class.asBoxType(), vt);
+        result = test8(MyValue1.class.asIndirectType(), vt);
         Asserts.assertTrue(result);
     }
 
@@ -190,9 +193,9 @@
     @DontCompile
     public void test9_verifier(boolean warmup) {
         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
-        boolean result = test9(MyValue2.class.asValueType(), vt);
+        boolean result = test9(MyValue2.class, vt);
         Asserts.assertFalse(result);
-        result = test9(MyValue2.class.asBoxType(), vt);
+        result = test9(MyValue2.class.asIndirectType(), vt);
         Asserts.assertFalse(result);
     }
 
@@ -205,7 +208,7 @@
     @DontCompile
     public void test10_verifier(boolean warmup) {
         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
-        Object result = test10(MyValue1.class.asValueType(), vt);
+        Object result = test10(MyValue1.class, vt);
         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
     }
 
@@ -218,7 +221,7 @@
     public void test11_verifier(boolean warmup) {
         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
         try {
-            test11(MyValue2.class.asValueType(), vt);
+            test11(MyValue2.class, vt);
             throw new RuntimeException("should have thrown");
         } catch (ClassCastException cce) {
         }
@@ -226,7 +229,7 @@
 
     @Test()
     public Object test12(MyValue1 vt) {
-        return MyValue1.class.asValueType().cast(vt);
+        return MyValue1.class.cast(vt);
     }
 
     @DontCompile
@@ -238,7 +241,7 @@
 
     @Test()
     public Object test13(MyValue1 vt) {
-        return MyValue2.class.asValueType().cast(vt);
+        return MyValue2.class.cast(vt);
     }
 
     @DontCompile
@@ -254,7 +257,7 @@
     // value type array creation via reflection
     @Test()
     public void test14(int len, long hash) {
-        Object[] va = (Object[])Array.newInstance(MyValue1.class.asValueType().asBoxType().asValueType(), len);
+        Object[] va = (Object[])Array.newInstance(MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), len);
         for (int i = 0; i < len; ++i) {
             Asserts.assertEQ(((MyValue1)va[i]).hashPrimitive(), hash);
         }
@@ -354,11 +357,11 @@
     private static final boolean V1_FLATTENED;
     static {
         try {
-            Field xField = MyValue1.class.asValueType().getDeclaredField("x");
+            Field xField = MyValue1.class.getDeclaredField("x");
             X_OFFSET = U.objectFieldOffset(xField);
-            Field yField = MyValue1.class.asValueType().getDeclaredField("y");
+            Field yField = MyValue1.class.getDeclaredField("y");
             Y_OFFSET = U.objectFieldOffset(yField);
-            Field v1Field = MyValue1.class.asValueType().getDeclaredField("v1");
+            Field v1Field = MyValue1.class.getDeclaredField("v1");
             V1_OFFSET = U.objectFieldOffset(v1Field);
             V1_FLATTENED = U.isFlattened(v1Field);
         } catch (Exception e) {
@@ -449,7 +452,7 @@
         Class<?>[] ca = new Class<?>[1];
         for (int i = 0; i < 1; ++i) {
           // Folds during loop opts
-          ca[i] = MyValue1.class.asValueType();
+          ca[i] = MyValue1.class.asPrimaryType();
         }
         return Array.newInstance(ca[0], 1);
     }
@@ -534,7 +537,7 @@
     @Test(failOn=CALL_Unsafe)
     public MyValue2 test30(MyValue1 v) {
         if (V1_FLATTENED) {
-            return U.getValue(v, V1_OFFSET, MyValue2.class.asValueType().asBoxType().asValueType());
+            return U.getValue(v, V1_OFFSET, MyValue2.class.asPrimaryType().asIndirectType().asPrimaryType());
         }
         return (MyValue2)U.getReference(v, V1_OFFSET);
     }
@@ -563,7 +566,7 @@
     @Test(failOn=CALL_Unsafe)
     public MyValue1 test31() {
         if (TEST31_VT_FLATTENED) {
-            return U.getValue(this, TEST31_VT_OFFSET, MyValue1.class.asValueType().asBoxType().asValueType());
+            return U.getValue(this, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
         }
         return (MyValue1)U.getReference(this, TEST31_VT_OFFSET);
     }
@@ -579,7 +582,7 @@
     @Test(failOn=CALL_Unsafe)
     public void test32(MyValue1 vt) {
         if (TEST31_VT_FLATTENED) {
-            U.putValue(this, TEST31_VT_OFFSET, MyValue1.class.asValueType().asBoxType().asValueType(), vt);
+            U.putValue(this, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), vt);
         } else {
             U.putReference(this, TEST31_VT_OFFSET, vt);
         }
@@ -609,7 +612,7 @@
     @Test(failOn=CALL_Unsafe)
     public MyValue1 test33(MyValue1[] arr) {
         if (TEST33_FLATTENED_ARRAY) {
-            return U.getValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.class.asValueType().asBoxType().asValueType());
+            return U.getValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
         }
         return (MyValue1)U.getReference(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE);
     }
@@ -627,7 +630,7 @@
     @Test(failOn=CALL_Unsafe)
     public void test34(MyValue1[] arr, MyValue1 vt) {
         if (TEST33_FLATTENED_ARRAY) {
-            U.putValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.class.asValueType().asBoxType().asValueType(), vt);
+            U.putValue(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), vt);
         } else {
             U.putReference(arr, TEST33_BASE_OFFSET + TEST33_INDEX_SCALE, vt);
         }
@@ -646,7 +649,7 @@
     @Test(failOn=CALL_Unsafe)
     public MyValue1 test35(Object o) {
         if (TEST31_VT_FLATTENED) {
-            return U.getValue(o, TEST31_VT_OFFSET, MyValue1.class.asValueType().asBoxType().asValueType());
+            return U.getValue(o, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
         }
         return (MyValue1)U.getReference(o, TEST31_VT_OFFSET);
     }
@@ -663,7 +666,7 @@
     @Test(failOn=CALL_Unsafe)
     public MyValue1 test36(long offset) {
         if (TEST31_VT_FLATTENED) {
-            return U.getValue(this, offset, MyValue1.class.asValueType().asBoxType().asValueType());
+            return U.getValue(this, offset, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType());
         }
         return (MyValue1)U.getReference(this, offset);
     }
@@ -680,7 +683,7 @@
     @Test(failOn=CALL_Unsafe)
     public void test37(Object o, MyValue1 vt) {
         if (TEST31_VT_FLATTENED) {
-            U.putValue(o, TEST31_VT_OFFSET, MyValue1.class.asValueType().asBoxType().asValueType(), vt);
+            U.putValue(o, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), vt);
         } else {
             U.putReference(o, TEST31_VT_OFFSET, vt);
         }
@@ -699,7 +702,7 @@
     @Test(match = { CALL_Unsafe }, matchCount = { 1 })
     public void test38(Object o) {
         if (TEST31_VT_FLATTENED) {
-            U.putValue(this, TEST31_VT_OFFSET, MyValue1.class.asValueType().asBoxType().asValueType(), o);
+            U.putValue(this, TEST31_VT_OFFSET, MyValue1.class.asPrimaryType().asIndirectType().asPrimaryType(), o);
         } else {
             U.putReference(this, TEST31_VT_OFFSET, o);
         }
@@ -738,7 +741,7 @@
     @DontCompile
     public void test40_verifier(boolean warmup) {
         int len = Math.abs(rI) % 42;
-        Object[] va = test40(MyValue1.class.asBoxType(), len);
+        Object[] va = test40(MyValue1.class.asIndirectType(), len);
         for (int i = 0; i < len; ++i) {
             Asserts.assertEQ(va[i], null);
         }
@@ -753,9 +756,9 @@
     @DontCompile
     public void test41_verifier(boolean warmup) {
         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
-        boolean result = test41(MyValue1.class.asBoxType(), vt);
+        boolean result = test41(MyValue1.class.asIndirectType(), vt);
         Asserts.assertTrue(result);
-        result = test41(MyValue1.class.asValueType(), vt);
+        result = test41(MyValue1.class, vt);
         Asserts.assertTrue(result);
     }
 
@@ -767,9 +770,9 @@
     @DontCompile
     public void test42_verifier(boolean warmup) {
         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
-        boolean result = test42(MyValue2.class.asBoxType(), vt);
+        boolean result = test42(MyValue2.class.asIndirectType(), vt);
         Asserts.assertFalse(result);
-        result = test42(MyValue2.class.asValueType(), vt);
+        result = test42(MyValue2.class, vt);
         Asserts.assertFalse(result);
     }
 
@@ -782,9 +785,9 @@
     @DontCompile
     public void test43_verifier(boolean warmup) {
         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
-        Object result = test43(MyValue1.class.asBoxType(), vt);
+        Object result = test43(MyValue1.class.asIndirectType(), vt);
         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
-        result = test43(MyValue1.class.asBoxType(), null);
+        result = test43(MyValue1.class.asIndirectType(), null);
         Asserts.assertEQ(result, null);
     }
 
@@ -797,7 +800,7 @@
     public void test44_verifier(boolean warmup) {
         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
         try {
-            test44(MyValue2.class.asBoxType(), vt);
+            test44(MyValue2.class.asIndirectType(), vt);
             throw new RuntimeException("should have thrown");
         } catch (ClassCastException cce) {
         }
@@ -805,7 +808,7 @@
 
     @Test()
     public Object test45(MyValue1? vt) {
-        return MyValue1.class.asBoxType().cast(vt);
+        return MyValue1.class.asIndirectType().cast(vt);
     }
 
     @DontCompile
@@ -819,7 +822,7 @@
 
     @Test()
     public Object test46(MyValue1? vt) {
-        return MyValue2.class.asBoxType().cast(vt);
+        return MyValue2.class.asIndirectType().cast(vt);
     }
 
     @DontCompile
@@ -835,7 +838,7 @@
 
     @Test()
     public Object test47(MyValue1? vt) {
-        return MyValue1.class.asValueType().cast(vt);
+        return MyValue1.class.asPrimaryType().cast(vt);
     }
 
     @DontCompile
@@ -858,10 +861,10 @@
     @DontCompile
     public void test48_verifier(boolean warmup) {
         MyValue1? vt = MyValue1.createWithFieldsInline(rI, rL);
-        Object result = test48(MyValue1.class.asValueType(), vt);
+        Object result = test48(MyValue1.class, vt);
         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
         try {
-            test48(MyValue1.class.asValueType(), null);
+            test48(MyValue1.class, null);
             throw new RuntimeException("should have thrown");
         } catch (NullPointerException npe) {
         }
@@ -869,7 +872,7 @@
 
     @Test()
     public Object test49(MyValue1 vt) {
-        return MyValue1.class.asBoxType().cast(vt);
+        return MyValue1.class.asIndirectType().cast(vt);
     }
 
     @DontCompile
@@ -889,9 +892,9 @@
         MyValue1 vt = MyValue1.createWithFieldsInline(rI, rL);
         MyValue1[] va  = new MyValue1[42];
         MyValue1?[] vba = new MyValue1?[42];
-        Object result = test50(MyValue1.class.asValueType(), vt);
+        Object result = test50(MyValue1.class, vt);
         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
-        result = test50(MyValue1.class.asBoxType(), vt);
+        result = test50(MyValue1.class.asIndirectType(), vt);
         Asserts.assertEQ(((MyValue1)result).hash(), vt.hash());
         result = test50(MyValue1[].class, va);
         Asserts.assertEQ(result, va);
@@ -900,7 +903,7 @@
         result = test50(MyValue1?[].class, va);
         Asserts.assertEQ(result, va);
         try {
-            test50(MyValue1.class.asValueType(), null);
+            test50(MyValue1.class, null);
             throw new RuntimeException("should have thrown");
         } catch (NullPointerException npe) {
         }
@@ -914,7 +917,7 @@
     // value type array creation via reflection
     @Test()
     public void test51(int len) {
-        Object[] va = (Object[])Array.newInstance(MyValue1.class.asBoxType().asValueType().asBoxType(), len);
+        Object[] va = (Object[])Array.newInstance(MyValue1.class.asIndirectType().asPrimaryType().asIndirectType(), len);
         for (int i = 0; i < len; ++i) {
             Asserts.assertEQ(va[i], null);
         }
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestLWorld.java	Thu Jun 06 13:45:40 2019 -0700
@@ -24,7 +24,6 @@
 package compiler.valhalla.valuetypes;
 
 import java.lang.invoke.*;
-import java.lang.reflect.Method;
 
 import jdk.experimental.value.MethodHandleBuilder;
 import jdk.test.lib.Asserts;
@@ -1277,7 +1276,7 @@
     // Tests writing an array element with a (statically known) incompatible type
     private static final MethodHandle setArrayElementIncompatible = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
         "setArrayElementIncompatible",
-        MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class.asValueType()),
+        MethodType.methodType(void.class, TestLWorld.class, MyValue1[].class, int.class, MyValue2.class.asPrimaryType()),
         CODE -> {
             CODE.
             aload_1().
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestMethodHandles.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestMethodHandles.java	Thu Jun 06 13:45:40 2019 -0700
@@ -59,28 +59,28 @@
             ClassLoader loader = clazz.getClassLoader();
             MethodHandles.Lookup lookup = MethodHandles.lookup();
 
-            MethodType mt = MethodType.methodType(MyValue3.class.asValueType());
+            MethodType mt = MethodType.methodType(MyValue3.class);
             test1_mh = lookup.findVirtual(clazz, "test1_target", mt);
             test2_mh = lookup.findVirtual(clazz, "test2_target", mt);
             test3_mh = lookup.findVirtual(clazz, "test3_target", mt);
 
-            MethodType test4_mt1 = MethodType.methodType(int.class, MyValue1.class.asValueType());
-            MethodType test4_mt2 = MethodType.methodType(MyValue1.class.asValueType());
+            MethodType test4_mt1 = MethodType.methodType(int.class, MyValue1.class);
+            MethodType test4_mt2 = MethodType.methodType(MyValue1.class);
             MethodHandle test4_mh1 = lookup.findStatic(clazz, "test4_helper1", test4_mt1);
             MethodHandle test4_mh2 = lookup.findStatic(clazz, "test4_helper2", test4_mt2);
             test4_mh = MethodHandles.filterReturnValue(test4_mh2, test4_mh1);
 
-            MethodType test5_mt = MethodType.methodType(int.class, MyValue1.class.asValueType());
+            MethodType test5_mt = MethodType.methodType(int.class, MyValue1.class);
             test5_mh = lookup.findVirtual(clazz, "test5_target", test5_mt);
 
-            MethodType test6_mt = MethodType.methodType(MyValue3.class.asValueType());
+            MethodType test6_mt = MethodType.methodType(MyValue3.class);
             MethodHandle test6_mh1 = lookup.findVirtual(clazz, "test6_target1", test6_mt);
             MethodHandle test6_mh2 = lookup.findVirtual(clazz, "test6_target2", test6_mt);
             MethodType boolean_mt = MethodType.methodType(boolean.class);
             MethodHandle test6_mh_test = lookup.findVirtual(clazz, "test6_test", boolean_mt);
             test6_mh = MethodHandles.guardWithTest(test6_mh_test, test6_mh1, test6_mh2);
 
-            MethodType myvalue2_mt = MethodType.methodType(MyValue2.class.asValueType());
+            MethodType myvalue2_mt = MethodType.methodType(MyValue2.class);
             test7_mh1 = lookup.findStatic(clazz, "test7_target1", myvalue2_mt);
             MethodHandle test7_mh2 = lookup.findStatic(clazz, "test7_target2", myvalue2_mt);
             MethodHandle test7_mh_test = lookup.findStatic(clazz, "test7_test", boolean_mt);
@@ -95,7 +95,7 @@
                                                     MethodHandles.dropArguments(test8_mh1, 0, MethodHandle.class),
                                                     MethodHandles.invoker(myvalue2_mt));
 
-            MethodType test9_mt = MethodType.methodType(MyValue3.class.asValueType());
+            MethodType test9_mt = MethodType.methodType(MyValue3.class);
             MethodHandle test9_mh1 = lookup.findVirtual(clazz, "test9_target1", test9_mt);
             MethodHandle test9_mh2 = lookup.findVirtual(clazz, "test9_target2", test9_mt);
             MethodHandle test9_mh3 = lookup.findVirtual(clazz, "test9_target3", test9_mt);
@@ -106,12 +106,12 @@
                                                     test9_mh1,
                                                     MethodHandles.guardWithTest(test9_mh_test2, test9_mh2, test9_mh3));
 
-            MethodType test10_mt = MethodType.methodType(MyValue2.class.asValueType());
+            MethodType test10_mt = MethodType.methodType(MyValue2.class);
             MethodHandle test10_mh1 = lookup.findStatic(clazz, "test10_target1", test10_mt);
             test10_mh2 = lookup.findStatic(clazz, "test10_target2", test10_mt);
             test10_mh3 = lookup.findStatic(clazz, "test10_target3", test10_mt);
             MethodType test10_mt2 = MethodType.methodType(boolean.class);
-            MethodType test10_mt3 = MethodType.methodType(MyValue2.class.asValueType());
+            MethodType test10_mt3 = MethodType.methodType(MyValue2.class);
             MethodHandle test10_mh_test1 = lookup.findStatic(clazz, "test10_test1", test10_mt2);
             MethodHandle test10_mh_test2 = lookup.findStatic(clazz, "test10_test2", test10_mt2);
             test10_mh = MethodHandles.guardWithTest(test10_mh_test1,
@@ -135,7 +135,7 @@
 
     public static void main(String[] args) throws Throwable {
         TestMethodHandles test = new TestMethodHandles();
-        test.run(args, MyValue1.class.asValueType(), MyValue2.class.asValueType(), MyValue2Inline.class.asValueType(), MyValue3.class.asValueType(), MyValue3Inline.class.asValueType());
+        test.run(args, MyValue1.class, MyValue2.class, MyValue2Inline.class, MyValue3.class, MyValue3Inline.class);
     }
 
     // Everything inlined
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNativeClone.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNativeClone.java	Thu Jun 06 13:45:40 2019 -0700
@@ -55,7 +55,7 @@
 
     private static final MethodHandle cloneValue = MethodHandleBuilder.loadCode(MethodHandles.lookup(),
         "MyValue",
-        MethodType.methodType(Object.class, MyValue.class.asValueType()),
+        MethodType.methodType(Object.class, MyValue.class),
         CODE -> {
             CODE.
             aload_0().
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java	Thu Jun 06 13:45:40 2019 -0700
@@ -1414,7 +1414,7 @@
             if (args[i] != null && !parameterTypes[0].isInstance(args[i])) {
                 continue;
             }
-            if (args[i] == null && parameterTypes[0] == MyValue1.class.asValueType()) {
+            if (args[i] == null && parameterTypes[0] == MyValue1.class) {
                 continue;
             }
             if (parameterCount == 1) {
@@ -1436,7 +1436,7 @@
                     if (args[j] != null && !parameterTypes[1].isInstance(args[j])) {
                         continue;
                     }
-                    if (args[j] == null && parameterTypes[1] == MyValue1.class.asValueType()) {
+                    if (args[j] == null && parameterTypes[1] == MyValue1.class) {
                         continue;
                     }
                     System.out.print("Testing " + m.getName() + "(" + args[i] + ", " + args[j] + ")");
@@ -1524,14 +1524,14 @@
             compiled = WHITE_BOX.isMethodCompiled(cmpSometimesEqual1_m, false);
             res = cmpSometimesEqual1(args[idx]);
             if (ACmpOnValues != 3) {
-                Asserts.assertEQ(res, args[idx] == null || !args[idx].getClass().isValue());
+                Asserts.assertEQ(res, args[idx] == null || !args[idx].getClass().isInlineClass());
             } else if (compiled) {
                 Asserts.assertTrue(res);
             }
             compiled = WHITE_BOX.isMethodCompiled(cmpSometimesEqual2_m, false);
             res = cmpSometimesEqual2(args[idx]);
             if (ACmpOnValues != 3) {
-                Asserts.assertNE(res, args[idx] == null || !args[idx].getClass().isValue());
+                Asserts.assertNE(res, args[idx] == null || !args[idx].getClass().isInlineClass());
             } else if (compiled) {
                 Asserts.assertFalse(res);
             }
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNullableValueTypes.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNullableValueTypes.java	Thu Jun 06 13:45:40 2019 -0700
@@ -64,11 +64,11 @@
             ClassLoader loader = clazz.getClassLoader();
             MethodHandles.Lookup lookup = MethodHandles.lookup();
 
-            MethodType test18_mt = MethodType.methodType(void.class, MyValue1.class.asBoxType());
+            MethodType test18_mt = MethodType.methodType(void.class, MyValue1.class.asNullableType());
             test18_mh1 = lookup.findStatic(clazz, "test18_target1", test18_mt);
             test18_mh2 = lookup.findStatic(clazz, "test18_target2", test18_mt);
 
-            MethodType test19_mt = MethodType.methodType(void.class, MyValue1.class.asBoxType());
+            MethodType test19_mt = MethodType.methodType(void.class, MyValue1.class.asNullableType());
             test19_mh1 = lookup.findStatic(clazz, "test19_target1", test19_mt);
             test19_mh2 = lookup.findStatic(clazz, "test19_target2", test19_mt);
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -468,7 +468,7 @@
     @Test
     @Warmup(10000) // Warmup to make sure 'test17_dontinline' is compiled
     public boolean test16(Object arg) throws Exception {
-        Method test16method = getClass().getMethod("test16_dontinline", MyValue1.class.asBoxType());
+        Method test16method = getClass().getMethod("test16_dontinline", MyValue1.class.asNullableType());
         return (boolean)test16method.invoke(this, arg);
     }
 
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/Ifacmp.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/Ifacmp.java	Thu Jun 06 13:45:40 2019 -0700
@@ -165,7 +165,7 @@
     }
 
     boolean shouldEqualSelf(Object a) {
-        return acmpModeInlineAlwaysFalse ? (!(a != null && a.getClass().isValue())) : true;
+        return acmpModeInlineAlwaysFalse ? (!(a != null && a.getClass().isInlineClass())) : true;
     }
 
     void checkEqual(Object a, Object b, boolean isEqual) {
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueOops.java	Thu Jun 06 13:45:40 2019 -0700
@@ -305,7 +305,7 @@
      */
     public static void testOverGc() {
         try {
-            Class<?> vtClass = Person.class.asValueType();
+            Class<?> vtClass = Person.class;
 
             System.out.println("vtClass="+vtClass);
 
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeArray.java	Thu Jun 06 13:45:40 2019 -0700
@@ -69,7 +69,7 @@
             Class<?> arrayCls = Class.forName(arrayClsName);
             assertTrue(arrayCls.isArray(), "Expected an array class");
 
-            assertTrue(arrayCls.getComponentType() == Point.class.asBoxType(),
+            assertTrue(arrayCls.getComponentType() == Point.class.asIndirectType(),
                        "Expected component type of Point.class got: " + arrayCls.getComponentType());
 
             arrayClsName = "[" + arrayClsName;
@@ -81,7 +81,7 @@
             arrayCls = Class.forName(qarrayClsName);
             assertTrue(arrayCls.isArray(), "Expected an array class");
 
-            assertTrue(arrayCls.getComponentType() == Point.class.asValueType(),
+            assertTrue(arrayCls.getComponentType() == Point.class,
                        arrayCls +
                        " Expected component type of Point.class got: " + arrayCls.getComponentType());
 
@@ -200,7 +200,7 @@
         assertTrue(array3[0][0] == null, "Expected NULL");
 
         // Now create ObjArrays of ValueArray...
-        cls = (Class<?>) Point.class.asBoxType();
+        cls = (Class<?>) Point.class.asIndirectType();
         Point?[][] barray = (Point?[][]) Array.newInstance(cls, 1, 2);
         assertEquals(barray.length, 1, "Incorrect length");
         assertEquals(barray[0].length, 2, "Incorrect length");
@@ -255,8 +255,8 @@
         assertTrue(myInts instanceof Comparable[]);
         assertTrue(myInts instanceof MyInt?[]);
 
-        Class<?> cls = MyInt.class.asValueType();
-        assertTrue(cls.isValue());
+        Class<?> cls = MyInt.class;
+        assertTrue(cls.isInlineClass());
         Object arrObj = Array.newInstance(cls, 1);
         assertTrue(arrObj instanceof Object[], "Not Object array");
         assertTrue(arrObj instanceof Comparable[], "Not Comparable array");
--- a/test/jdk/valhalla/valuetypes/MethodHandleTest.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/MethodHandleTest.java	Thu Jun 06 13:45:40 2019 -0700
@@ -32,7 +32,7 @@
 import java.lang.invoke.*;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.*;
+import java.util.List;
 
 import org.testng.annotations.BeforeTest;
 import org.testng.annotations.DataProvider;
@@ -120,15 +120,15 @@
         }
 
         Class<?> elementType = c.getComponentType();
-        if (elementType.isValue()) {
-            assertTrue(elementType == elementType.asValueType());
+        if (elementType.isInlineClass()) {
+            assertTrue(elementType == elementType.asPrimaryType());
         }
         // set an array element to null
         try {
             Object v = (Object)setter.invoke(array, 0, null);
-            assertFalse(elementType.isValue(), "should fail to set an inline class array element to null");
+            assertFalse(elementType.isInlineClass(), "should fail to set an inline class array element to null");
         } catch (NullPointerException e) {
-            assertTrue(elementType.isValue(), "should only fail to set an inline class array element to null");
+            assertTrue(elementType.isInlineClass(), "should only fail to set an inline class array element to null");
         }
     }
 
@@ -136,7 +136,7 @@
     public static void testNullableArray() throws Throwable {
         Class<?> arrayClass = (new Point?[0]).getClass();
         Class<?> elementType = arrayClass.getComponentType();
-        assertTrue(elementType == Point.class.asBoxType());
+        assertTrue(elementType == Point.class.asIndirectType(), arrayClass.getComponentType().toString());
 
         MethodHandle setter = MethodHandles.arrayElementSetter(arrayClass);
         MethodHandle getter = MethodHandles.arrayElementGetter(arrayClass);
@@ -163,7 +163,7 @@
             unreflectField(f);
             findGetter(f);
             varHandle(f);
-            if (c.isValue())
+            if (c.isInlineClass())
                 ensureImmutable(f);
             else
                 ensureNullable(f);
@@ -196,7 +196,7 @@
     void setValueField(String name, Object obj, Object value) throws Throwable {
         Field f = c.getDeclaredField(name);
         boolean isStatic = Modifier.isStatic(f.getModifiers());
-        assertTrue(f.getType().isValue());
+        assertTrue(f.getType().isInlineClass());
         assertTrue((isStatic && obj == null) || (!isStatic && obj != null));
         Object v = f.get(obj);
 
@@ -262,8 +262,7 @@
      */
     void ensureNullable(Field f) throws Throwable {
         assertFalse(Modifier.isStatic(f.getModifiers()));
-        // flattenable implies non-nullable
-        boolean canBeNull = !isFlattenable(f);
+        boolean canBeNull = f.getType().isNullableType();
         // test reflection
         try {
             f.set(o, null);
@@ -315,9 +314,4 @@
     boolean isFlattened(Field f) {
         return (f.getModifiers() & 0x00008000) == 0x00008000;
     }
-
-    boolean isFlattenable(Field f) {
-        return (f.getModifiers() & 0x00000100) == 0x00000100;
-    }
-
 }
--- a/test/jdk/valhalla/valuetypes/NonFlattenValue.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/NonFlattenValue.java	Thu Jun 06 13:45:40 2019 -0700
@@ -25,8 +25,7 @@
     Point? nfp;
 
     NonFlattenValue() {
-        Point p = Point.makePoint(0,0);
-        this.nfp = p;
+        this.nfp = Point.makePoint(0,0);
     }
     public Point? point() {
         return nfp;
@@ -47,6 +46,7 @@
 
     @Override
     public String toString() {
-        return nfp.toString();
+        // nfp may be null when NonFlattenValue[] is created and filled with default value
+        return nfp != null ? nfp.toString() : "default NonFlattenValue";
     }
 }
--- a/test/jdk/valhalla/valuetypes/ObjectMethods.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/ObjectMethods.java	Thu Jun 06 13:45:40 2019 -0700
@@ -25,15 +25,15 @@
 /*
  * @test
  * @summary test Object methods on inline types
- * @compile -XDallowWithFieldOperator ObjectMethods.java
- * @run testng/othervm -XX:+EnableValhalla -Dvalue.bsm.salt=1 ObjectMethods
- * @run testng/othervm -XX:+EnableValhalla -Dvalue.bsm.salt=1 -XX:ValueFieldMaxFlatSize=0 ObjectMethods
+ * @compile -XDallowWithFieldOperator Point.java  Line.java MutablePath.java MixedValues.java Value.java
+ * @build ObjectMethods
+ * @run testng/othervm -XX:+EnableValhalla -Xcomp -Dvalue.bsm.salt=1 ObjectMethods
+ * @run testng/othervm -XX:+EnableValhalla -Xcomp -Dvalue.bsm.salt=1 -XX:ValueFieldMaxFlatSize=0 ObjectMethods
  */
 
 import java.lang.reflect.Modifier;
 import java.util.Arrays;
 import java.util.List;
-import java.util.Objects;
 import java.util.stream.Stream;
 
 import org.testng.annotations.BeforeTest;
@@ -84,8 +84,8 @@
             { MIXED_VALUES, new MixedValues(P1, LINE1, MUTABLE_PATH, "value"), false},
             // uninitialized default value
             { MyValue1.default, MyValue1.default, true},
-            { MyValue1.default, MyValue1.make(0,0, null), true},
-            { MyValue1.make(10, 20, P1), MyValue1.make(10, 20, Point.makePoint(1,2)), true},
+            { MyValue1.default, new MyValue1(0,0, null), true},
+            { new MyValue1(10, 20, P1), new MyValue1(10, 20, Point.makePoint(1,2)), true},
         };
     }
 
@@ -115,9 +115,9 @@
               "[Value char_v=\u0000 byte_v=0 boolean_v=false int_v=0 short_v=0 long_v=0 double_v=0.0 " +
               "float_v=0.0 number_v=99 point_v=[Point x=0 y=0] ref_v=[ref]]" },
             // enclosing instance field `this$0` should be filtered
-            { MyValue1.default, "[ObjectMethods$MyValue1 p=[Point x=0 y=0] box=null]" },
-            { MyValue1.make(0,0, null), "[ObjectMethods$MyValue1 p=[Point x=0 y=0] box=null]" },
-            { MyValue1.make(0,0, P1), "[ObjectMethods$MyValue1 p=[Point x=0 y=0] box=[Point x=1 y=2]]" },
+            { MyValue1.default, "[ObjectMethods$MyValue1 p=[Point x=0 y=0] np=null]" },
+            { new MyValue1(0,0, null), "[ObjectMethods$MyValue1 p=[Point x=0 y=0] np=null]" },
+            { new MyValue1(0,0, P1), "[ObjectMethods$MyValue1 p=[Point x=0 y=0] np=[Point x=1 y=2]]" },
         };
     }
 
@@ -141,13 +141,13 @@
                            .setReference(new Object()).build();
         // this is sensitive to the order of the returned fields from Class::getDeclaredFields
         return new Object[][]{
-            { P1,                   hash(Point.class.asValueType(), 1, 2) },
-            { LINE1,                hash(Line.class.asValueType(), Point.makePoint(1, 2), Point.makePoint(3, 4)) },
+            { P1,                   hash(Point.class, 1, 2) },
+            { LINE1,                hash(Line.class, Point.makePoint(1, 2), Point.makePoint(3, 4)) },
             { v,                    hash(hashCodeComponents(v))},
-            { Point.makePoint(0,0), hash(Point.class.asValueType(), 0, 0) },
-            { Point.default,        hash(Point.class.asValueType(), 0, 0) },
-            { MyValue1.default,     hash(MyValue1.class.asValueType(), Point.default, null) },
-            { MyValue1.make(0,0, null), hash(MyValue1.class.asValueType(), Point.makePoint(0,0), null) },
+            { Point.makePoint(0,0), hash(Point.class, 0, 0) },
+            { Point.default,        hash(Point.class, 0, 0) },
+            { MyValue1.default,     hash(MyValue1.class, Point.default, null) },
+            { new MyValue1(0, 0, null), hash(MyValue1.class, Point.makePoint(0,0), null) },
         };
     }
 
@@ -157,7 +157,7 @@
     }
 
     private static Object[] hashCodeComponents(Object o) {
-        Class<?> type = o.getClass().asValueType();
+        Class<?> type = o.getClass();
         // filter static fields and synthetic fields
         Stream<Object> fields = Arrays.stream(type.getDeclaredFields())
             .filter(f -> !Modifier.isStatic(f.getModifiers()) && !f.isSynthetic())
@@ -180,14 +180,12 @@
     }
 
     static inline class MyValue1 {
-        Point p = Point.default;
-        Point? box = Point.default;
+        private Point p;
+        private Point? np;
 
-        static MyValue1 make(int x, int y, Point? box) {
-            MyValue1 v = MyValue1.default;
-            v = __WithField(v.p, Point.makePoint(x, y));
-            v = __WithField(v.box, box);
-            return v;
+        MyValue1(int x, int y, Point? np) {
+            this.p = Point.makePoint(x, y);
+            this.np = np;
         }
     }
 }
--- a/test/jdk/valhalla/valuetypes/QTypeDescriptorTest.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/QTypeDescriptorTest.java	Thu Jun 06 13:45:40 2019 -0700
@@ -61,8 +61,8 @@
 
     @Test
     public static void testMethodInvoke() throws Exception {
-        Class<?> pointQType = Point.class.asValueType();
-        Class<?> nonFlattenValueQType = NonFlattenValue.class.asValueType();
+        Class<?> pointQType = Point.class;
+        Class<?> nonFlattenValueQType = NonFlattenValue.class;
         Method m = QTypeDescriptorTest.class
             .getDeclaredMethod("toLine", pointQType, nonFlattenValueQType);
         makeLine(m, P0, NFV);
@@ -127,10 +127,10 @@
 
     @DataProvider
     static Object[][] descriptors() {
-        Class<?> pointLType = Point.class.asBoxType();
-        Class<?> pointQType = Point.class.asValueType();
-        Class<?> nonFlattenValueLType = NonFlattenValue.class.asBoxType();
-        Class<?> nonFlattenValueQType = NonFlattenValue.class.asValueType();
+        Class<?> pointLType = Point.class.asIndirectType();
+        Class<?> pointQType = Point.class;
+        Class<?> nonFlattenValueLType = NonFlattenValue.class.asIndirectType();
+        Class<?> nonFlattenValueQType = NonFlattenValue.class;
         return new Object[][]{
             { QTypeDescriptorTest.class, "toLine", new Class<?>[] {pointQType, nonFlattenValueQType}, true},
             { QTypeDescriptorTest.class, "toLine", new Class<?>[] {pointLType, nonFlattenValueQType}, false},
@@ -154,8 +154,8 @@
 
     @DataProvider
     static Object[][] methodTypes() {
-        Class<?> pointLType = Point.class.asBoxType();
-        Class<?> pointQType = Point.class.asValueType();
+        Class<?> pointLType = Point.class.asIndirectType();
+        Class<?> pointQType = Point.class;
         ClassLoader loader = QTypeDescriptorTest.class.getClassLoader();
         return new Object[][]{
             { "point",      MethodType.methodType(pointLType),                            true },
--- a/test/jdk/valhalla/valuetypes/Reflection.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/Reflection.java	Thu Jun 06 13:45:40 2019 -0700
@@ -38,6 +38,8 @@
         testPointClass();
         testLineClass();
         testNonFlattenValue();
+        testMirrors();
+        testClassName();
     }
 
     static void testPointClass() throws Exception  {
@@ -54,19 +56,68 @@
     static void testLineClass() throws Exception {
         Line l = Line.makeLine(10, 20, 30, 40);
         Reflection test = new Reflection(Line.class, "Line", l);
-        test.checkField("p1", Point.class.asValueType());
-        test.checkField("p2", Point.class.asValueType());
-        test.checkMethod("p1", Point.class.asValueType());
-        test.checkMethod("p2", Point.class.asValueType());
+        test.checkField("public final Point Line.p1", "p1", Point.class);
+        test.checkField("public final Point Line.p2", "p2", Point.class);
+        test.checkMethod("public Point Line.p1()",           "p1", Point.class);
+        test.checkMethod("public Point Line.p2()",           "p2", Point.class);
     }
 
     static void testNonFlattenValue() throws Exception {
         NonFlattenValue nfv = NonFlattenValue.make(10, 20);
         Reflection test = new Reflection(NonFlattenValue.class, "NonFlattenValue", nfv);
-        test.checkField("nfp", Point.class.asBoxType());
-        test.checkMethod("point", Point.class.asBoxType());
-        test.checkMethod("pointValue", Point.class.asValueType());
-        test.checkMethod("has", void.class, Point.class.asValueType(), Point.class.asBoxType());
+        test.checkField("final Point? NonFlattenValue.nfp", "nfp", Point.class.asIndirectType());
+        test.checkMethod("public Point NonFlattenValue.pointValue()", "pointValue", Point.class);
+        test.checkMethod("public Point? NonFlattenValue.point()", "point", Point.class.asIndirectType());
+        test.checkMethod("public boolean NonFlattenValue.has(Point,Point?)", "has", boolean.class, Point.class, Point.class.asIndirectType());
+    }
+
+    /*
+     * Tests reflection APIs with the primary type and indirect/nullable projection type
+     */
+    static void testMirrors() throws Exception {
+        Class<?> primary = Point.class;
+        Class<?> indirect = Point.class.asIndirectType();
+
+        assertEquals(primary, Point.class);
+        assertEquals(indirect, Point.class.asNullableType());
+        assertTrue(primary.isInlineClass());
+        assertFalse(primary.isIndirectType());
+        assertFalse(primary.isNullableType());
+
+        assertTrue(indirect.isInlineClass());
+        assertTrue(indirect.isIndirectType());
+        assertTrue(indirect.isNullableType());
+
+        Point o = Point.makePoint(10, 20);
+        assertTrue(primary.isInstance(o));
+        assertTrue(indirect.isInstance(o));
+
+        // V <: V? and V <: Object
+        assertTrue(indirect.isAssignableFrom(primary));
+        assertTrue(Object.class.isAssignableFrom(primary));
+        assertFalse(primary.isAssignableFrom(indirect));
+        assertTrue(Object.class.isAssignableFrom(indirect));
+
+        assertEquals(primary, primary.asSubclass(indirect));
+        try {
+            Class<?> c = indirect.asSubclass(primary);
+            assertTrue(false);
+        } catch (ClassCastException e) { }
+
+        // indirect class
+        assertEquals(Reflection.class.asPrimaryType(), Reflection.class);
+        assertEquals(Reflection.class.asIndirectType(), Reflection.class);
+        assertEquals(Reflection.class.asNullableType(), Reflection.class);
+        assertTrue(Reflection.class.isIndirectType());
+        assertTrue(Reflection.class.isNullableType());
+    }
+
+    static void testClassName() {
+        assertEquals(Point.class.getName(), "Point");
+        assertEquals(Point.class.asNullableType().getName(), "Point");
+        assertEquals(Line.class.getName(), "Line");
+        assertEquals((new Point[0]).getClass().getName(), "[QPoint;");
+        assertEquals((new Point?[0][0]).getClass().getName(), "[[LPoint;");
     }
 
     private final Class<?> c;
@@ -74,48 +125,53 @@
     private final Object o;
     Reflection(Class<?> type, String cn, Object o) throws Exception {
         this.c = Class.forName(cn);
-        if (!c.isValue() || c != type) {
+        if (!c.isInlineClass() || c != type) {
             throw new RuntimeException(cn + " is not an inline class");
         }
 
-        // the box type is the primary mirror
+        // V.class, Class.forName, and the type of the object return the primary mirror
         assertEquals(type, o.getClass());
-        assertEquals(type, c.asBoxType());
+        assertEquals(type, c.asPrimaryType());
+        assertEquals(c, c.asPrimaryType());
 
         this.ctor = c.getDeclaredConstructor();
         this.o = o;
 
-        // TODO: what should Object::getClass return?
-        // assertEquals(o.getClass(), c.asValueType());
 
-        // test the box type and value type
-        testBoxAndValueType(this.c);
-        // test array of Q-type
-        // TODO: array of L-type support
-        testArrayOfQType();
+        // test the primary mirror and secondary mirror
+        testMirrors(this.c);
+        // test array of Q-type and L-type
+        testArray(c.asPrimaryType());
+        testArray(c.asNullableType());
     }
 
-    private static void testBoxAndValueType(Class<?> c) {
-        Class<?> box = c.asBoxType();
-        Class<?> val = c.asValueType();
-        assertTrue(val != null);
-        assertEquals(box.getTypeName(), c.getTypeName());
-        assertEquals(val.getTypeName(), c.getTypeName() + "/val");
-        assertEquals(box, c);
-        assertEquals(val.asBoxType(), box);
-        assertEquals(box.asValueType(), val);
+    private static void testMirrors(Class<?> c) {
+        Class<?> inlineType = c.asPrimaryType();
+        Class<?> nullableType = c.asNullableType();
+
+        assertTrue(inlineType != null);
+        assertEquals(nullableType.getTypeName(), c.getTypeName() + "?");
+
+        assertEquals(nullableType.getName(), inlineType.getName());
+        assertEquals(nullableType.getTypeName(), inlineType.getTypeName() + "?");
+        assertEquals(inlineType.asNullableType(), nullableType);
+        assertEquals(nullableType.asPrimaryType(), inlineType);
     }
 
-    void testArrayOfQType() {
-        Class<?> elementType = c.asValueType();
-        Object array = Array.newInstance(elementType, 1);
+    void testArray(Class<?> elementType) {
+        Object[] array = (Object[])Array.newInstance(elementType, 1);
         Class<?> arrayType = array.getClass();
         assertTrue(arrayType.isArray());
         Class<?> componentType = arrayType.getComponentType();
-        assertTrue(componentType.isValue());
+        assertTrue(componentType.isInlineClass());
         assertEquals(componentType, elementType);
         // Array is a reference type
-        assertEquals(arrayType.asBoxType(), arrayType);
+        assertEquals(arrayType.asNullableType(), arrayType);
+        if (array[0] == null) {
+            System.out.println("array[0] = null");
+        } else {
+            System.out.println("array[0] = " + array[0]);
+        }
     }
 
     void accessFieldX(int x) throws Exception {
@@ -177,22 +233,15 @@
         } catch (InaccessibleObjectException e) { }
     }
 
-    void checkField(String name, Class<?> type) throws Exception {
+    void checkField(String source, String name, Class<?> type) throws Exception {
         Field f = c.getDeclaredField(name);
-        System.out.format("Field %s::%s of type %s = %s%n",
-                          f.getDeclaringClass().getTypeName(), f.getName(),
-                          f.getType().getTypeName(), f.get(o));
         assertEquals(f.getType(), type);
+        assertEquals(f.toString(), source);
     }
 
-    void checkMethod(String name, Class<?> returnType, Class<?>... params) throws Exception {
+    void checkMethod(String source, String name, Class<?> returnType, Class<?>... params) throws Exception {
         Method m = c.getDeclaredMethod(name, params);
-
-        String paramDesc = (params == null || params.length == 0) ? "" :
-            Arrays.stream(params).map(Class::getTypeName).collect(Collectors.joining(", "));
-        System.out.format("Method %s::%s(%s)%s%n",
-                          m.getDeclaringClass().getTypeName(), m.getName(),
-                          paramDesc, returnType.getTypeName());
+        assertEquals(m.toString(), source);
     }
 
     static void assertEquals(Object o1, Object o2) {
@@ -205,6 +254,10 @@
     static void assertTrue(boolean value) {
         if (!value)
             throw new AssertionError("expected true");
+    }
 
+    static void assertFalse(boolean value) {
+        if (value)
+            throw new AssertionError("expected false");
     }
 }
--- a/test/jdk/valhalla/valuetypes/ValueArray.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/ValueArray.java	Thu Jun 06 13:45:40 2019 -0700
@@ -25,7 +25,6 @@
  * @test
  * @summary Basic test for Array::get, Array::set, Arrays::setAll on inline class array
  * @compile -XDallowWithFieldOperator Point.java NonFlattenValue.java
- * @compile -XDallowWithFieldOperator ValueArray.java
  * @run testng/othervm -XX:+EnableValhalla -XX:ValueArrayElemMaxFlatSize=-1 ValueArray
  * @run testng/othervm -XX:+EnableValhalla -XX:ValueArrayElemMaxFlatSize=0  ValueArray
  */
@@ -39,11 +38,109 @@
 import static org.testng.Assert.*;
 
 public class ValueArray {
+    private final Class<?> arrayClass;
+    private final Class<?> componentType;
+    private final Object[] array;
+    ValueArray(Class<?> arrayClass, Object[] array) {
+        this.arrayClass = arrayClass;
+        this.array = array;
+        this.componentType = arrayClass.getComponentType();
+        assertTrue(arrayClass.isArray());
+        assertTrue(array.getClass() == arrayClass);
+    }
+
     private static Class<?> nullablePointArrayClass() {
         Object a = new Point?[0];
         return a.getClass();
     }
 
+    void run() {
+        testClassName();
+        testArrayElements();
+
+        if (componentType.isInlineClass()) {
+            Object[] qArray = (Object[]) Array.newInstance(componentType.asPrimaryType(), 0);
+            Object[] lArray = (Object[]) Array.newInstance(componentType.asIndirectType(), 0);
+            testInlineArrayCovariance(componentType, qArray, lArray);
+        }
+    }
+
+    void testClassName() {
+        // test class names
+        String arrayClassName = arrayClass.getName();
+        StringBuilder sb = new StringBuilder();
+        Class<?> c = arrayClass;
+        while (c.isArray()) {
+            sb.append("[");
+            c = c.getComponentType();
+        }
+        sb.append(c.isIndirectType() ? "L" : "Q").append(c.getName()).append(";");
+        assertEquals(sb.toString(), arrayClassName);
+        assertEquals(c.getTypeName(), c.getName() + (c.isInlineClass() && c.isIndirectType() ? "?" : ""));
+    }
+
+    void testArrayElements() {
+        Object[] array = (Object[]) Array.newInstance(componentType, this.array.length);
+        assertTrue(array.getClass() == arrayClass);
+        assertTrue(array.getClass().getComponentType() == componentType);
+
+        // set elements
+        for (int i=0; i < this.array.length; i++) {
+            Array.set(array, i, this.array[i]);
+        }
+        for (int i=0; i < this.array.length; i++) {
+            Object o = Array.get(array, i);
+            assertEquals(o, this.array[i]);
+        }
+        Arrays.setAll(array, i -> this.array[i]);
+
+        // test nullable
+        if (componentType.isNullableType()) {
+            for (int i=0; i < array.length; i++) {
+                Array.set(array, i, null);
+            }
+        } else {
+            for (int i=0; i < array.length; i++) {
+                try {
+                    Array.set(array, i, null);
+                    assertFalse(true, "expect NPE but not thrown");
+                } catch (NullPointerException e) { }
+            }
+        }
+    }
+
+    void testInlineArrayCovariance(Class<?> componentType, Object[] qArray, Object[] lArray) {
+        assertTrue(componentType.isInlineClass());
+
+        // Class.instanceOf (self)
+        assertTrue(qArray.getClass().isInstance(qArray));
+        assertTrue(lArray.getClass().isInstance(lArray));
+
+        // Class.instanceof inline vs indirect
+        assertFalse(qArray.getClass().isInstance(lArray));
+        assertTrue(lArray.getClass().isInstance(qArray));
+
+        // Class.isAssignableFrom (self)
+        assertTrue(qArray.getClass().isAssignableFrom(qArray.getClass()));
+        assertTrue(lArray.getClass().isAssignableFrom(lArray.getClass()));
+
+        // Class.isAssignableFrom inline vs indirect
+        assertTrue(lArray.getClass().isAssignableFrom(qArray.getClass()));
+        assertFalse(qArray.getClass().isAssignableFrom(lArray.getClass()));
+
+        // Class.cast (self)
+        qArray.getClass().cast(qArray);
+        lArray.getClass().cast(lArray);
+
+        // Class.cast inline vs indirect
+        lArray.getClass().cast(qArray);
+        try {
+            qArray.getClass().cast(lArray);
+            assertFalse(true, "cast of Point? to Point should not succeed");
+        } catch (ClassCastException cce) { }
+    }
+
+
     @DataProvider(name="arrayTypes")
     static Object[][] arrayTypes() {
         return new Object[][] {
@@ -59,7 +156,7 @@
             new Object[] { nullablePointArrayClass(),
                            new Point?[] { Point.makePoint(11, 22),
                                           Point.makePoint(110, 220),
-                                          null}},
+                                          null }},
             new Object[] { NonFlattenValue[].class,
                            new NonFlattenValue[] { NonFlattenValue.make(1, 2),
                                                    NonFlattenValue.make(10, 20),
@@ -67,33 +164,10 @@
         };
     }
 
-
     @Test(dataProvider="arrayTypes")
-    public static void test(Class<?> c, Object[] elements) {
-        ValueArray test = new ValueArray(c, elements.length);
-        test.run(elements);
-        Class<?> compType = c.getComponentType();
-        if (compType.isValue()) {
-            test.testSetNullElement(compType == compType.asBoxType());
-        }
-     }
-
-    @Test
-    public static void testPointArray() {
-        PointArray array = PointArray.makeArray(Point.makePoint(1, 2), Point.makePoint(10, 20));
-        ValueArray test = new ValueArray(array.points);
-        test.run(Point.makePoint(3, 4), Point.makePoint(30, 40));
-    }
-
-    @Test
-    public static void testNullablePointArray() {
-        Point ?[]array = new Point ?[3];
-        array[0] = Point.makePoint(1, 2);
-        array[1] = null;
-        array[2] = Point.makePoint(3, 4);
-
-        ValueArray test = new ValueArray(array);
-        test.run(null, Point.makePoint(3, 4), null);
+    public static void test(Class<?> arrayClass, Object[] array) {
+        ValueArray test = new ValueArray(arrayClass, array);
+        test.run();
     }
 
     @Test
@@ -125,95 +199,19 @@
 
     }
 
-    @Test()
-    static void testArrayCovariance() {
+    @Test
+    static void testPointArray() {
         Point[] qArray = new Point[0];
         Point?[] lArray = new Point?[0];
 
+        ValueArray test = new ValueArray(Point[].class, qArray);
+        test.run();
+
+        ValueArray test1 = new ValueArray(Point?[].class, lArray);
+        test.run();
+
         // language instanceof
         assertTrue(qArray instanceof Point[]);
         assertTrue(lArray instanceof Point?[]);
-
-        // Class.instanceOf (self)
-        assertTrue(qArray.getClass().isInstance(qArray));
-        assertTrue(lArray.getClass().isInstance(lArray));
-
-        // Class.instanceof inline vs indirect
-        assertFalse(qArray.getClass().isInstance(lArray));
-        assertTrue(lArray.getClass().isInstance(qArray));
-
-        // Class.isAssignableFrom (self)
-        assertTrue(qArray.getClass().isAssignableFrom(qArray.getClass()));
-        assertTrue(lArray.getClass().isAssignableFrom(lArray.getClass()));
-
-        // Class.isAssignableFrom inline vs indirect
-        assertTrue(lArray.getClass().isAssignableFrom(qArray.getClass()));
-        assertFalse(qArray.getClass().isAssignableFrom(lArray.getClass()));
-
-        // Class.cast (self)
-        qArray.getClass().cast(qArray);
-        lArray.getClass().cast(lArray);
-
-        // Class.cast inline vs indirect
-        lArray.getClass().cast(qArray);
-        try {
-            qArray.getClass().cast(lArray);
-            fail("cast of Point? to Point should not succeed");
-        } catch (ClassCastException cce) {
-            // expected
-        }
-    }
-
-    private final Object[] array;
-
-    ValueArray(Class<?> arrayClass, int len) {
-        this((Object[])Array.newInstance(arrayClass.getComponentType(), len));
-        assertTrue(array.getClass() == arrayClass);
-    }
-
-    ValueArray(Object[] array) {
-        this.array = array;
-    }
-
-    void run(Object... elements) {
-        for (int i=0; i < elements.length; i++) {
-            Array.set(array, i, elements[i]);
-        }
-
-        for (int i=0; i < elements.length; i++) {
-            Object o = Array.get(array, i);
-            assertEquals(o, elements[i]);
-        }
-
-        Arrays.setAll(array, i -> elements[i]);
-    }
-
-    void testSetNullElement(boolean nullable) {
-        assert(array.getClass().getComponentType().isValue());
-        for (int i=0; i < array.length; i++) {
-            try {
-                Array.set(array, i, null);
-                if (!nullable)
-                    throw new AssertionError("NPE not thrown");
-            } catch (NullPointerException e) {
-                assertFalse(nullable);
-            }
-        }
-    }
-
-  static inline class PointArray {
-        public Point[] points;
-        PointArray() {
-            points = new Point[0];
-        }
-        public static PointArray makeArray(Point... points) {
-            PointArray a = PointArray.default;
-            Point[] array = new Point[points.length];
-            for (int i=0; i < points.length; i++) {
-                array[i] = points[i];
-            }
-            a = __WithField(a.points, array);
-            return a;
-        }
     }
 }
--- a/test/jdk/valhalla/valuetypes/ValueBootstrapMethods.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/jdk/valhalla/valuetypes/ValueBootstrapMethods.java	Thu Jun 06 13:45:40 2019 -0700
@@ -34,21 +34,15 @@
 import java.lang.invoke.CallSite;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.lang.reflect.*;
+import java.lang.reflect.Method;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
-import java.util.Set;
 
-import jdk.internal.org.objectweb.asm.Attribute;
-import jdk.internal.org.objectweb.asm.ByteVector;
-import jdk.internal.org.objectweb.asm.ClassReader;
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Handle;
-import jdk.internal.org.objectweb.asm.Label;
 import jdk.internal.org.objectweb.asm.MethodVisitor;
 import jdk.internal.org.objectweb.asm.Type;
 import static jdk.internal.org.objectweb.asm.Opcodes.*;
@@ -60,7 +54,7 @@
         Class<?> test = valueTestClass();
         Value value = Value.make(10, 5.03, "foo", "bar", "goo");
 
-        Class<?> valueClass = Value.class.asValueType();
+        Class<?> valueClass = Value.class;
         Method hashCode = test.getMethod("hashCode", valueClass);
         int hash = (int)hashCode.invoke(null, value);
         assertEquals(hash, value.hashCode());
@@ -97,7 +91,7 @@
         }
 
         List<Object> values() {
-            return List.of(Value.class.asValueType(), i, d, s, l);
+            return List.of(Value.class, i, d, s, l);
         }
 
         public int hashCode() {
@@ -116,7 +110,7 @@
      */
     private static Class<?> valueTestClass() throws Exception {
         Path path = Paths.get(TEST_CLASSES, "ValueTest.class");
-        generate(Value.class.asValueType(), "ValueTest", path);
+        generate(Value.class, "ValueTest", path);
         return Class.forName("ValueTest");
     }
 
--- a/test/langtools/tools/javac/valhalla/lworld-values/ValueBootstrapMethodsTest.java	Thu Jun 06 08:09:09 2019 -0700
+++ b/test/langtools/tools/javac/valhalla/lworld-values/ValueBootstrapMethodsTest.java	Thu Jun 06 13:45:40 2019 -0700
@@ -55,7 +55,7 @@
         }
 
         private List<Object> values() {
-            return List.of(Value.class.asValueType(), i, d, s, l);
+            return List.of(Value.class, i, d, s, l);
         }
 
         public int localHashCode() {