< prev index next >

src/hotspot/share/classfile/classFileParser.cpp

Print this page

        

@@ -1544,11 +1544,11 @@
 
   int num_injected = 0;
   const InjectedField* const injected = JavaClasses::get_injected(_class_name,
                                                                   &num_injected);
 
-  const int total_fields = length + num_injected + (is_value_type ? 1 : 0);
+  const int total_fields = length + num_injected + (is_value_type ? 2 : 0);
 
   // The field array starts with tuples of shorts
   // [access, name index, sig index, initial value index, byte offset].
   // A generic signature slot only exists for field with generic
   // signature attribute. And the access flag is set with

@@ -1574,10 +1574,11 @@
                                               total_fields * (FieldInfo::field_slots + 1));
 
   // The generic signature slots start after all other fields' data.
   int generic_signature_slot = total_fields * FieldInfo::field_slots;
   int num_generic_signature = 0;
+  int instance_fields_count = 0;
   for (int n = 0; n < length; n++) {
     // access_flags, name_index, descriptor_index, attributes_count
     cfs->guarantee_more(8, CHECK);
 
     jint recognized_modifiers = JVM_RECOGNIZED_FIELD_MODIFIERS;

@@ -1614,10 +1615,11 @@
             " ACC_FLATTENABLE cannot be specified for an array",
             name->as_C_string(), sig->as_klass_external_name(), CHECK);
       }
       _has_flattenable_fields = true;
     }
+    if (!access_flags.is_static()) instance_fields_count++;
 
     u2 constantvalue_index = 0;
     bool is_synthetic = false;
     u2 generic_signature_index = 0;
     const bool is_static = access_flags.is_static();

@@ -1721,11 +1723,10 @@
       index++;
     }
   }
 
   if (is_value_type) {
-    index = length + num_injected;
     FieldInfo* const field = FieldInfo::from_field_array(fa, index);
     field->initialize(JVM_ACC_FIELD_INTERNAL | JVM_ACC_STATIC,
                       vmSymbols::default_value_name_enum,
                       vmSymbols::java_lang_Object_enum,
                       0);

@@ -1733,10 +1734,23 @@
     const FieldAllocationType atype = fac->update(true, type, false);
     field->set_allocation_type(atype);
     index++;
   }
 
+  if (is_value_type && instance_fields_count == 0) {
+    _is_empty_value = true;
+    FieldInfo* const field = FieldInfo::from_field_array(fa, index);
+    field->initialize(JVM_ACC_FIELD_INTERNAL,
+        vmSymbols::empty_marker_name_enum,
+        vmSymbols::byte_signature_enum,
+        0);
+    const BasicType type = FieldType::basic_type(vmSymbols::byte_signature());
+    const FieldAllocationType atype = fac->update(false, type, false);
+    field->set_allocation_type(atype);
+    index++;
+  }
+
   assert(NULL == _fields, "invariant");
 
   _fields =
     MetadataFactory::new_array<u2>(_loader_data,
                                    index * FieldInfo::field_slots + num_generic_signature,

@@ -5791,10 +5805,13 @@
   ik->set_should_verify_class(_need_verify);
 
   // Not yet: supers are done below to support the new subtype-checking fields
   ik->set_nonstatic_field_size(_field_info->nonstatic_field_size);
   ik->set_has_nonstatic_fields(_field_info->has_nonstatic_fields);
+  if (_is_empty_value) {
+    ik->set_is_empty_value();
+  }
   assert(_fac != NULL, "invariant");
   ik->set_static_oop_field_count(_fac->count[STATIC_OOP] + _fac->count[STATIC_FLATTENABLE]);
 
   // this transfers ownership of a lot of arrays from
   // the parser onto the InstanceKlass*

@@ -5959,13 +5976,18 @@
       ValueKlass::cast(ik)->set_default_value_offset(ik->field_offset(i));
     }
   }
 
   if (is_value_type()) {
-    ValueKlass::cast(ik)->set_alignment(_alignment);
-    ValueKlass::cast(ik)->set_first_field_offset(_first_field_offset);
-    ValueKlass::cast(ik)->set_exact_size_in_bytes(_exact_size_in_bytes);
+    ValueKlass* vk = ValueKlass::cast(ik);
+    if (UseNewLayout) {
+      vk->set_alignment(_alignment);
+      vk->set_first_field_offset(_first_field_offset);
+      vk->set_exact_size_in_bytes(_exact_size_in_bytes);
+    } else {
+      vk->set_first_field_offset(vk->first_field_offset_old());
+    }
     ValueKlass::cast(ik)->initialize_calling_convention(CHECK);
   }
 
   ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);
 

@@ -6155,10 +6177,11 @@
   _relax_verify(false),
   _has_nonstatic_concrete_methods(false),
   _declares_nonstatic_concrete_methods(false),
   _has_final_method(false),
   _has_flattenable_fields(false),
+  _is_empty_value(false),
   _has_finalizer(false),
   _has_empty_finalizer(false),
   _has_vanilla_constructor(false),
   _max_bootstrap_specifier_index(-1) {
 
< prev index next >