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