350 const GrowableArray<SigEntry>& sig_vk = collect_fields();
351 int nb_fields = SigEntry::count_fields(sig_vk)+1;
352 Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR);
353 *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
354 for (int i = 0; i < sig_vk.length(); i++ ) {
355 extended_sig->at_put(i, sig_vk.at(i));
356 }
357
358 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
359 sig_bt[0] = T_METADATA;
360 SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true);
361 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
362 int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
363
364 if (total > 0) {
365 Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK_AND_CLEAR);
366 *((Array<VMRegPair>**)adr_return_regs()) = return_regs;
367 for (int i = 0; i < nb_fields; i++ ) {
368 return_regs->at_put(i, regs[i]);
369 }
370 }
371 }
372
373 // Create handles for all oop fields returned in registers that are
374 // going to be live across a safepoint.
375 bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
376 if (ValueTypeReturnedAsFields) {
377 if (return_regs() != NULL) {
378 save_oop_fields(reg_map, handles);
379 return true;
380 }
381 }
382 return false;
383 }
384
385 // Same as above but with pre-computed return convention
386 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
387 Thread* thread = Thread::current();
388 const Array<SigEntry>* sig_vk = extended_sig();
389 const Array<VMRegPair>* regs = return_regs();
427 int off = sig_vk->at(i)._offset;
428 VMRegPair pair = regs->at(j);
429 address loc = reg_map.location(pair.first());
430 *(oop*)loc = handles.at(k++)();
431 }
432 if (bt == T_VALUETYPE) {
433 continue;
434 }
435 if (bt == T_VOID &&
436 sig_vk->at(i-1)._bt != T_LONG &&
437 sig_vk->at(i-1)._bt != T_DOUBLE) {
438 continue;
439 }
440 j++;
441 }
442 assert(j == regs->length(), "missed a field?");
443 }
444
445 // Fields are in registers. Create an instance of the value type and
446 // initialize it with the values of the fields.
447 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) {
448 oop new_vt = allocate_instance(CHECK_NULL);
449
450 const Array<SigEntry>* sig_vk = extended_sig();
451 const Array<VMRegPair>* regs = return_regs();
452
453 int j = 1;
454 int k = 0;
455 for (int i = 0; i < sig_vk->length(); i++) {
456 BasicType bt = sig_vk->at(i)._bt;
457 if (bt == T_VALUETYPE) {
458 continue;
459 }
460 if (bt == T_VOID) {
461 if (sig_vk->at(i-1)._bt == T_LONG ||
462 sig_vk->at(i-1)._bt == T_DOUBLE) {
463 j++;
464 }
465 continue;
466 }
467 int off = sig_vk->at(i)._offset;
468 VMRegPair pair = regs->at(j);
511 oopDesc::store_heap_oop(p, v);
512 } else {
513 narrowOop* p = (narrowOop*)((address)new_vt + off);
514 oopDesc::encode_store_heap_oop(p, v);
515 }
516 break;
517 }
518 case T_FLOAT: {
519 jfloat v = *(jfloat*)loc;
520 *(jfloat*)((address)new_vt + off) = v;
521 break;
522 }
523 case T_DOUBLE: {
524 jdouble v = *(jdouble*)loc;
525 *(jdouble*)((address)new_vt + off) = v;
526 break;
527 }
528 default:
529 ShouldNotReachHere();
530 }
531 j++;
532 }
533 assert(j == regs->length(), "missed a field?");
534 assert(k == handles.length(), "missed an oop?");
535 return new_vt;
536 }
537
538 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
539 BasicType bt = T_METADATA;
540 VMRegPair pair;
541 int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
542 assert(nb == 1, "broken");
543
544 address loc = map.location(pair.first());
545 intptr_t ptr = *(intptr_t*)loc;
546 if (is_set_nth_bit(ptr, 0)) {
547 clear_nth_bit(ptr, 0);
548 assert(Metaspace::contains((void*)ptr), "should be klass");
549 return (ValueKlass*)ptr;
550 }
|
350 const GrowableArray<SigEntry>& sig_vk = collect_fields();
351 int nb_fields = SigEntry::count_fields(sig_vk)+1;
352 Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR);
353 *((Array<SigEntry>**)adr_extended_sig()) = extended_sig;
354 for (int i = 0; i < sig_vk.length(); i++ ) {
355 extended_sig->at_put(i, sig_vk.at(i));
356 }
357
358 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields);
359 sig_bt[0] = T_METADATA;
360 SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true);
361 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields);
362 int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields);
363
364 if (total > 0) {
365 Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK_AND_CLEAR);
366 *((Array<VMRegPair>**)adr_return_regs()) = return_regs;
367 for (int i = 0; i < nb_fields; i++ ) {
368 return_regs->at_put(i, regs[i]);
369 }
370
371 BufferedValueTypeBlob* buffered_blob = SharedRuntime::generate_buffered_value_type_adapter(this);
372 *((address*)adr_pack_handler()) = buffered_blob->pack_fields();
373 *((address*)adr_unpack_handler()) = buffered_blob->unpack_fields();
374 assert(CodeCache::find_blob(pack_handler()) == buffered_blob, "lost track of blob");
375 }
376 assert(vtable_length() == 0, "a value klass with a vtable?");
377 }
378
379 void ValueKlass::deallocate_contents(ClassLoaderData* loader_data) {
380 if (extended_sig() != NULL) {
381 MetadataFactory::free_array<SigEntry>(loader_data, extended_sig());
382 }
383 if (return_regs() != NULL) {
384 MetadataFactory::free_array<VMRegPair>(loader_data, return_regs());
385 }
386 if (pack_handler() != NULL) {
387 CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
388 assert(buffered_blob->is_buffered_value_type_blob(), "bad blob type");
389 BufferBlob::free((BufferBlob*)buffered_blob);
390 }
391 InstanceKlass::deallocate_contents(loader_data);
392 }
393
394 void ValueKlass::cleanup(ValueKlass* ik) {
395 ik->cleanup_blobs();
396 }
397
398
399 void ValueKlass::cleanup_blobs() {
400 if (pack_handler() != NULL) {
401 CodeBlob* buffered_blob = CodeCache::find_blob(pack_handler());
402 assert(buffered_blob->is_buffered_value_type_blob(), "bad blob type");
403 BufferBlob::free((BufferBlob*)buffered_blob);
404 }
405 }
406
407 // Create handles for all oop fields returned in registers that are
408 // going to be live across a safepoint.
409 bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
410 if (ValueTypeReturnedAsFields) {
411 if (return_regs() != NULL) {
412 save_oop_fields(reg_map, handles);
413 return true;
414 }
415 }
416 return false;
417 }
418
419 // Same as above but with pre-computed return convention
420 void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
421 Thread* thread = Thread::current();
422 const Array<SigEntry>* sig_vk = extended_sig();
423 const Array<VMRegPair>* regs = return_regs();
461 int off = sig_vk->at(i)._offset;
462 VMRegPair pair = regs->at(j);
463 address loc = reg_map.location(pair.first());
464 *(oop*)loc = handles.at(k++)();
465 }
466 if (bt == T_VALUETYPE) {
467 continue;
468 }
469 if (bt == T_VOID &&
470 sig_vk->at(i-1)._bt != T_LONG &&
471 sig_vk->at(i-1)._bt != T_DOUBLE) {
472 continue;
473 }
474 j++;
475 }
476 assert(j == regs->length(), "missed a field?");
477 }
478
479 // Fields are in registers. Create an instance of the value type and
480 // initialize it with the values of the fields.
481 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, bool buffered, TRAPS) {
482 bool ignored = false;
483 oop new_vt = NULL;
484 if (buffered) {
485 new_vt = allocate_buffered_or_heap_instance(&ignored, CHECK_NULL);
486 } else {
487 new_vt = allocate_instance(CHECK_NULL);
488 }
489
490 const Array<SigEntry>* sig_vk = extended_sig();
491 const Array<VMRegPair>* regs = return_regs();
492
493 int j = 1;
494 int k = 0;
495 for (int i = 0; i < sig_vk->length(); i++) {
496 BasicType bt = sig_vk->at(i)._bt;
497 if (bt == T_VALUETYPE) {
498 continue;
499 }
500 if (bt == T_VOID) {
501 if (sig_vk->at(i-1)._bt == T_LONG ||
502 sig_vk->at(i-1)._bt == T_DOUBLE) {
503 j++;
504 }
505 continue;
506 }
507 int off = sig_vk->at(i)._offset;
508 VMRegPair pair = regs->at(j);
551 oopDesc::store_heap_oop(p, v);
552 } else {
553 narrowOop* p = (narrowOop*)((address)new_vt + off);
554 oopDesc::encode_store_heap_oop(p, v);
555 }
556 break;
557 }
558 case T_FLOAT: {
559 jfloat v = *(jfloat*)loc;
560 *(jfloat*)((address)new_vt + off) = v;
561 break;
562 }
563 case T_DOUBLE: {
564 jdouble v = *(jdouble*)loc;
565 *(jdouble*)((address)new_vt + off) = v;
566 break;
567 }
568 default:
569 ShouldNotReachHere();
570 }
571 *(intptr_t*)loc = 0xDEAD;
572 j++;
573 }
574 assert(j == regs->length(), "missed a field?");
575 assert(k == handles.length(), "missed an oop?");
576 return new_vt;
577 }
578
579 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
580 BasicType bt = T_METADATA;
581 VMRegPair pair;
582 int nb = SharedRuntime::java_return_convention(&bt, &pair, 1);
583 assert(nb == 1, "broken");
584
585 address loc = map.location(pair.first());
586 intptr_t ptr = *(intptr_t*)loc;
587 if (is_set_nth_bit(ptr, 0)) {
588 clear_nth_bit(ptr, 0);
589 assert(Metaspace::contains((void*)ptr), "should be klass");
590 return (ValueKlass*)ptr;
591 }
|