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 } |