< prev index next >

hotspot/src/share/vm/classfile/classFileParser.cpp

Print this page

        

@@ -1467,10 +1467,32 @@
       assert(count[atype] < 0xFFFF, "More than 65535 fields");
       count[atype]++;
     }
     return atype;
   }
+
+  // Attempt to redistribute NONSTATIC_VALUETYPE alloc type
+  FieldAllocationType redistribute_value(bool oops, int value_size) {
+    FieldAllocationType atype = NONSTATIC_VALUETYPE;
+    switch (value_size) {
+    case 1:
+      atype = NONSTATIC_BYTE;
+      break;
+    case 2:
+      atype = NONSTATIC_SHORT;
+      break;
+    case 4:
+      atype = (oops) ? NONSTATIC_OOP : NONSTATIC_WORD;
+      break;
+    default:
+      assert(is_size_aligned(value_size, BytesPerLong), "Unaligned value %d", value_size);
+      return atype;
+    }
+    count[atype]++;
+    count[NONSTATIC_VALUETYPE]--; // Leave only large variable sized behind
+    return atype;
+  }
 };
 
 // Side-effects: populates the _fields, _fields_annotations,
 // _fields_type_annotations fields
 void ClassFileParser::parse_fields(const ClassFileStream* const cfs,

@@ -3810,11 +3832,11 @@
   }
 }
 
 // Layout fields and fill in FieldLayoutInfo.  Could use more refactoring!
 void ClassFileParser::layout_fields(ConstantPool* cp,
-                                    const FieldAllocationCount* fac,
+                                    FieldAllocationCount* fac,
                                     const ClassAnnotationCollector* parsed_annotations,
                                     FieldLayoutInfo* info,
                                     TRAPS) {
 
   assert(cp != NULL, "invariant");

@@ -3833,18 +3855,44 @@
   //
   // We ignore static fields, because @Contended is not supported for them.
   // The layout code below will also ignore the static fields.
   int nonstatic_contended_count = 0;
   FieldAllocationCount fac_contended;
+
+  // Redistribute value types if possible, gather their klasses, oopmap count...
+  unsigned int value_type_oop_map_count = 0;
+  int large_value_count = 0;
+  ValueKlass** nonstatic_value_type_klasses =
+      NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, ValueKlass*, fac->count[NONSTATIC_VALUETYPE]);
+
   for (AllFieldStream fs(_fields, cp); !fs.done(); fs.next()) {
     FieldAllocationType atype = (FieldAllocationType) fs.allocation_type();
     if (fs.is_contended()) {
       fac_contended.count[atype]++;
       if (!fs.access_flags().is_static()) {
         nonstatic_contended_count++;
       }
     }
+    else if (atype == NONSTATIC_VALUETYPE) {
+      Symbol* signature = fs.signature();
+      Klass* klass = SystemDictionary::resolve_or_fail(signature,
+                                                       Handle(THREAD, _loader_data->class_loader()),
+                                                       _protection_domain, true, CHECK);
+      assert(klass != NULL && klass->access_flags().is_value_type(), "Sanity check");
+      ValueKlass* vklass = ValueKlass::cast(klass);
+      if (vklass->contains_oops()) {
+        value_type_oop_map_count += vklass->nonstatic_oop_map_count();
+      }
+      int raw_value_size = vklass->raw_value_byte_size();
+      FieldAllocationType atype = fac->redistribute_value(vklass->contains_oops(), raw_value_size);
+      if (atype == NONSTATIC_VALUETYPE) {
+        // Failed to slot in with the others, allocate large values last jlong align for safe copy
+        nonstatic_value_type_klasses[large_value_count++] = vklass;
+      } else {
+        fs.coerce_allocation_type(NONSTATIC_VALUETYPE, (int) atype);
+      }
+    }
   }
 
 
   // Calculate the starting byte offsets
   int next_static_oop_offset    = InstanceMirrorKlass::offset_of_static_fields();

@@ -3901,47 +3949,11 @@
   unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
   unsigned int nonstatic_word_count   = fac->count[NONSTATIC_WORD]   - fac_contended.count[NONSTATIC_WORD];
   unsigned int nonstatic_short_count  = fac->count[NONSTATIC_SHORT]  - fac_contended.count[NONSTATIC_SHORT];
   unsigned int nonstatic_byte_count   = fac->count[NONSTATIC_BYTE]   - fac_contended.count[NONSTATIC_BYTE];
   unsigned int nonstatic_oop_count    = fac->count[NONSTATIC_OOP]    - fac_contended.count[NONSTATIC_OOP];
-
-  int static_value_type_count = 0;
-  int nonstatic_value_type_count = 0;
-  int* nonstatic_value_type_indexes = NULL;
-  Klass** nonstatic_value_type_klasses = NULL;
-  unsigned int value_type_oop_map_count = 0;
-
-  int max_nonstatic_value_type = fac->count[NONSTATIC_VALUETYPE] + 1;
-
-  nonstatic_value_type_indexes = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, int,
-                                                              max_nonstatic_value_type);
-  for (int i = 0; i < max_nonstatic_value_type; i++) {
-    nonstatic_value_type_indexes[i] = -1;
-  }
-  nonstatic_value_type_klasses = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, Klass*,
-                                                              max_nonstatic_value_type);
-
-  for (AllFieldStream fs(_fields, _cp); !fs.done(); fs.next()) {
-    if (fs.allocation_type() == STATIC_VALUETYPE) {
-      static_value_type_count++;
-    } else if (fs.allocation_type() == NONSTATIC_VALUETYPE) {
-      Symbol* signature = fs.signature();
-      Klass* klass = SystemDictionary::resolve_or_fail(signature,
-                                                       Handle(THREAD, _loader_data->class_loader()),
-                                                       _protection_domain, true, CHECK);
-      assert(klass != NULL, "Sanity check");
-      assert(klass->access_flags().is_value_type(), "Value type expected");
-      nonstatic_value_type_indexes[nonstatic_value_type_count] = fs.index();
-      nonstatic_value_type_klasses[nonstatic_value_type_count] = klass;
-      nonstatic_value_type_count++;
-
-      ValueKlass* vklass = ValueKlass::cast(klass);
-      if (vklass->contains_oops()) {
-        value_type_oop_map_count += vklass->nonstatic_oop_map_count();
-      }
-    }
-  }
+  unsigned int nonstatic_value_type_count = fac->count[NONSTATIC_VALUETYPE];
 
   // Total non-static fields count, including every contended field
   unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
                                         fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
                                         fac->count[NONSTATIC_OOP] + fac->count[NONSTATIC_VALUETYPE];

@@ -4151,29 +4163,24 @@
         real_offset = next_static_double_offset;
         next_static_double_offset += BytesPerLong;
         break;
       case NONSTATIC_VALUETYPE:
       {
-        Klass* klass = nonstatic_value_type_klasses[next_value_type_index];
-        assert(klass != NULL, "Klass should have been loaded and resolved earlier");
-        assert(klass->access_flags().is_value_type(),"Must be a value type");
-        ValueKlass* vklass = ValueKlass::cast(klass);
         real_offset = next_nonstatic_valuetype_offset;
-        next_nonstatic_valuetype_offset += (vklass->size_helper()) * wordSize - vklass->first_field_offset();
-        // aligning next value type on a 64 bits boundary
-        next_nonstatic_valuetype_offset = align_size_up(next_nonstatic_valuetype_offset, BytesPerLong);
-        next_value_type_index += 1;
 
+        assert(next_value_type_index < large_value_count, "Incorrect number of value alloc types");
+        ValueKlass* vklass = nonstatic_value_type_klasses[next_value_type_index++];
         if (vklass->contains_oops()) { // add flatten oop maps
           int diff = real_offset - vklass->first_field_offset();
           const OopMapBlock* map = vklass->start_of_nonstatic_oop_maps();
           const OopMapBlock* const last_map = map + vklass->nonstatic_oop_map_count();
           while (map < last_map) {
             nonstatic_oop_maps->add(map->offset() + diff, map->count());
             map++;
           }
         }
+        next_nonstatic_valuetype_offset += vklass->raw_value_byte_size();
       }
       break;
       case NONSTATIC_OOP:
         if( nonstatic_oop_space_count > 0 ) {
           real_offset = nonstatic_oop_space_offset;

@@ -4340,11 +4347,11 @@
     assert(!is_value_type() && !is_derive_value_type(), "@Contended not supported for value types yet");
     next_nonstatic_padded_offset += ContendedPaddingWidth;
   }
 
   int notaligned_nonstatic_fields_end;
-  if (nonstatic_value_type_count != 0) {
+  if (has_nonstatic_value_fields) {
     notaligned_nonstatic_fields_end = next_nonstatic_valuetype_offset;
   } else {
     notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
   }
 
< prev index next >