changeset 53155:42678a58ba1f lworld

8214717: [lworld] C2 should use nullability information (.box/.val) instead of relying on -XX:NullableValueTypes
author thartmann
date Mon, 03 Dec 2018 17:47:41 +0100
parents df2a954edeae
children 8f8d2ccfdc40
files src/hotspot/share/ci/ciEnv.cpp src/hotspot/share/ci/ciEnv.hpp src/hotspot/share/ci/ciMethodType.cpp src/hotspot/share/ci/ciMethodType.hpp src/hotspot/share/ci/ciSignature.cpp src/hotspot/share/ci/ciStreams.cpp src/hotspot/share/ci/ciStreams.hpp src/hotspot/share/ci/ciTypeFlow.cpp src/hotspot/share/opto/graphKit.cpp src/hotspot/share/opto/graphKit.hpp src/hotspot/share/opto/parseHelper.cpp src/hotspot/share/runtime/globals.hpp test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNullableValueTypes.java test/hotspot/jtreg/compiler/valhalla/valuetypes/ValueTypeTest.java test/hotspot/jtreg/runtime/valhalla/valuetypes/FlattenableSemanticTest.java
diffstat 16 files changed, 158 insertions(+), 89 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/ci/ciEnv.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciEnv.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -598,6 +598,23 @@
 }
 
 // ------------------------------------------------------------------
+// ciEnv::get_never_null_impl
+//
+// Implementation of get_never_null.
+bool ciEnv::get_never_null_impl(const constantPoolHandle& cpool, int index) {
+  Symbol* klass_name = cpool->klass_name_at(index);
+  return klass_name->is_Q_signature();
+}
+
+// ------------------------------------------------------------------
+// ciEnv::get_never_null
+//
+// Get information about nullability from the constant pool.
+bool ciEnv::get_never_null(const constantPoolHandle& cpool, int index) {
+  GUARDED_VM_ENTRY(return get_never_null_impl(cpool, index);)
+}
+
+// ------------------------------------------------------------------
 // ciEnv::get_constant_by_index_impl
 //
 // Implementation of get_constant_by_index().
--- a/src/hotspot/share/ci/ciEnv.hpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciEnv.hpp	Mon Dec 03 17:47:41 2018 +0100
@@ -132,6 +132,8 @@
   ciMethod*  get_method_by_index(const constantPoolHandle& cpool,
                                  int method_index, Bytecodes::Code bc,
                                  ciInstanceKlass* loading_klass);
+  bool       get_never_null(const constantPoolHandle& cpool,
+                            int klass_index);
 
   // Implementation methods for loading and constant pool access.
   ciKlass* get_klass_by_name_impl(ciKlass* accessing_klass,
@@ -150,6 +152,8 @@
   ciMethod*  get_method_by_index_impl(const constantPoolHandle& cpool,
                                       int method_index, Bytecodes::Code bc,
                                       ciInstanceKlass* loading_klass);
+  bool       get_never_null_impl(const constantPoolHandle& cpool,
+                                 int klass_index);
 
   // Helper methods
   bool       check_klass_accessibility(ciKlass* accessing_klass,
--- a/src/hotspot/share/ci/ciMethodType.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciMethodType.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -38,9 +38,10 @@
   }
 }
 
-ciType* ciMethodType::rtype() const {
+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);
     return class_to_citype(rtype);
   )
 }
@@ -53,9 +54,10 @@
   GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_slot_count(get_oop());)
 }
 
-ciType* ciMethodType::ptype_at(int index) const {
+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);
     return class_to_citype(ptype);
   )
 }
--- a/src/hotspot/share/ci/ciMethodType.hpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciMethodType.hpp	Mon Dec 03 17:47:41 2018 +0100
@@ -40,12 +40,12 @@
   // What kind of ciObject is this?
   bool is_method_type() const { return true; }
 
-  ciType* rtype() const;
+  ciType* rtype(bool& never_null) const;
 
   int ptype_count() const;
   int ptype_slot_count() const ;
 
-  ciType* ptype_at(int index) const;
+  ciType* ptype_at(int index, bool& never_null) const;
 };
 
 #endif // SHARE_VM_CI_CIMETHODTYPE_HPP
--- a/src/hotspot/share/ci/ciSignature.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciSignature.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -68,7 +68,8 @@
         ciSymbol* klass_name = env->get_symbol(name);
         type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
       }
-      if (type->is_valuetype() && !NullableValueTypes) {
+      if (ss.type() == T_VALUETYPE) {
+        assert(type->is_valuetype(), "must be a valuetype");
         type = new (arena) ciWrapper(type, /* never_null */ true);
       }
     }
@@ -97,15 +98,18 @@
   Arena* arena = CURRENT_ENV->arena();
   _types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
   ciType* type = NULL;
+  bool never_null = false;
   for (int i = 0; i < _count; i++) {
-    type = method_type->ptype_at(i);
-    if (type->is_valuetype() && !NullableValueTypes) {
+    type = method_type->ptype_at(i, never_null);
+    if (never_null) {
+      assert(type->is_valuetype(), "must be a valuetype");
       type = new (arena) ciWrapper(type, /* never_null */ true);
     }
     _types->append(type);
   }
-  type = method_type->rtype();
-  if (type->is_valuetype() && !NullableValueTypes) {
+  type = method_type->rtype(never_null);
+  if (never_null) {
+    assert(type->is_valuetype(), "must be a valuetype");
     type = new (arena) ciWrapper(type, /* never_null */ true);
   }
   _types->append(type);
--- a/src/hotspot/share/ci/ciStreams.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciStreams.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -192,6 +192,16 @@
 }
 
 // ------------------------------------------------------------------
+// ciBytecodeStream::get_never_null
+//
+// Get information about nullability from the constant pool.
+bool ciBytecodeStream::get_never_null() const {
+  VM_ENTRY_MARK;
+  constantPoolHandle cpool(_method->get_Method()->constants());
+  return CURRENT_ENV->get_never_null(cpool, get_klass_index());
+}
+
+// ------------------------------------------------------------------
 // ciBytecodeStream::get_constant_raw_index
 //
 // If this bytecode is one of the ldc variants, get the index of the
--- a/src/hotspot/share/ci/ciStreams.hpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciStreams.hpp	Mon Dec 03 17:47:41 2018 +0100
@@ -235,6 +235,7 @@
   // or checkcast, get the referenced klass.
   ciKlass* get_klass(bool& will_link);
   int get_klass_index() const;
+  bool get_never_null() const;
 
   // If this bytecode is one of the ldc variants, get the referenced
   // constant.  Do not attempt to resolve it, since that would require
--- a/src/hotspot/share/ci/ciTypeFlow.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/ci/ciTypeFlow.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -629,7 +629,8 @@
     do_null_assert(klass);
   } else {
     pop_object();
-    if (klass->is_valuetype() && !NullableValueTypes) {
+    if (str->get_never_null()) {
+      assert(klass->is_valuetype(), "must be a value type");
       push(outer()->mark_as_never_null(klass));
     } else {
       push_object(klass);
--- a/src/hotspot/share/opto/graphKit.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/opto/graphKit.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -3136,12 +3136,10 @@
 // If failure_control is supplied and not null, it is filled in with
 // the control edge for the cast failure.  Otherwise, an appropriate
 // uncommon trap or exception is thrown.
-Node* GraphKit::gen_checkcast(Node *obj, Node* superklass,
-                              Node* *failure_control) {
+Node* GraphKit::gen_checkcast(Node *obj, Node* superklass, Node* *failure_control, bool never_null) {
   kill_dead_locals();           // Benefit all the uncommon traps
   const TypeKlassPtr* tk = _gvn.type(superklass)->is_klassptr();
   const TypeOopPtr* toop = TypeOopPtr::make_from_klass(tk->klass());
-
   bool is_value = obj->is_ValueType();
 
   // Fast cutout:  Check the case that the cast is vacuously true.
@@ -3168,9 +3166,12 @@
         // to the type system as a speculative type.
         if (!is_value) {
           obj = record_profiled_receiver_for_speculation(obj);
-          if (toop->is_valuetypeptr() && toop->value_klass()->is_scalarizable() && !NullableValueTypes) {
+          if (never_null) {
+            assert(toop->is_valuetypeptr(), "must be a value type pointer");
             obj = null_check(obj);
-            obj = ValueTypeNode::make_from_oop(this, obj, toop->value_klass());
+            if (toop->value_klass()->is_scalarizable()) {
+              obj = ValueTypeNode::make_from_oop(this, obj, toop->value_klass());
+            }
           }
         }
         return obj;
@@ -3213,7 +3214,8 @@
   Node* not_null_obj = NULL;
   if (is_value) {
     not_null_obj = obj;
-  } else if (toop->is_valuetypeptr() && !NullableValueTypes) {
+  } else if (never_null) {
+    assert(toop->is_valuetypeptr(), "must be a value type pointer");
     not_null_obj = null_check(obj);
   } else {
     not_null_obj = null_check_oop(obj, &null_ctl, never_see_null, safe_for_replace, speculative_not_null);
--- a/src/hotspot/share/opto/graphKit.hpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/opto/graphKit.hpp	Mon Dec 03 17:47:41 2018 +0100
@@ -830,8 +830,7 @@
 
   // Generate a check-cast idiom.  Used by both the check-cast bytecode
   // and the array-store bytecode
-  Node* gen_checkcast( Node *subobj, Node* superkls,
-                       Node* *failure_control = NULL );
+  Node* gen_checkcast(Node *subobj, Node* superkls, Node* *failure_control = NULL, bool never_null = false);
 
   Node* is_always_locked(Node* obj);
   Node* gen_value_type_test(Node* kls);
--- a/src/hotspot/share/opto/parseHelper.cpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/opto/parseHelper.cpp	Mon Dec 03 17:47:41 2018 +0100
@@ -68,6 +68,7 @@
 void Parse::do_checkcast() {
   bool will_link;
   ciKlass* klass = iter().get_klass(will_link);
+  bool never_null = iter().get_never_null();
 
   Node *obj = peek();
 
@@ -95,7 +96,7 @@
     return;
   }
 
-  Node *res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass)) );
+  Node* res = gen_checkcast(obj, makecon(TypeKlassPtr::make(klass)), NULL, never_null);
   if (stopped()) {
     return;
   }
--- a/src/hotspot/share/runtime/globals.hpp	Mon Dec 03 14:22:02 2018 +0100
+++ b/src/hotspot/share/runtime/globals.hpp	Mon Dec 03 17:47:41 2018 +0100
@@ -2662,9 +2662,6 @@
   develop(bool, ScalarizeValueTypes, true,                                  \
           "Scalarize value types in compiled code")                         \
                                                                             \
-  product(bool, NullableValueTypes, false,                                  \
-          "Treat all value types as nullable")                              \
-                                                                            \
   experimental(bool, UsePointerPerturbation, false,                         \
                "With value types, use the perturbation scheme for acmp")    \
 
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java	Mon Dec 03 14:22:02 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNewAcmp.java	Mon Dec 03 17:47:41 2018 +0100
@@ -1385,7 +1385,6 @@
 
     protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
     protected static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
-    protected static final boolean NullableValueTypes = (Boolean)WHITE_BOX.getVMFlag("NullableValueTypes");
 
     public void runTest(Method m, Object[] args, int warmup, int nullMode) throws Exception {
         Class<?>[] parameterTypes = m.getParameterTypes();
@@ -1398,7 +1397,7 @@
             if (args[i] != null && !parameterTypes[0].isInstance(args[i])) {
                 continue;
             }
-            if (args[i] == null && parameterTypes[0] == MyValue.class.asValueType() && !NullableValueTypes) {
+            if (args[i] == null && parameterTypes[0] == MyValue.class.asValueType()) {
                 continue;
             }
             if (parameterCount == 1) {
@@ -1420,7 +1419,7 @@
                     if (args[j] != null && !parameterTypes[1].isInstance(args[j])) {
                         continue;
                     }
-                    if (args[j] == null && parameterTypes[1] == MyValue.class.asValueType() && !NullableValueTypes) {
+                    if (args[j] == null && parameterTypes[1] == MyValue.class.asValueType()) {
                         continue;
                     }
                     System.out.print("Testing " + m.getName() + "(" + args[i] + ", " + args[j] + ")");
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNullableValueTypes.java	Mon Dec 03 14:22:02 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/TestNullableValueTypes.java	Mon Dec 03 17:47:41 2018 +0100
@@ -42,7 +42,7 @@
  * @compile -XDenableValueTypes -XDallowWithFieldOperator TestNullableValueTypes.java
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox jdk.test.lib.Platform
  * @run main/othervm/timeout=120 -Xbootclasspath/a:. -ea -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
- *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla -XX:+NullableValueTypes
+ *                               -XX:+UnlockExperimentalVMOptions -XX:+WhiteBoxAPI -XX:+EnableValhalla
  *                               compiler.valhalla.valuetypes.ValueTypeTest
  *                               compiler.valhalla.valuetypes.TestNullableValueTypes
  */
@@ -70,11 +70,11 @@
             ClassLoader loader = clazz.getClassLoader();
             MethodHandles.Lookup lookup = MethodHandles.lookup();
 
-            MethodType test18_mt = MethodType.methodType(void.class, MyValue1.class);
+            MethodType test18_mt = MethodType.methodType(void.class, MyValue1.class.asBoxType());
             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);
+            MethodType test19_mt = MethodType.methodType(void.class, MyValue1.class.asBoxType());
             test19_mh1 = lookup.findStatic(clazz, "test19_target1", test19_mt);
             test19_mh2 = lookup.findStatic(clazz, "test19_target2", test19_mt);
         } catch (NoSuchMethodException | IllegalAccessException e) {
@@ -164,7 +164,7 @@
     }
 
     @Test
-    public MyValue1 test5(MyValue1 vt) {
+    public MyValue1 test5(MyValue1.box vt) {
         try {
             Object o = vt;
             vt = (MyValue1)o;
@@ -214,27 +214,27 @@
     }
 
     @ForceInline
-    public MyValue1.box getNull_inline() {
+    public MyValue1.box getNullInline() {
         return null;
     }
 
     @DontInline
-    public MyValue1.box getNull_dontInline() {
+    public MyValue1.box getNullDontInline() {
         return null;
     }
 
     @Test
     public void test7() throws Throwable {
-        nullField = getNull_inline();     // Should not throw
-        nullField = getNull_dontInline(); // Should not throw
+        nullField = getNullInline();     // Should not throw
+        nullField = getNullDontInline(); // Should not throw
         try {
-            valueField1 = getNull_inline();
+            valueField1 = getNullInline();
             throw new RuntimeException("NullPointerException expected");
         } catch (NullPointerException e) {
             // Expected
         }
         try {
-            valueField1 = getNull_dontInline();
+            valueField1 = getNullDontInline();
             throw new RuntimeException("NullPointerException expected");
         } catch (NullPointerException e) {
             // Expected
@@ -324,7 +324,7 @@
     int test12_cnt;
 
     @DontInline
-    public MyValue1 test12_helper() {
+    public MyValue1.box test12_helper() {
         test12_cnt++;
         return nullField;
     }
@@ -350,25 +350,25 @@
 
     // null return at virtual call
     class A {
-        public MyValue1 test13_helper() {
+        public MyValue1.box test13_helper() {
             return nullField;
         }
     }
 
     class B extends A {
-        public MyValue1 test13_helper() {
+        public MyValue1.val test13_helper() {
             return nullField;
         }
     }
 
     class C extends A {
-        public MyValue1 test13_helper() {
+        public MyValue1.box test13_helper() {
             return nullField;
         }
     }
 
-    class D extends A {
-        public MyValue1 test13_helper() {
+    class D extends B {
+        public MyValue1.box test13_helper() {
             return nullField;
         }
     }
@@ -430,20 +430,31 @@
 */
 
     @DontInline
-    MyValue1 get_nullField() {
+    MyValue1.box getNullField1() {
+        return nullField;
+    }
+
+    @DontInline
+    MyValue1.val getNullField2() {
         return nullField;
     }
 
     @Test()
     public void test15() {
+        nullField = getNullField1(); // should not throw
         try {
-            valueField1 = get_nullField();
+            valueField1 = getNullField1();
             throw new RuntimeException("NullPointerException expected");
         } catch (NullPointerException e) {
             // Expected
         }
-
-        nullField = get_nullField(); // should not throw
+        try {
+// TODO enable this once we've fixed the interpreter to throw a NPE
+//            valueField1 = getNullField2();
+//            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException e) {
+            // Expected
+        }
     }
 
     @DontCompile
@@ -452,7 +463,7 @@
     }
 
     @DontInline
-    public boolean test16_dontinline(MyValue1 vt) {
+    public boolean test16_dontinline(MyValue1.box vt) {
         return (Object)vt == null;
     }
 
@@ -460,7 +471,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.asValueType());
+        Method test16method = getClass().getMethod("test16_dontinline", MyValue1.class.asBoxType());
         return (boolean)test16method.invoke(this, arg);
     }
 
@@ -506,12 +517,12 @@
     static MyValue1.box nullValue;
 
     @DontInline
-    static void test18_target1(MyValue1 vt) {
+    static void test18_target1(MyValue1.box vt) {
         nullValue = vt;
     }
 
     @ForceInline
-    static void test18_target2(MyValue1 vt) {
+    static void test18_target2(MyValue1.box vt) {
         nullValue = vt;
     }
 
@@ -536,12 +547,12 @@
     static MethodHandle test19_mh2;
 
     @DontInline
-    static void test19_target1(MyValue1 vt) {
+    static void test19_target1(MyValue1.box vt) {
         nullValue = vt;
     }
 
     @ForceInline
-    static void test19_target2(MyValue1 vt) {
+    static void test19_target2(MyValue1.box vt) {
         nullValue = vt;
     }
 
@@ -608,8 +619,9 @@
     public Test21Value test21(Test21Value vt) {
         vt = vt.test1();
         try {
-            vt = vt.test2();
-            throw new RuntimeException("NullPointerException expected");
+// TODO enable this once we've fixed the interpreter to throw a NPE
+//            vt = vt.test2();
+//            throw new RuntimeException("NullPointerException expected");
         } catch (NullPointerException e) {
             // Expected
         }
@@ -620,4 +632,25 @@
     public void test21_verifier(boolean warmup) {
         test21(Test21Value.default);
     }
+
+    @DontInline
+    public MyValue1.val test22_helper() {
+        return nullField;
+    }
+
+    @Test
+    public void test22() {
+        valueField1 = test22_helper();
+    }
+
+    @DontCompile
+    public void test22_verifier(boolean warmup) {
+        try {
+// TODO enable this once we've fixed the interpreter to throw a NPE
+//            test22();
+//            throw new RuntimeException("NullPointerException expected");
+        } catch (NullPointerException e) {
+            // Expected
+        }
+    }
 }
--- a/test/hotspot/jtreg/compiler/valhalla/valuetypes/ValueTypeTest.java	Mon Dec 03 14:22:02 2018 +0100
+++ b/test/hotspot/jtreg/compiler/valhalla/valuetypes/ValueTypeTest.java	Mon Dec 03 17:47:41 2018 +0100
@@ -126,7 +126,6 @@
     protected static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs");
     protected static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten");
     protected static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields");
-    protected static final boolean NullableValueTypes = (Boolean)WHITE_BOX.getVMFlag("NullableValueTypes");
     protected static final int COMP_LEVEL_ANY = -2;
     protected static final int COMP_LEVEL_FULL_OPTIMIZATION = TEST_C1 ? 1 : 4;
     protected static final Hashtable<String, Method> tests = new Hashtable<String, Method>();
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/FlattenableSemanticTest.java	Mon Dec 03 14:22:02 2018 +0100
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/FlattenableSemanticTest.java	Mon Dec 03 17:47:41 2018 +0100
@@ -37,7 +37,7 @@
  * @compile -XDemitQtypes -XDenableValueTypes -XDallowWithFieldOperator Point.java JumboValue.java
  * @compile -XDemitQtypes -XDenableValueTypes -XDallowWithFieldOperator FlattenableSemanticTest.java
  * @run main/othervm -Xint -XX:ValueFieldMaxFlatSize=64 -XX:+EnableValhalla runtime.valhalla.valuetypes.FlattenableSemanticTest
- * @run main/othervm -Xcomp -XX:+EnableValhalla -XX:ValueFieldMaxFlatSize=64 -XX:+NullableValueTypes runtime.valhalla.valuetypes.FlattenableSemanticTest
+ * @run main/othervm -Xcomp -XX:+EnableValhalla -XX:ValueFieldMaxFlatSize=64 runtime.valhalla.valuetypes.FlattenableSemanticTest
  * // debug: -XX:+PrintValueLayout -XX:-ShowMessageBoxOnError
  */
 public class FlattenableSemanticTest {
@@ -78,45 +78,45 @@
         Asserts.assertNotNull(test.fij, "Invalid null value for unitialized flattenable field");
 
         // Assigning null must be allowed for non flattenable value fields
-	boolean exception = true;
-	try {
-	    nfsp = (Point.box)getNull();
-	    nfsp = null;
-	    exception = false;
-	} catch (NullPointerException e) {
-	    exception = true;
-	}
-	Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
-	
-	try {
-	    nfsj = (JumboValue.box)getNull();
-	    nfsj = null;
-	    exception = false;
-	} catch (NullPointerException e) {
-	    exception = true;
-	}
-	Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
+        boolean exception = true;
+        try {
+            nfsp = (Point.box)getNull();
+            nfsp = null;
+            exception = false;
+        } catch (NullPointerException e) {
+            exception = true;
+        }
+        Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
 
-	try {
-	    test.nfip = (Point.box)getNull();
-	    test.nfip = null;
-	    exception = false;
-	} catch (NullPointerException e) {
-	    exception = true;
-	}
+        try {
+            nfsj = (JumboValue.box)getNull();
+            nfsj = null;
+            exception = false;
+        } catch (NullPointerException e) {
+            exception = true;
+        }
         Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
-	
-	try {
-	    test.nfij = (JumboValue.box)getNull();
-	    test.nfij = null;
-	    exception = false;
-	} catch (NullPointerException e) {
-	    exception = true;
-	}
+
+        try {
+            test.nfip = (Point.box)getNull();
+            test.nfip = null;
+            exception = false;
+        } catch (NullPointerException e) {
+            exception = true;
+        }
+        Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
+
+        try {
+            test.nfij = (JumboValue.box)getNull();
+            test.nfij = null;
+            exception = false;
+        } catch (NullPointerException e) {
+            exception = true;
+        }
         Asserts.assertFalse(exception, "Invalid NPE when assigning null to a non flattenable field");
 
         // Assigning null to a flattenable value field must trigger a NPE
-	exception = false;
+        exception = false;
         try {
             fsp = (Point)getNull();
         } catch(NullPointerException e) {