88 guarantee(0, "Unknown type %d", type); 89 } 90 assert(last_tsz != 0, "Invariant"); 91 last_offset = fs.offset(); 92 } 93 } 94 // Assumes VT with no fields are meaningless and illegal 95 last_offset += last_tsz; 96 assert(last_offset > first_offset && last_tsz, "Invariant"); 97 return 1 << upper_log2(last_offset - first_offset); 98 } 99 100 instanceOop ValueKlass::allocate_instance(TRAPS) { 101 int size = size_helper(); // Query before forming handle. 102 103 instanceOop oop = (instanceOop)Universe::heap()->obj_allocate(this, size, CHECK_NULL); 104 assert(oop->mark()->is_always_locked(), "Unlocked value type"); 105 return oop; 106 } 107 108 instanceOop ValueKlass::allocate_buffered_or_heap_instance(bool* in_heap, TRAPS) { 109 assert(THREAD->is_Java_thread(), "Only Java threads can call this method"); 110 111 instanceOop value = NULL; 112 if (is_bufferable()) { 113 value = (instanceOop)VTBuffer::allocate_value(this, CHECK_NULL); 114 *in_heap = false; 115 } 116 if (value == NULL) { 117 log_info(valuetypes)("Value buffering failed, allocating in the Java heap"); 118 value = allocate_instance(CHECK_NULL); 119 *in_heap = true; 120 } 121 return value; 122 } 123 124 bool ValueKlass::is_atomic() { 125 return (nonstatic_field_size() * heapOopSize) <= longSize; 126 } 127 128 int ValueKlass::nonstatic_oop_count() { 129 int oops = 0; 130 int map_count = nonstatic_oop_map_count(); 131 OopMapBlock* block = start_of_nonstatic_oop_maps(); 132 OopMapBlock* end = block + map_count; 133 while (block != end) { 134 oops += block->count(); 135 block++; 136 } 137 return oops; 138 } 139 140 // Arrays of... 141 142 bool ValueKlass::flatten_array() { 143 if (!ValueArrayFlatten) { 454 int off = sig_vk->at(i)._offset; 455 VMRegPair pair = regs->at(j); 456 address loc = reg_map.location(pair.first()); 457 *(oop*)loc = handles.at(k++)(); 458 } 459 if (bt == T_VALUETYPE) { 460 continue; 461 } 462 if (bt == T_VOID && 463 sig_vk->at(i-1)._bt != T_LONG && 464 sig_vk->at(i-1)._bt != T_DOUBLE) { 465 continue; 466 } 467 j++; 468 } 469 assert(j == regs->length(), "missed a field?"); 470 } 471 472 // Fields are in registers. Create an instance of the value type and 473 // initialize it with the values of the fields. 474 oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, bool buffered, TRAPS) { 475 bool ignored = false; 476 oop new_vt = NULL; 477 if (buffered) { 478 new_vt = allocate_buffered_or_heap_instance(&ignored, CHECK_NULL); 479 } else { 480 new_vt = allocate_instance(CHECK_NULL); 481 } 482 483 const Array<SigEntry>* sig_vk = extended_sig(); 484 const Array<VMRegPair>* regs = return_regs(); 485 486 int j = 1; 487 int k = 0; 488 for (int i = 0; i < sig_vk->length(); i++) { 489 BasicType bt = sig_vk->at(i)._bt; 490 if (bt == T_VALUETYPE) { 491 continue; 492 } 493 if (bt == T_VOID) { 494 if (sig_vk->at(i-1)._bt == T_LONG || 495 sig_vk->at(i-1)._bt == T_DOUBLE) { 496 j++; 497 } 498 continue; 499 } 500 int off = sig_vk->at(i)._offset; 501 VMRegPair pair = regs->at(j); 502 address loc = reg_map.location(pair.first()); | 88 guarantee(0, "Unknown type %d", type); 89 } 90 assert(last_tsz != 0, "Invariant"); 91 last_offset = fs.offset(); 92 } 93 } 94 // Assumes VT with no fields are meaningless and illegal 95 last_offset += last_tsz; 96 assert(last_offset > first_offset && last_tsz, "Invariant"); 97 return 1 << upper_log2(last_offset - first_offset); 98 } 99 100 instanceOop ValueKlass::allocate_instance(TRAPS) { 101 int size = size_helper(); // Query before forming handle. 102 103 instanceOop oop = (instanceOop)Universe::heap()->obj_allocate(this, size, CHECK_NULL); 104 assert(oop->mark()->is_always_locked(), "Unlocked value type"); 105 return oop; 106 } 107 108 bool ValueKlass::is_atomic() { 109 return (nonstatic_field_size() * heapOopSize) <= longSize; 110 } 111 112 int ValueKlass::nonstatic_oop_count() { 113 int oops = 0; 114 int map_count = nonstatic_oop_map_count(); 115 OopMapBlock* block = start_of_nonstatic_oop_maps(); 116 OopMapBlock* end = block + map_count; 117 while (block != end) { 118 oops += block->count(); 119 block++; 120 } 121 return oops; 122 } 123 124 // Arrays of... 125 126 bool ValueKlass::flatten_array() { 127 if (!ValueArrayFlatten) { 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()); |