297 // The list of basic types that is returned starts with a T_VALUETYPE 298 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as 299 // delimiters. Every entry between the two is a field of the value 300 // type. If there's an embedded value type in the list, it also starts 301 // with a T_VALUETYPE and ends with a T_VOID. This is so we can 302 // generate a unique fingerprint for the method's adapters and we can 303 // generate the list of basic types from the interpreter point of view 304 // (value types passed as reference: iterate on the list until a 305 // T_VALUETYPE, drop everything until and including the closing 306 // T_VOID) or the compiler point of view (each field of the value 307 // types is an argument: drop all T_VALUETYPE/T_VOID from the list). 308 GrowableArray<SigEntry> ValueKlass::collect_fields(int base_off) const { 309 GrowableArray<SigEntry> sig_extended; 310 sig_extended.push(SigEntry(T_VALUETYPE, base_off)); 311 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { 312 if (fs.access_flags().is_static()) continue; 313 fieldDescriptor& fd = fs.field_descriptor(); 314 BasicType bt = fd.field_type(); 315 int offset = base_off + fd.offset() - (base_off > 0 ? first_field_offset() : 0); 316 if (bt == T_VALUETYPE) { 317 Symbol* signature = fd.signature(); 318 JavaThread* THREAD = JavaThread::current(); 319 oop loader = class_loader(); 320 oop domain = protection_domain(); 321 ResetNoHandleMark rnhm; 322 HandleMark hm; 323 NoSafepointVerifier nsv; 324 Klass* klass = SystemDictionary::resolve_or_null(signature, 325 Handle(THREAD, loader), Handle(THREAD, domain), 326 THREAD); 327 assert(klass != NULL && !HAS_PENDING_EXCEPTION, "lookup shouldn't fail"); 328 const GrowableArray<SigEntry>& embedded = ValueKlass::cast(klass)->collect_fields(offset); 329 sig_extended.appendAll(&embedded); 330 } else { 331 sig_extended.push(SigEntry(bt, offset)); 332 if (bt == T_LONG || bt == T_DOUBLE) { 333 sig_extended.push(SigEntry(T_VOID, offset)); 334 } 335 } 336 } 337 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0); 338 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields 339 if (base_off == 0) { 340 sig_extended.sort(SigEntry::compare); 341 } 342 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure"); 343 return sig_extended; 344 } 345 346 void ValueKlass::initialize_calling_convention() { 347 // Because the pack and unpack handler addresses need to be loadable from generated code, 348 // they are stored at a fixed offset in the klass metadata. Since value type klasses do 349 // not have a vtable, the vtable offset is used to store these addresses. | 297 // The list of basic types that is returned starts with a T_VALUETYPE 298 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as 299 // delimiters. Every entry between the two is a field of the value 300 // type. If there's an embedded value type in the list, it also starts 301 // with a T_VALUETYPE and ends with a T_VOID. This is so we can 302 // generate a unique fingerprint for the method's adapters and we can 303 // generate the list of basic types from the interpreter point of view 304 // (value types passed as reference: iterate on the list until a 305 // T_VALUETYPE, drop everything until and including the closing 306 // T_VOID) or the compiler point of view (each field of the value 307 // types is an argument: drop all T_VALUETYPE/T_VOID from the list). 308 GrowableArray<SigEntry> ValueKlass::collect_fields(int base_off) const { 309 GrowableArray<SigEntry> sig_extended; 310 sig_extended.push(SigEntry(T_VALUETYPE, base_off)); 311 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { 312 if (fs.access_flags().is_static()) continue; 313 fieldDescriptor& fd = fs.field_descriptor(); 314 BasicType bt = fd.field_type(); 315 int offset = base_off + fd.offset() - (base_off > 0 ? first_field_offset() : 0); 316 if (bt == T_VALUETYPE) { 317 if (fd.is_flatten()) { 318 Symbol* signature = fd.signature(); 319 JavaThread* THREAD = JavaThread::current(); 320 oop loader = class_loader(); 321 oop domain = protection_domain(); 322 ResetNoHandleMark rnhm; 323 HandleMark hm; 324 NoSafepointVerifier nsv; 325 Klass* klass = SystemDictionary::resolve_or_null(signature, 326 Handle(THREAD, loader), Handle(THREAD, domain), 327 THREAD); 328 assert(klass != NULL && !HAS_PENDING_EXCEPTION, "lookup shouldn't fail"); 329 const GrowableArray<SigEntry>& embedded = ValueKlass::cast(klass)->collect_fields(offset); 330 sig_extended.appendAll(&embedded); 331 } else { 332 sig_extended.push(SigEntry(T_OBJECT, offset)); 333 } 334 } else { 335 sig_extended.push(SigEntry(bt, offset)); 336 if (bt == T_LONG || bt == T_DOUBLE) { 337 sig_extended.push(SigEntry(T_VOID, offset)); 338 } 339 } 340 } 341 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0); 342 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields 343 if (base_off == 0) { 344 sig_extended.sort(SigEntry::compare); 345 } 346 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure"); 347 return sig_extended; 348 } 349 350 void ValueKlass::initialize_calling_convention() { 351 // Because the pack and unpack handler addresses need to be loadable from generated code, 352 // they are stored at a fixed offset in the klass metadata. Since value type klasses do 353 // not have a vtable, the vtable offset is used to store these addresses. |