changeset 47431:b704aecd02e6 mvt

8189690: [mvt]Static fields support for Value Types is broken Reviewed-by: dsimms
author fparain
date Mon, 23 Oct 2017 10:40:30 -0400
parents 3ac981476357
children 02ec88e82173
files src/hotspot/share/classfile/classFileParser.cpp src/hotspot/share/interpreter/interpreterRuntime.cpp src/hotspot/share/oops/instanceKlass.hpp test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeCreation.java
diffstat 4 files changed, 45 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/classfile/classFileParser.cpp	Mon Oct 23 16:18:53 2017 +0200
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Mon Oct 23 10:40:30 2017 -0400
@@ -4584,14 +4584,9 @@
       }
     }
 
-    for (FieldStream st((InstanceKlass*)defined_klass, false, false); !st.eos(); st.next()) {
-      Symbol* signature = st.signature();
-      if (signature->starts_with("Q")) {
-        Klass* klass = SystemDictionary::resolve_or_fail(signature,
-                                                         Handle(THREAD, defined_klass->class_loader()),
-                                                         Handle(THREAD, defined_klass->protection_domain()), true, CHECK);
-        assert(klass != NULL, "Sanity check");
-        assert(klass->access_flags().is_value_type(), "Value type expected");
+    for(int i = 0; i < defined_klass->java_fields_count(); i++) {
+      if (defined_klass->field_signature(i)->starts_with("Q")  && (((defined_klass->field_access_flags(i) & JVM_ACC_STATIC)) == 0)) {
+        const Klass* klass = defined_klass->get_value_field_klass(i);
         defining_loader_data->record_dependency(klass, CHECK);
       }
     }
@@ -5740,11 +5735,8 @@
     }
   }
 
-  // Update the loader_data graph.
-  record_defined_class_dependencies(ik, CHECK);
-
   for(int i = 0; i < ik->java_fields_count(); i++) {
-    if (ik->field_signature(i)->starts_with("Q")) {
+    if (ik->field_signature(i)->starts_with("Q")  && (((ik->field_access_flags(i) & JVM_ACC_STATIC)) == 0)) {
       Klass* klass = SystemDictionary::resolve_or_fail(ik->field_signature(i),
                                                        Handle(THREAD, ik->class_loader()),
                                                        Handle(THREAD, ik->protection_domain()), true, CHECK);
@@ -5754,6 +5746,9 @@
     }
   }
 
+  // Update the loader_data graph.
+  record_defined_class_dependencies(ik, CHECK);
+
   ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);
 
   if (!is_internal()) {
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Mon Oct 23 16:18:53 2017 +0200
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Mon Oct 23 10:40:30 2017 -0400
@@ -369,7 +369,15 @@
   int offset = klass->field_offset(index);
   assert(mirror->obj_field(offset) == NULL,"Field must not be initialized twice");
 
-  Klass* field_k = klass->get_value_field_klass(index);
+  Klass* field_k = klass->get_value_field_klass_or_null(index);
+  if (field_k == NULL) {
+    field_k = SystemDictionary::resolve_or_fail(klass->field_signature(index),
+                                                Handle(THREAD, klass->class_loader()),
+                                                Handle(THREAD, klass->protection_domain()), true, CHECK);
+    assert(field_k != NULL, "Sanity check");
+    assert(field_k->access_flags().is_value_type(), "Value type expected");
+    klass->set_value_field_klass(index, field_k);
+  }
   ValueKlass* field_vklass = ValueKlass::cast(field_k);
   // allocate instance, because it is going to be assigned to a static field
   // it must not be a buffered value
--- a/src/hotspot/share/oops/instanceKlass.hpp	Mon Oct 23 16:18:53 2017 +0200
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Mon Oct 23 10:40:30 2017 -0400
@@ -1239,7 +1239,7 @@
     }
   }
 
-  Klass* get_value_field_klass(int idx) {
+  Klass* get_value_field_klass(int idx) const {
     assert(has_value_fields(), "Sanity checking");
     Klass* k = ((Klass**)adr_value_fields_klasses())[idx];
     assert(k != NULL, "Should always be set before being read");
@@ -1247,6 +1247,13 @@
     return k;
   }
 
+  Klass* get_value_field_klass_or_null(int idx) const {
+    assert(has_value_fields(), "Sanity checking");
+    Klass* k = ((Klass**)adr_value_fields_klasses())[idx];
+    assert(k == NULL || k->is_value(), "Must be a value type");
+    return k;
+  }
+
   void set_value_field_klass(int idx, Klass* k) {
     assert(has_value_fields(), "Sanity checking");
     assert(k != NULL, "Should not be set to NULL");
--- a/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeCreation.java	Mon Oct 23 16:18:53 2017 +0200
+++ b/test/hotspot/jtreg/runtime/valhalla/valuetypes/ValueTypeCreation.java	Mon Oct 23 10:40:30 2017 -0400
@@ -43,6 +43,7 @@
         testLong8();
         // Embedded oops not yet supported
         //testPerson();
+	StaticSelf.test();
     }
 
     void testPoint() {
@@ -72,4 +73,24 @@
         Asserts.assertEquals(person.getFirstName(), "John", "First name incorrect");
         Asserts.assertEquals(person.getLastName(), "Smith", "Last name incorrect");
     }
+
+    static final __ByValue class StaticSelf {
+
+	static final StaticSelf DEFAULT = create(0);
+	final int f1;
+
+	private StaticSelf() { f1 = 0; }
+	public String toString() { return "StaticSelf f1=" + f1; }
+
+	__ValueFactory static StaticSelf create(int f1) {
+	    StaticSelf s = __MakeDefault StaticSelf();
+	    s.f1 = f1;
+	    return s;
+	}
+
+	public static void test() {
+	    String s = DEFAULT.toString();
+	}
+
+    }
 }