< prev index next >

src/hotspot/share/oops/valueKlass.cpp

Print this page




  29 #include "interpreter/interpreter.hpp"
  30 #include "logging/log.hpp"
  31 #include "memory/metadataFactory.hpp"
  32 #include "oops/access.hpp"
  33 #include "oops/compressedOops.inline.hpp"
  34 #include "oops/fieldStreams.hpp"
  35 #include "oops/instanceKlass.inline.hpp"
  36 #include "oops/method.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "oops/objArrayKlass.hpp"
  39 #include "oops/valueKlass.hpp"
  40 #include "oops/valueArrayKlass.hpp"
  41 #include "runtime/fieldDescriptor.inline.hpp"
  42 #include "runtime/handles.inline.hpp"
  43 #include "runtime/safepointVerifiers.hpp"
  44 #include "runtime/sharedRuntime.hpp"
  45 #include "runtime/signature.hpp"
  46 #include "runtime/thread.inline.hpp"
  47 #include "utilities/copy.hpp"
  48 
  49 int ValueKlass::first_field_offset_old() const {
  50 #ifdef ASSERT
  51   int first_offset = INT_MAX;
  52   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
  53     if (fs.offset() < first_offset) first_offset= fs.offset();
  54   }
  55 #endif
  56   int base_offset = instanceOopDesc::base_offset_in_bytes();
  57   // The first field of value types is aligned on a long boundary
  58   base_offset = align_up(base_offset, BytesPerLong);
  59   assert(base_offset == first_offset, "inconsistent offsets");
  60   return base_offset;
  61 }
  62 
  63 int ValueKlass::raw_value_byte_size() const {
  64   int heapOopAlignedSize = nonstatic_field_size() << LogBytesPerHeapOop;
  65   // If bigger than 64 bits or needs oop alignment, then use jlong aligned
  66   // which for values should be jlong aligned, asserts in raw_field_copy otherwise
  67   if (heapOopAlignedSize >= longSize || contains_oops()) {
  68     return heapOopAlignedSize;
  69   }
  70   // Small primitives...
  71   // If a few small basic type fields, return the actual size, i.e.
  72   // 1 byte = 1
  73   // 2 byte = 2
  74   // 3 byte = 4, because pow2 needed for element stores
  75   int first_offset = first_field_offset();
  76   int last_offset  = 0; // find the last offset, add basic type size
  77   int last_tsz     = 0;
  78   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
  79     if (fs.access_flags().is_static()) {
  80       continue;
  81     } else if (fs.offset() > last_offset) {
  82       BasicType type = fs.field_descriptor().field_type();
  83       if (is_java_primitive(type)) {
  84         last_tsz = type2aelembytes(type);
  85       } else if (type == T_VALUETYPE) {
  86         // Not just primitives. Layout aligns embedded value, so use jlong aligned it is
  87         return heapOopAlignedSize;
  88       } else {
  89         guarantee(0, "Unknown type %d", type);
  90       }
  91       assert(last_tsz != 0, "Invariant");
  92       last_offset = fs.offset();
  93     }
  94   }
  95   // Assumes VT with no fields are meaningless and illegal
  96   last_offset += last_tsz;
  97   assert(last_offset > first_offset && last_tsz, "Invariant");
  98   return 1 << upper_log2(last_offset - first_offset);
  99 }
 100 
 101 instanceOop ValueKlass::allocate_instance(TRAPS) {
 102   int size = size_helper();  // Query before forming handle.


 312 // Value type arguments are not passed by reference, instead each
 313 // field of the value type is passed as an argument. This helper
 314 // function collects the fields of the value types (including embedded
 315 // value type's fields) in a list. Included with the field's type is
 316 // the offset of each field in the value type: i2c and c2i adapters
 317 // need that to load or store fields. Finally, the list of fields is
 318 // sorted in order of increasing offsets: the adapters and the
 319 // compiled code need to agree upon the order of fields.
 320 //
 321 // The list of basic types that is returned starts with a T_VALUETYPE
 322 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID pairs are used as
 323 // delimiters. Every entry between the two is a field of the value
 324 // type. If there's an embedded value type in the list, it also starts
 325 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
 326 // generate a unique fingerprint for the method's adapters and we can
 327 // generate the list of basic types from the interpreter point of view
 328 // (value types passed as reference: iterate on the list until a
 329 // T_VALUETYPE, drop everything until and including the closing
 330 // T_VOID) or the compiler point of view (each field of the value
 331 // types is an argument: drop all T_VALUETYPE/T_VOID from the list).
 332 int ValueKlass::collect_fields(GrowableArray<SigEntry>* sig, int base_off) const {
 333   int count = 0;
 334   SigEntry::add_entry(sig, T_VALUETYPE, base_off);
 335   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
 336     if (fs.access_flags().is_static()) continue;
 337     int offset = base_off + fs.offset() - (base_off > 0 ? first_field_offset() : 0);
 338     if (fs.is_flattened()) {
 339       // Resolve klass of flattened value type field and recursively collect fields
 340       Klass* vk = get_value_field_klass(fs.index());
 341       count += ValueKlass::cast(vk)->collect_fields(sig, offset);
 342     } else {
 343       BasicType bt = FieldType::basic_type(fs.signature());
 344       if (bt == T_VALUETYPE) {
 345         bt = T_OBJECT;
 346       }
 347       SigEntry::add_entry(sig, bt, offset);
 348       count += type2size[bt];
 349     }
 350   }
 351   int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
 352   SigEntry::add_entry(sig, T_VOID, offset);
 353   if (base_off == 0) {
 354     sig->sort(SigEntry::compare);
 355   }




  29 #include "interpreter/interpreter.hpp"
  30 #include "logging/log.hpp"
  31 #include "memory/metadataFactory.hpp"
  32 #include "oops/access.hpp"
  33 #include "oops/compressedOops.inline.hpp"
  34 #include "oops/fieldStreams.hpp"
  35 #include "oops/instanceKlass.inline.hpp"
  36 #include "oops/method.hpp"
  37 #include "oops/oop.inline.hpp"
  38 #include "oops/objArrayKlass.hpp"
  39 #include "oops/valueKlass.hpp"
  40 #include "oops/valueArrayKlass.hpp"
  41 #include "runtime/fieldDescriptor.inline.hpp"
  42 #include "runtime/handles.inline.hpp"
  43 #include "runtime/safepointVerifiers.hpp"
  44 #include "runtime/sharedRuntime.hpp"
  45 #include "runtime/signature.hpp"
  46 #include "runtime/thread.inline.hpp"
  47 #include "utilities/copy.hpp"
  48 
  49 int ValueKlass::first_field_offset_old() {
  50 #ifdef ASSERT
  51   int first_offset = INT_MAX;
  52   for (AllFieldStream fs(this); !fs.done(); fs.next()) {
  53     if (fs.offset() < first_offset) first_offset= fs.offset();
  54   }
  55 #endif
  56   int base_offset = instanceOopDesc::base_offset_in_bytes();
  57   // The first field of value types is aligned on a long boundary
  58   base_offset = align_up(base_offset, BytesPerLong);
  59   assert(base_offset == first_offset, "inconsistent offsets");
  60   return base_offset;
  61 }
  62 
  63 int ValueKlass::raw_value_byte_size() {
  64   int heapOopAlignedSize = nonstatic_field_size() << LogBytesPerHeapOop;
  65   // If bigger than 64 bits or needs oop alignment, then use jlong aligned
  66   // which for values should be jlong aligned, asserts in raw_field_copy otherwise
  67   if (heapOopAlignedSize >= longSize || contains_oops()) {
  68     return heapOopAlignedSize;
  69   }
  70   // Small primitives...
  71   // If a few small basic type fields, return the actual size, i.e.
  72   // 1 byte = 1
  73   // 2 byte = 2
  74   // 3 byte = 4, because pow2 needed for element stores
  75   int first_offset = first_field_offset();
  76   int last_offset  = 0; // find the last offset, add basic type size
  77   int last_tsz     = 0;
  78   for (AllFieldStream fs(this); !fs.done(); fs.next()) {
  79     if (fs.access_flags().is_static()) {
  80       continue;
  81     } else if (fs.offset() > last_offset) {
  82       BasicType type = char2type(fs.signature()->char_at(0));
  83       if (is_java_primitive(type)) {
  84         last_tsz = type2aelembytes(type);
  85       } else if (type == T_VALUETYPE) {
  86         // Not just primitives. Layout aligns embedded value, so use jlong aligned it is
  87         return heapOopAlignedSize;
  88       } else {
  89         guarantee(0, "Unknown type %d", type);
  90       }
  91       assert(last_tsz != 0, "Invariant");
  92       last_offset = fs.offset();
  93     }
  94   }
  95   // Assumes VT with no fields are meaningless and illegal
  96   last_offset += last_tsz;
  97   assert(last_offset > first_offset && last_tsz, "Invariant");
  98   return 1 << upper_log2(last_offset - first_offset);
  99 }
 100 
 101 instanceOop ValueKlass::allocate_instance(TRAPS) {
 102   int size = size_helper();  // Query before forming handle.


 312 // Value type arguments are not passed by reference, instead each
 313 // field of the value type is passed as an argument. This helper
 314 // function collects the fields of the value types (including embedded
 315 // value type's fields) in a list. Included with the field's type is
 316 // the offset of each field in the value type: i2c and c2i adapters
 317 // need that to load or store fields. Finally, the list of fields is
 318 // sorted in order of increasing offsets: the adapters and the
 319 // compiled code need to agree upon the order of fields.
 320 //
 321 // The list of basic types that is returned starts with a T_VALUETYPE
 322 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID pairs are used as
 323 // delimiters. Every entry between the two is a field of the value
 324 // type. If there's an embedded value type in the list, it also starts
 325 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
 326 // generate a unique fingerprint for the method's adapters and we can
 327 // generate the list of basic types from the interpreter point of view
 328 // (value types passed as reference: iterate on the list until a
 329 // T_VALUETYPE, drop everything until and including the closing
 330 // T_VOID) or the compiler point of view (each field of the value
 331 // types is an argument: drop all T_VALUETYPE/T_VOID from the list).
 332 int ValueKlass::collect_fields(GrowableArray<SigEntry>* sig, int base_off) {
 333   int count = 0;
 334   SigEntry::add_entry(sig, T_VALUETYPE, base_off);
 335   for (AllFieldStream fs(this); !fs.done(); fs.next()) {
 336     if (fs.access_flags().is_static()) continue;
 337     int offset = base_off + fs.offset() - (base_off > 0 ? first_field_offset() : 0);
 338     if (fs.is_flattened()) {
 339       // Resolve klass of flattened value type field and recursively collect fields
 340       Klass* vk = get_value_field_klass(fs.index());
 341       count += ValueKlass::cast(vk)->collect_fields(sig, offset);
 342     } else {
 343       BasicType bt = FieldType::basic_type(fs.signature());
 344       if (bt == T_VALUETYPE) {
 345         bt = T_OBJECT;
 346       }
 347       SigEntry::add_entry(sig, bt, offset);
 348       count += type2size[bt];
 349     }
 350   }
 351   int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0);
 352   SigEntry::add_entry(sig, T_VOID, offset);
 353   if (base_off == 0) {
 354     sig->sort(SigEntry::compare);
 355   }


< prev index next >