src/cpu/sparc/vm/c1_Runtime1_sparc.cpp

Print this page
rev 146 : [mq]: mixa.layout.patch

*** 341,350 **** --- 341,438 ---- __ delayed()->restore(); return oop_maps; } + inline Address layout_helper_addr(Register klass) { + return Address(klass, 0, (klassOopDesc::header_size() * HeapWordSize + + Klass::layout_helper_offset_in_bytes())); + } + + static void compute_instance_size(Register obj_size, Register klass, + Label& have_obj_size, Label& size_is_variable, + Register t1, + StubAssembler* sasm, bool hot_part) { + assert_different_registers(obj_size, klass, t1); + + if (hot_part) { + __ lduw(layout_helper_addr(klass), obj_size); + __ andcc(obj_size, ~LayoutHelper::_size_low_mask, obj_size); + if (mixed_arrays) { + __ jcc(Assembler::negative, size_is_variable); + __ bind(have_obj_size); + } + } else { + if (MixedArrays) { + // Side path for fixing up the initial size of a variable object. + // Must round from int to object alignment, and clear high bits. + __ bind(size_is_variable); + __ add(obj_size, LayoutHelper::_header_size_odd_mask, obj_size); + __ set((LayoutHelper::_header_size_mask & ~MinObjAlignmentInBytesMask), t1); + __ and3(obj_size, t1, obj_size); + __ jmp(have_obj_size); + } + } + } + + static void compute_array_size(Register arr_size, Register klass, Register length, + Label& have_scaled_length, Label& need_multiply, + Register t1, Register t2, + StubAssembler* sasm, bool hot_part) { + assert_different_registers(arr_size, klass, length, t1, t2); + + if (hot_part) { + // get the allocation size: round_up(hdr + length << (lh>>16 & 0x1F)) + __ lduw(layout_helper_addr(klass), t1); + // int scale = (lh >> LayoutHelper::_element_size_shift); + __ mov(t1, t2); // spill layout helper + __ srl(t1, LayoutHelper::_element_size_shift); // lh>>16, no mask needed + // size_t arr_size = (array_length << scale); + __ sllx(length, t1, arr_size); + if (MixedArrays) { + // int sizem_ip = (scale & (LayoutHelper::_element_sizem_mask_ip)); + __ andcc(t1, LayoutHelper::_element_sizem_mask_ip, t1); + __ jcc(Assembler::notZero, need_multiply); + __ bind(have_scaled_length); + } + // arr_size += Klass::layout_helper_header_size_in_bytes(lh); + assert(LayoutHelper::_header_size_shift == 0, ""); + // sll(t2, LayoutHelper::_header_size_shift, t2); + __ set((LayoutHelper::_header_size_mask & ~MinObjAlignmentInBytesMask), t1); + __ and(t2, t1, t2); // t2 = lh & _header_size_mask + __ add(arr_size, t2, arr_size); + __ add(arr_size, MinObjAlignmentInBytesMask, arr_size); // align up + __ and3(arr_size, ~MinObjAlignmentInBytesMask, arr_size); + } else { + if (MixedArrays) { + // Side path for scaling by a non-power-of-two array element size. + __ bind(need_multiply); + // int sizem = (sizem_ip >> LayoutHelper::_element_scale_bits); + __ srl(t1, LayoutHelper::_element_scale_bits, t1); + // arr_size = (array_length * (1+sizem)) << scale; + __ add(t1, 1, t1); + // previous value of arr_size is junk; start from length again + assert(wordSize == jintSize, "else use mulx"); + __ smul(length, t1, arr_size); + __ srl(t2, LayoutHelper::_element_size_shift, t1); // lh>>16, mask needed + __ and3(t1, LayoutHelper::_element_scale_mask, t1); + __ sllx(arr_size, t1, arr_size); + __ jmp(have_scaled_length); + } + } + } + + static void initialize_array_body(Register obj, Register arr_size, Register t1, Register t2, StubAssembler* sasm) { + assert_different_registers(obj, arr_size, t1, t2); + + int min_header_size = arrayOopDesc::header_size(T_BYTE); + __ sub(arr_size, min_header_size, arr_size); // body length + __ add(obj, min_header_size, t1); // body start + __ initialize_body(t1, arr_size, 0, t2); + } + + OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { OopMapSet* oop_maps = NULL; // for better readability const bool must_gc_arguments = true;
*** 411,429 **** __ delayed()->nop(); } #ifdef ASSERT // assert object can be fast path allocated { ! Label ok, not_ok; __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size); ! __ cmp(G1_obj_size, 0); // make sure it's an instance (LH > 0) ! __ br(Assembler::lessEqual, false, Assembler::pn, not_ok); ! __ delayed()->nop(); ! __ btst(Klass::_lh_instance_slow_path_bit, G1_obj_size); __ br(Assembler::zero, false, Assembler::pn, ok); __ delayed()->nop(); - __ bind(not_ok); __ stop("assert(can be fast path allocated)"); __ should_not_reach_here(); __ bind(ok); } #endif // ASSERT --- 499,513 ---- __ delayed()->nop(); } #ifdef ASSERT // assert object can be fast path allocated { ! Label ok; __ ld(G5_klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc), G1_obj_size); ! __ btst(LayoutHelper::_slow_path_low_bit, G1_obj_size); __ br(Assembler::zero, false, Assembler::pn, ok); __ delayed()->nop(); __ stop("assert(can be fast path allocated)"); __ should_not_reach_here(); __ bind(ok); } #endif // ASSERT
*** 433,460 **** __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass __ bind(retry_tlab); // get the instance size ! __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size); __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path); __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2); __ verify_oop(O0_obj); __ mov(O0, I0); __ ret(); __ delayed()->restore(); __ bind(try_eden); // get the instance size ! __ ld(G5_klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(), G1_obj_size); __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path); __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2); __ verify_oop(O0_obj); __ mov(O0, I0); __ ret(); __ delayed()->restore(); __ bind(slow_path); // pop this frame so generate_stub_call can push it's own __ restore(); } --- 517,560 ---- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G5_klass __ bind(retry_tlab); // get the instance size ! Label have_obj_size, size_is_variable; ! compute_instance_size(G1_obj_size, G5_klass, ! have_obj_size, size_is_variable, ! G3_t1, sasm, true); __ tlab_allocate(O0_obj, G1_obj_size, 0, G3_t1, slow_path); __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2); __ verify_oop(O0_obj); __ mov(O0, I0); __ ret(); __ delayed()->restore(); + // generate side path, if any + compute_instance_size(G1_obj_size, G5_klass, + have_obj_size, size_is_variable, + G3_t1, sasm, false); + __ bind(try_eden); // get the instance size ! Label have_obj_size_2, size_is_variable_2; ! compute_instance_size(G1_obj_size, G5_klass, ! have_obj_size_2, size_is_variable_2, ! G3_t1, sasm, true); __ eden_allocate(O0_obj, G1_obj_size, 0, G3_t1, G4_t2, slow_path); __ initialize_object(O0_obj, G5_klass, G1_obj_size, 0, G3_t1, G4_t2); __ verify_oop(O0_obj); __ mov(O0, I0); __ ret(); __ delayed()->restore(); + // generate side path, if any + compute_instance_size(G1_obj_size, G5_klass, + have_obj_size_2, size_is_variable_2, + G3_t1, sasm, false); + __ bind(slow_path); // pop this frame so generate_stub_call can push it's own __ restore(); }
*** 477,494 **** { Register G5_klass = G5; // Incoming Register G4_length = G4; // Incoming Register O0_obj = O0; // Outgoing - Address klass_lh(G5_klass, 0, ((klassOopDesc::header_size() * HeapWordSize) - + Klass::layout_helper_offset_in_bytes())); - assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); - assert(Klass::_lh_header_size_mask == 0xFF, "bytewise"); - // Use this offset to pick out an individual byte of the layout_helper: - const int klass_lh_header_size_offset = ((BytesPerInt - 1) // 3 - 2 selects byte {0,1,0,0} - - Klass::_lh_header_size_shift / BitsPerByte); - if (id == new_type_array_id) { __ set_info("new_type_array", dont_gc_arguments); } else { __ set_info("new_object_array", dont_gc_arguments); } --- 577,586 ----
*** 496,510 **** #ifdef ASSERT // assert object type is really an array of the proper kind { Label ok; Register G3_t1 = G3; ! __ ld(klass_lh, G3_t1); ! __ sra(G3_t1, Klass::_lh_array_tag_shift, G3_t1); ! int tag = ((id == new_type_array_id) ! ? Klass::_lh_array_tag_type_value ! : Klass::_lh_array_tag_obj_value); __ cmp(G3_t1, tag); __ brx(Assembler::equal, false, Assembler::pt, ok); __ delayed()->nop(); __ stop("assert(is an array klass)"); __ should_not_reach_here(); --- 588,606 ---- #ifdef ASSERT // assert object type is really an array of the proper kind { Label ok; Register G3_t1 = G3; ! __ lduw(layout_helper_addr(G5_klass), G3_t1); ! int flag_shift = LayoutHelper::_flags_shift; ! flag_shift += LayoutHelper::_flags_low_bits; // shift out BasicType also ! int tag = LayoutHelper::for_array((id == new_type_array_id) ? T_BYTE : T_OBJECT).as_int(); ! tag >>= flag_shift; ! __ sra(G3_t1, flag_shift, G3_t1); ! assert(id == new_object_array_id || ! tag == (LayoutHelper::for_array(T_DOUBLE).as_int() >> flag_shift), ! "same tag for all type arrays"); __ cmp(G3_t1, tag); __ brx(Assembler::equal, false, Assembler::pt, ok); __ delayed()->nop(); __ stop("assert(is an array klass)"); __ should_not_reach_here();
*** 531,580 **** __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass __ bind(retry_tlab); // get the allocation size: (length << (layout_helper & 0x1F)) + header_size ! __ ld(klass_lh, G3_t1); ! __ sll(G4_length, G3_t1, G1_arr_size); ! __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1); ! __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1); ! __ add(G1_arr_size, G3_t1, G1_arr_size); ! __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); // align up ! __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size); ! __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2); ! __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset); ! __ sub(G1_arr_size, G3_t1, O1_t2); // body length ! __ add(O0_obj, G3_t1, G3_t1); // body start ! __ initialize_body(G3_t1, O1_t2); __ verify_oop(O0_obj); __ retl(); __ delayed()->nop(); __ bind(try_eden); // get the allocation size: (length << (layout_helper & 0x1F)) + header_size ! __ ld(klass_lh, G3_t1); ! __ sll(G4_length, G3_t1, G1_arr_size); ! __ srl(G3_t1, Klass::_lh_header_size_shift, G3_t1); ! __ and3(G3_t1, Klass::_lh_header_size_mask, G3_t1); ! __ add(G1_arr_size, G3_t1, G1_arr_size); ! __ add(G1_arr_size, MinObjAlignmentInBytesMask, G1_arr_size); ! __ and3(G1_arr_size, ~MinObjAlignmentInBytesMask, G1_arr_size); ! __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2); ! __ ldub(klass_lh, G3_t1, klass_lh_header_size_offset); ! __ sub(G1_arr_size, G3_t1, O1_t2); // body length ! __ add(O0_obj, G3_t1, G3_t1); // body start ! __ initialize_body(G3_t1, O1_t2); __ verify_oop(O0_obj); __ retl(); __ delayed()->nop(); __ bind(slow_path); } if (id == new_type_array_id) { oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length); --- 627,672 ---- __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves G4_length and G5_klass __ bind(retry_tlab); // get the allocation size: (length << (layout_helper & 0x1F)) + header_size ! Label have_scaled_length, need_multiply; ! compute_array_size(G1_arr_size, G5_klass, G4_length, ! have_scaled_length, need_multiply, ! G3_t1, O1_t2, sasm, true); __ tlab_allocate(O0_obj, G1_arr_size, 0, G3_t1, slow_path); // preserves G1_arr_size __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2); ! initialize_array_body(O0_obj, G1_arr_size, G3_t1, O1_t2, sasm); __ verify_oop(O0_obj); __ retl(); __ delayed()->nop(); + // generate side path, if any + compute_array_size(G1_arr_size, G5_klass, G4_length, + have_scaled_length, need_multiply, + G3_t1, O1_t2, sasm, false); + __ bind(try_eden); + Label have_scaled_length_2, need_multiply_2; // get the allocation size: (length << (layout_helper & 0x1F)) + header_size ! compute_array_size(G1_arr_size, G5_klass, G4_length, ! have_scaled_length_2, need_multiply_2, ! G3_t1, O1_t2, sasm, true); __ eden_allocate(O0_obj, G1_arr_size, 0, G3_t1, O1_t2, slow_path); // preserves G1_arr_size __ initialize_header(O0_obj, G5_klass, G4_length, G3_t1, O1_t2); ! initialize_array_body(O0_obj, G1_arr_size, G3_t1, O1_t2, sasm); __ verify_oop(O0_obj); __ retl(); __ delayed()->nop(); + // generate side path, if any + compute_array_size(G1_arr_size, G5_klass, G4_length, + have_scaled_length_2, need_multiply_2, + G3_t1, O1_t2, sasm, false); + __ bind(slow_path); } if (id == new_type_array_id) { oop_maps = generate_stub_call(sasm, I0, CAST_FROM_FN_PTR(address, new_type_array), G5_klass, G4_length);