251 while (map != end) { 252 address doop_address = dst_oop_addr + map->offset(); 253 bs->write_ref_array((HeapWord*) doop_address, map->count()); 254 map++; 255 } 256 } else { // Buffered value case 257 raw_field_copy(src, dst, raw_byte_size); 258 } 259 } else { // Primitive-only case... 260 raw_field_copy(src, dst, raw_byte_size); 261 } 262 } 263 264 // Value type arguments are not passed by reference, instead each 265 // field of the value type is passed as an argument. This helper 266 // function collects the fields of the value types (including embedded 267 // value type's fields) in a list. Included with the field's type is 268 // the offset of each field in the value type: i2c and c2i adapters 269 // need that to load or store fields. Finally, the list of fields is 270 // sorted in order of increasing offsets: the adapters and the 271 // compiled code need and agreed upon order of fields. 272 // 273 // The list of basic types that is returned starts with a T_VALUETYPE 274 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as 275 // delimiters. Every entry between the two is a field of the value 276 // type. If there's an embedded value type in the list, it also starts 277 // with a T_VALUETYPE and ends with a T_VOID. This is so we can 278 // generate a unique fingerprint for the method's adapters and we can 279 // generate the list of basic types from the interpreter point of view 280 // (value types passed as reference: iterate on the list until a 281 // T_VALUETYPE, drop everything until and including the closing 282 // T_VOID) or the compiler point of view (each field of the value 283 // types is an argument: drop all T_VALUETYPE/T_VOID from the list). 284 GrowableArray<SigEntry> ValueKlass::collect_fields(int base_off) const { 285 GrowableArray<SigEntry> sig_extended; 286 sig_extended.push(SigEntry(T_VALUETYPE, base_off)); 287 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { 288 if (fs.access_flags().is_static()) continue; 289 fieldDescriptor& fd = fs.field_descriptor(); 290 BasicType bt = fd.field_type(); 291 int offset = base_off + fd.offset() - (base_off > 0 ? first_field_offset() : 0); 292 if (bt == T_VALUETYPE) { 293 if (fd.is_flattened()) { 294 Symbol* signature = fd.signature(); 295 JavaThread* THREAD = JavaThread::current(); 296 oop loader = class_loader(); 297 oop domain = protection_domain(); 298 ResetNoHandleMark rnhm; 299 HandleMark hm; 300 NoSafepointVerifier nsv; 301 Klass* klass = SystemDictionary::resolve_or_null(signature, 302 Handle(THREAD, loader), Handle(THREAD, domain), 303 THREAD); 304 assert(klass != NULL && !HAS_PENDING_EXCEPTION, "lookup shouldn't fail"); 305 const GrowableArray<SigEntry>& embedded = ValueKlass::cast(klass)->collect_fields(offset); 306 sig_extended.appendAll(&embedded); 307 } else { 308 sig_extended.push(SigEntry(T_VALUETYPEPTR, offset)); 309 } 310 } else { 311 sig_extended.push(SigEntry(bt, offset)); 312 if (bt == T_LONG || bt == T_DOUBLE) { 313 sig_extended.push(SigEntry(T_VOID, offset)); 314 } 315 } 316 } 317 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0); 318 sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields 319 if (base_off == 0) { 320 sig_extended.sort(SigEntry::compare); 321 } 322 assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure"); 323 return sig_extended; 324 } 325 326 void ValueKlass::initialize_calling_convention() { 327 // Because the pack and unpack handler addresses need to be loadable from generated code, 328 // they are stored at a fixed offset in the klass metadata. Since value type klasses do 329 // not have a vtable, the vtable offset is used to store these addresses. 330 //guarantee(vtable_length() == 0, "vtables are not supported in value klasses"); 331 if (ValueTypeReturnedAsFields || ValueTypePassFieldsAsArgs) { 332 Thread* THREAD = Thread::current(); 333 assert(!HAS_PENDING_EXCEPTION, "should have no exception"); 334 ResourceMark rm; 335 const GrowableArray<SigEntry>& sig_vk = collect_fields(); 336 int nb_fields = SigEntry::count_fields(sig_vk)+1; 337 Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR); 338 *((Array<SigEntry>**)adr_extended_sig()) = extended_sig; 339 for (int i = 0; i < sig_vk.length(); i++) { 340 extended_sig->at_put(i, sig_vk.at(i)); 341 } 342 343 if (ValueTypeReturnedAsFields) { 344 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields); 345 sig_bt[0] = T_METADATA; 346 SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true); 347 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields); 348 int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields); 349 350 if (total > 0) { 351 Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK_AND_CLEAR); 352 *((Array<VMRegPair>**)adr_return_regs()) = return_regs; 353 for (int i = 0; i < nb_fields; i++) { 354 return_regs->at_put(i, regs[i]); 355 } 356 357 BufferedValueTypeBlob* buffered_blob = SharedRuntime::generate_buffered_value_type_adapter(this); 358 *((address*)adr_pack_handler()) = buffered_blob->pack_fields(); 359 *((address*)adr_unpack_handler()) = buffered_blob->unpack_fields(); 360 assert(CodeCache::find_blob(pack_handler()) == buffered_blob, "lost track of blob"); 361 } 362 } 363 } 364 } 365 366 void ValueKlass::deallocate_contents(ClassLoaderData* loader_data) { 367 if (extended_sig() != NULL) { 368 MetadataFactory::free_array<SigEntry>(loader_data, extended_sig()); 369 } 370 if (return_regs() != NULL) { 371 MetadataFactory::free_array<VMRegPair>(loader_data, return_regs()); 385 BufferBlob::free((BufferBlob*)buffered_blob); 386 *((address*)adr_pack_handler()) = NULL; 387 *((address*)adr_unpack_handler()) = NULL; 388 } 389 } 390 391 // Can this value type be returned as multiple values? 392 bool ValueKlass::can_be_returned_as_fields() const { 393 return return_regs() != NULL; 394 } 395 396 // Create handles for all oop fields returned in registers that are going to be live across a safepoint 397 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const { 398 Thread* thread = Thread::current(); 399 const Array<SigEntry>* sig_vk = extended_sig(); 400 const Array<VMRegPair>* regs = return_regs(); 401 int j = 1; 402 403 for (int i = 0; i < sig_vk->length(); i++) { 404 BasicType bt = sig_vk->at(i)._bt; 405 if (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY) { 406 int off = sig_vk->at(i)._offset; 407 VMRegPair pair = regs->at(j); 408 address loc = reg_map.location(pair.first()); 409 oop v = *(oop*)loc; 410 assert(v == NULL || oopDesc::is_oop(v), "not an oop?"); 411 assert(Universe::heap()->is_in_or_null(v), "must be heap pointer"); 412 handles.push(Handle(thread, v)); 413 } 414 if (bt == T_VALUETYPE) { 415 continue; 416 } 417 if (bt == T_VOID && 418 sig_vk->at(i-1)._bt != T_LONG && 419 sig_vk->at(i-1)._bt != T_DOUBLE) { 420 continue; 421 } 422 j++; 423 } 424 assert(j == regs->length(), "missed a field?"); 425 } 426 427 // Update oop fields in registers from handles after a safepoint 428 void ValueKlass::restore_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const { 429 assert(ValueTypeReturnedAsFields, "inconsistent"); 430 const Array<SigEntry>* sig_vk = extended_sig(); 431 const Array<VMRegPair>* regs = return_regs(); 432 assert(regs != NULL, "inconsistent"); 433 434 int j = 1; 435 for (int i = 0, k = 0; i < sig_vk->length(); i++) { 436 BasicType bt = sig_vk->at(i)._bt; 437 if (bt == T_OBJECT || bt == T_ARRAY) { 438 int off = sig_vk->at(i)._offset; 439 VMRegPair pair = regs->at(j); 440 address loc = reg_map.location(pair.first()); 441 *(oop*)loc = handles.at(k++)(); 442 } 443 if (bt == T_VALUETYPE) { 444 continue; 445 } 446 if (bt == T_VOID && 447 sig_vk->at(i-1)._bt != T_LONG && 448 sig_vk->at(i-1)._bt != T_DOUBLE) { 449 continue; 450 } 451 j++; 452 } 453 assert(j == regs->length(), "missed a field?"); 454 } 455 456 // Fields are in registers. Create an instance of the value type and 457 // initialize it with the values of the fields. 458 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) { 459 460 oop new_vt = allocate_instance(CHECK_NULL); 461 const Array<SigEntry>* sig_vk = extended_sig(); 462 const Array<VMRegPair>* regs = return_regs(); 463 464 int j = 1; 465 int k = 0; 466 for (int i = 0; i < sig_vk->length(); i++) { 467 BasicType bt = sig_vk->at(i)._bt; 468 if (bt == T_VALUETYPE) { 469 continue; 470 } 471 if (bt == T_VOID) { 472 if (sig_vk->at(i-1)._bt == T_LONG || 473 sig_vk->at(i-1)._bt == T_DOUBLE) { 474 j++; 475 } 476 continue; 477 } 478 int off = sig_vk->at(i)._offset; 479 VMRegPair pair = regs->at(j); 480 address loc = reg_map.location(pair.first()); 481 switch(bt) { 482 case T_BOOLEAN: { 483 jboolean v = *(intptr_t*)loc; 484 *(jboolean*)((address)new_vt + off) = v; 485 break; 486 } 487 case T_CHAR: { 488 jchar v = *(intptr_t*)loc; 489 *(jchar*)((address)new_vt + off) = v; 490 break; 491 } 492 case T_BYTE: { 493 jbyte v = *(intptr_t*)loc; 494 *(jbyte*)((address)new_vt + off) = v; 495 break; 496 } 497 case T_SHORT: { 498 jshort v = *(intptr_t*)loc; 499 *(jshort*)((address)new_vt + off) = v; 500 break; 501 } 502 case T_INT: { 503 jint v = *(intptr_t*)loc; 504 *(jint*)((address)new_vt + off) = v; 505 break; 506 } 507 case T_LONG: { 508 #ifdef _LP64 509 jlong v = *(intptr_t*)loc; 510 *(jlong*)((address)new_vt + off) = v; 511 #else 512 Unimplemented(); 513 #endif 514 break; 515 } 516 case T_OBJECT: 517 case T_VALUETYPEPTR: 518 case T_ARRAY: { 519 Handle handle = handles.at(k++); 520 HeapAccess<>::oop_store_at(new_vt, off, handle()); 521 break; 522 } 523 case T_FLOAT: { 524 jfloat v = *(jfloat*)loc; 525 *(jfloat*)((address)new_vt + off) = v; 526 break; 527 } 528 case T_DOUBLE: { 529 jdouble v = *(jdouble*)loc; 530 *(jdouble*)((address)new_vt + off) = v; 531 break; 532 } 533 default: 534 ShouldNotReachHere(); 535 } 536 *(intptr_t*)loc = 0xDEAD; 537 j++; 538 } 539 assert(j == regs->length(), "missed a field?"); 540 assert(k == handles.length(), "missed an oop?"); 541 return new_vt; 542 } 543 544 // Check the return register for a ValueKlass oop 545 ValueKlass* ValueKlass::returned_value_klass(const RegisterMap& map) { 546 BasicType bt = T_METADATA; 547 VMRegPair pair; 548 int nb = SharedRuntime::java_return_convention(&bt, &pair, 1); 549 assert(nb == 1, "broken"); 550 | 251 while (map != end) { 252 address doop_address = dst_oop_addr + map->offset(); 253 bs->write_ref_array((HeapWord*) doop_address, map->count()); 254 map++; 255 } 256 } else { // Buffered value case 257 raw_field_copy(src, dst, raw_byte_size); 258 } 259 } else { // Primitive-only case... 260 raw_field_copy(src, dst, raw_byte_size); 261 } 262 } 263 264 // Value type arguments are not passed by reference, instead each 265 // field of the value type is passed as an argument. This helper 266 // function collects the fields of the value types (including embedded 267 // value type's fields) in a list. Included with the field's type is 268 // the offset of each field in the value type: i2c and c2i adapters 269 // need that to load or store fields. Finally, the list of fields is 270 // sorted in order of increasing offsets: the adapters and the 271 // compiled code need to agree upon the order of fields. 272 // 273 // The list of basic types that is returned starts with a T_VALUETYPE 274 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID pairs are used as 275 // delimiters. Every entry between the two is a field of the value 276 // type. If there's an embedded value type in the list, it also starts 277 // with a T_VALUETYPE and ends with a T_VOID. This is so we can 278 // generate a unique fingerprint for the method's adapters and we can 279 // generate the list of basic types from the interpreter point of view 280 // (value types passed as reference: iterate on the list until a 281 // T_VALUETYPE, drop everything until and including the closing 282 // T_VOID) or the compiler point of view (each field of the value 283 // types is an argument: drop all T_VALUETYPE/T_VOID from the list). 284 int ValueKlass::collect_fields(GrowableArray<SigEntry>* sig, int base_off) const { 285 int count = 0; 286 SigEntry::add_entry(sig, T_VALUETYPE, base_off); 287 for (JavaFieldStream fs(this); !fs.done(); fs.next()) { 288 if (fs.access_flags().is_static()) continue; 289 int offset = base_off + fs.offset() - (base_off > 0 ? first_field_offset() : 0); 290 if (fs.is_flattened()) { 291 // Resolve klass of flattened value type field and recursively collect fields 292 Klass* vk = get_value_field_klass(fs.index()); 293 count += ValueKlass::cast(vk)->collect_fields(sig, offset); 294 } else { 295 BasicType bt = FieldType::basic_type(fs.signature()); 296 SigEntry::add_entry(sig, bt, offset); 297 count += type2size[bt]; 298 } 299 } 300 int offset = base_off + size_helper()*HeapWordSize - (base_off > 0 ? first_field_offset() : 0); 301 SigEntry::add_entry(sig, T_VOID, offset); 302 if (base_off == 0) { 303 sig->sort(SigEntry::compare); 304 } 305 assert(sig->at(0)._bt == T_VALUETYPE && sig->at(sig->length()-1)._bt == T_VOID, "broken structure"); 306 return count; 307 } 308 309 void ValueKlass::initialize_calling_convention(TRAPS) { 310 // Because the pack and unpack handler addresses need to be loadable from generated code, 311 // they are stored at a fixed offset in the klass metadata. Since value type klasses do 312 // not have a vtable, the vtable offset is used to store these addresses. 313 if (ValueTypeReturnedAsFields || ValueTypePassFieldsAsArgs) { 314 ResourceMark rm; 315 GrowableArray<SigEntry> sig_vk; 316 int nb_fields = collect_fields(&sig_vk); 317 Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK); 318 *((Array<SigEntry>**)adr_extended_sig()) = extended_sig; 319 for (int i = 0; i < sig_vk.length(); i++) { 320 extended_sig->at_put(i, sig_vk.at(i)); 321 } 322 323 if (ValueTypeReturnedAsFields) { 324 nb_fields++; 325 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields); 326 sig_bt[0] = T_METADATA; 327 SigEntry::fill_sig_bt(&sig_vk, sig_bt+1); 328 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields); 329 int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields); 330 331 if (total > 0) { 332 Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK); 333 *((Array<VMRegPair>**)adr_return_regs()) = return_regs; 334 for (int i = 0; i < nb_fields; i++) { 335 return_regs->at_put(i, regs[i]); 336 } 337 338 BufferedValueTypeBlob* buffered_blob = SharedRuntime::generate_buffered_value_type_adapter(this); 339 *((address*)adr_pack_handler()) = buffered_blob->pack_fields(); 340 *((address*)adr_unpack_handler()) = buffered_blob->unpack_fields(); 341 assert(CodeCache::find_blob(pack_handler()) == buffered_blob, "lost track of blob"); 342 } 343 } 344 } 345 } 346 347 void ValueKlass::deallocate_contents(ClassLoaderData* loader_data) { 348 if (extended_sig() != NULL) { 349 MetadataFactory::free_array<SigEntry>(loader_data, extended_sig()); 350 } 351 if (return_regs() != NULL) { 352 MetadataFactory::free_array<VMRegPair>(loader_data, return_regs()); 366 BufferBlob::free((BufferBlob*)buffered_blob); 367 *((address*)adr_pack_handler()) = NULL; 368 *((address*)adr_unpack_handler()) = NULL; 369 } 370 } 371 372 // Can this value type be returned as multiple values? 373 bool ValueKlass::can_be_returned_as_fields() const { 374 return return_regs() != NULL; 375 } 376 377 // Create handles for all oop fields returned in registers that are going to be live across a safepoint 378 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const { 379 Thread* thread = Thread::current(); 380 const Array<SigEntry>* sig_vk = extended_sig(); 381 const Array<VMRegPair>* regs = return_regs(); 382 int j = 1; 383 384 for (int i = 0; i < sig_vk->length(); i++) { 385 BasicType bt = sig_vk->at(i)._bt; 386 if (bt == T_OBJECT || bt == T_ARRAY) { 387 VMRegPair pair = regs->at(j); 388 address loc = reg_map.location(pair.first()); 389 oop v = *(oop*)loc; 390 assert(v == NULL || oopDesc::is_oop(v), "not an oop?"); 391 assert(Universe::heap()->is_in_or_null(v), "must be heap pointer"); 392 handles.push(Handle(thread, v)); 393 } 394 if (bt == T_VALUETYPE) { 395 continue; 396 } 397 if (bt == T_VOID && 398 sig_vk->at(i-1)._bt != T_LONG && 399 sig_vk->at(i-1)._bt != T_DOUBLE) { 400 continue; 401 } 402 j++; 403 } 404 assert(j == regs->length(), "missed a field?"); 405 } 406 407 // Update oop fields in registers from handles after a safepoint 408 void ValueKlass::restore_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const { 409 assert(ValueTypeReturnedAsFields, "inconsistent"); 410 const Array<SigEntry>* sig_vk = extended_sig(); 411 const Array<VMRegPair>* regs = return_regs(); 412 assert(regs != NULL, "inconsistent"); 413 414 int j = 1; 415 for (int i = 0, k = 0; i < sig_vk->length(); i++) { 416 BasicType bt = sig_vk->at(i)._bt; 417 if (bt == T_OBJECT || bt == T_ARRAY) { 418 VMRegPair pair = regs->at(j); 419 address loc = reg_map.location(pair.first()); 420 *(oop*)loc = handles.at(k++)(); 421 } 422 if (bt == T_VALUETYPE) { 423 continue; 424 } 425 if (bt == T_VOID && 426 sig_vk->at(i-1)._bt != T_LONG && 427 sig_vk->at(i-1)._bt != T_DOUBLE) { 428 continue; 429 } 430 j++; 431 } 432 assert(j == regs->length(), "missed a field?"); 433 } 434 435 // Fields are in registers. Create an instance of the value type and 436 // initialize it with the values of the fields. 437 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) { 438 oop new_vt = allocate_instance(CHECK_NULL); 439 const Array<SigEntry>* sig_vk = extended_sig(); 440 const Array<VMRegPair>* regs = return_regs(); 441 442 int j = 1; 443 int k = 0; 444 for (int i = 0; i < sig_vk->length(); i++) { 445 BasicType bt = sig_vk->at(i)._bt; 446 if (bt == T_VALUETYPE) { 447 continue; 448 } 449 if (bt == T_VOID) { 450 if (sig_vk->at(i-1)._bt == T_LONG || 451 sig_vk->at(i-1)._bt == T_DOUBLE) { 452 j++; 453 } 454 continue; 455 } 456 int off = sig_vk->at(i)._offset; 457 assert(off > 0, "offset in object should be positive"); 458 VMRegPair pair = regs->at(j); 459 address loc = reg_map.location(pair.first()); 460 switch(bt) { 461 case T_BOOLEAN: { 462 new_vt->bool_field_put(off, *(jboolean*)loc); 463 break; 464 } 465 case T_CHAR: { 466 new_vt->char_field_put(off, *(jchar*)loc); 467 break; 468 } 469 case T_BYTE: { 470 new_vt->byte_field_put(off, *(jbyte*)loc); 471 break; 472 } 473 case T_SHORT: { 474 new_vt->short_field_put(off, *(jshort*)loc); 475 break; 476 } 477 case T_INT: { 478 new_vt->int_field_put(off, *(jint*)loc); 479 break; 480 } 481 case T_LONG: { 482 #ifdef _LP64 483 new_vt->double_field_put(off, *(jdouble*)loc); 484 #else 485 Unimplemented(); 486 #endif 487 break; 488 } 489 case T_OBJECT: 490 case T_ARRAY: { 491 Handle handle = handles.at(k++); 492 new_vt->obj_field_put(off, handle()); 493 break; 494 } 495 case T_FLOAT: { 496 new_vt->float_field_put(off, *(jfloat*)loc); 497 break; 498 } 499 case T_DOUBLE: { 500 new_vt->double_field_put(off, *(jdouble*)loc); 501 break; 502 } 503 default: 504 ShouldNotReachHere(); 505 } 506 *(intptr_t*)loc = 0xDEAD; 507 j++; 508 } 509 assert(j == regs->length(), "missed a field?"); 510 assert(k == handles.length(), "missed an oop?"); 511 return new_vt; 512 } 513 514 // Check the return register for a ValueKlass oop 515 ValueKlass* ValueKlass::returned_value_klass(const RegisterMap& map) { 516 BasicType bt = T_METADATA; 517 VMRegPair pair; 518 int nb = SharedRuntime::java_return_convention(&bt, &pair, 1); 519 assert(nb == 1, "broken"); 520 |