src/cpu/x86/vm/c1_Runtime1_x86.cpp

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

*** 784,793 **** --- 784,884 ---- return oop_maps; } + inline Address layout_helper_addr(Register klass) { + return Address(klass, (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, + StubAssembler* sasm, bool hot_part) { + assert_different_registers(obj_size, klass); + + if (hot_part) { + __ movl(obj_size, layout_helper_addr(klass)); + __ andl(obj_size, ~LayoutHelper::_size_low_mask); + if (MixedArrays) { + __ 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); + __ addl(obj_size, LayoutHelper::_header_size_odd_mask); + __ andl(obj_size, (LayoutHelper::_header_size_mask & ~MinObjAlignmentInBytesMask)); + __ 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)) + __ movl(t1, layout_helper_addr(klass)); + __ movl(arr_size, length); + // int scale = (lh >> LayoutHelper::_element_size_shift); + __ movl(t1, t2); // spill layout helper + __ shrl(t1, LayoutHelper::_element_size_shift); // lh>>16, no mask needed + // size_t arr_size = (array_length << scale); + assert(t1 == rcx, "fixed register usage"); + __ shll(arr_size /* by t1=rcx, mod 32 */); + if (MixedArrays) { + // int sizem_ip = (scale & (LayoutHelper::_element_sizem_mask_ip)); + __ andl(t1, LayoutHelper::_element_sizem_mask_ip); + __ 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, ""); + // shrl(t2, LayoutHelper::_header_size_shift); + __ andl(t2, LayoutHelper::_header_size_mask); + __ addl(arr_size, t2); + __ addl(arr_size, MinObjAlignmentInBytesMask); // align up + __ andl(arr_size, ~MinObjAlignmentInBytesMask); + } else { + if (MixedArrays) { + // Side path for scaling by a non-power-of-two array element size. + __ bind(need_multiply); + __ movl(arr_size, length); // reload; previous value was trash + // int sizem = (sizem_ip >> LayoutHelper::_element_scale_bits); + __ shrl(t1, LayoutHelper::_element_scale_bits); + // arr_size = (array_length * (1+sizem)) << scale; + __ addl(t1, 1); + assert(wordSize == jintSize, "else use imulq, shlq, etc."); + __ imull(arr_size, t1); + __ movl(t1, t2); // reload layout helper + __ shrl(t1, LayoutHelper::_element_size_shift); // lh>>16, mask needed + __ andl(t1, LayoutHelper::_element_scale_mask); + assert(t1 == rcx, "fixed register usage"); + __ shll(arr_size /* by t1=rcx, mod 32 */); + __ 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); + __ subl(arr_size, min_header_size); // body length + __ movl(t1, obj); + __ addl(t1, min_header_size); // body start + __ initialize_body(t1, arr_size, 0, t2); + } + + OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { // for better readability const bool must_gc_arguments = true; const bool dont_gc_arguments = false;
*** 867,883 **** } #ifdef ASSERT // assert object can be fast path allocated { ! Label ok, not_ok; ! __ movl(obj_size, Address(klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc))); ! __ cmpl(obj_size, 0); // make sure it's an instance (LH > 0) ! __ jcc(Assembler::lessEqual, not_ok); ! __ testl(obj_size, Klass::_lh_instance_slow_path_bit); __ jcc(Assembler::zero, ok); - __ bind(not_ok); __ stop("assert(can be fast path allocated)"); __ should_not_reach_here(); __ bind(ok); } #endif // ASSERT --- 958,971 ---- } #ifdef ASSERT // assert object can be fast path allocated { ! Label ok; ! __ movl(obj_size, layout_helper_addr(klass)); ! __ testl(obj_size, LayoutHelper::_slow_path_low_bit); __ jcc(Assembler::zero, ok); __ stop("assert(can be fast path allocated)"); __ should_not_reach_here(); __ bind(ok); } #endif // ASSERT
*** 888,915 **** __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass) __ bind(retry_tlab); // get the instance size ! __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); __ popl(rbx); __ popl(rdi); __ ret(0); __ bind(try_eden); // get the instance size ! __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); __ eden_allocate(obj, obj_size, 0, t1, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); __ popl(rbx); __ popl(rdi); __ ret(0); __ bind(slow_path); __ popl(rbx); __ popl(rdi); } --- 976,1019 ---- __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass) __ bind(retry_tlab); // get the instance size ! Label have_obj_size, size_is_variable; ! compute_instance_size(obj_size, klass, ! have_obj_size, size_is_variable, ! sasm, true); __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); __ popl(rbx); __ popl(rdi); __ ret(0); + // generate side path, if any + compute_instance_size(obj_size, klass, + have_obj_size, size_is_variable, + sasm, false); + __ bind(try_eden); // get the instance size ! Label have_obj_size_2, size_is_variable_2; ! compute_instance_size(obj_size, klass, ! have_obj_size_2, size_is_variable_2, ! sasm, true); __ eden_allocate(obj, obj_size, 0, t1, slow_path); __ initialize_object(obj, klass, obj_size, 0, t1, t2); __ verify_oop(obj); __ popl(rbx); __ popl(rdi); __ ret(0); + // generate side path, if any + compute_instance_size(obj_size, klass, + have_obj_size_2, size_is_variable_2, + sasm, false); + __ bind(slow_path); __ popl(rbx); __ popl(rdi); }
*** 962,976 **** #ifdef ASSERT // assert object type is really an array of the proper kind { Label ok; Register t0 = obj; ! __ movl(t0, Address(klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc))); ! __ sarl(t0, Klass::_lh_array_tag_shift); ! int tag = ((id == new_type_array_id) ! ? Klass::_lh_array_tag_type_value ! : Klass::_lh_array_tag_obj_value); __ cmpl(t0, tag); __ jcc(Assembler::equal, ok); __ stop("assert(is an array klass)"); __ should_not_reach_here(); __ bind(ok); --- 1066,1084 ---- #ifdef ASSERT // assert object type is really an array of the proper kind { Label ok; Register t0 = obj; ! __ movl(t0, layout_helper_addr(klass)); ! 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; ! __ sarl(t0, flag_shift); ! assert(id == new_object_array_id || ! tag == (LayoutHelper::for_array(T_DOUBLE).as_int() >> flag_shift), ! "same tag for all type arrays"); __ cmpl(t0, tag); __ jcc(Assembler::equal, ok); __ stop("assert(is an array klass)"); __ should_not_reach_here(); __ bind(ok);
*** 993,1051 **** Label retry_tlab, try_eden; __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx, & rdx __ bind(retry_tlab); ! // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) ! __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); ! __ movl(arr_size, length); ! assert(t1 == rcx, "fixed register usage"); ! __ shll(arr_size /* by t1=rcx, mod 32 */); ! __ shrl(t1, Klass::_lh_header_size_shift); ! __ andl(t1, Klass::_lh_header_size_mask); ! __ addl(arr_size, t1); ! __ addl(arr_size, MinObjAlignmentInBytesMask); // align up ! __ andl(arr_size, ~MinObjAlignmentInBytesMask); ! __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size __ initialize_header(obj, klass, length, t1, t2); ! __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); ! assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); ! assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); ! __ andl(t1, Klass::_lh_header_size_mask); ! __ subl(arr_size, t1); // body length ! __ addl(t1, obj); // body start ! __ initialize_body(t1, arr_size, 0, t2); __ verify_oop(obj); __ ret(0); ! __ bind(try_eden); ! // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) ! __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); ! __ movl(arr_size, length); ! assert(t1 == rcx, "fixed register usage"); ! __ shll(arr_size /* by t1=rcx, mod 32 */); ! __ shrl(t1, Klass::_lh_header_size_shift); ! __ andl(t1, Klass::_lh_header_size_mask); ! __ addl(arr_size, t1); ! __ addl(arr_size, MinObjAlignmentInBytesMask); // align up ! __ andl(arr_size, ~MinObjAlignmentInBytesMask); __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size __ initialize_header(obj, klass, length, t1, t2); ! __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); ! assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); ! assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); ! __ andl(t1, Klass::_lh_header_size_mask); ! __ subl(arr_size, t1); // body length ! __ addl(t1, obj); // body start ! __ initialize_body(t1, arr_size, 0, t2); __ verify_oop(obj); __ ret(0); __ bind(slow_path); } __ enter(); OopMap* map = save_live_registers(sasm, 3); --- 1101,1143 ---- Label retry_tlab, try_eden; __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx, & rdx __ bind(retry_tlab); ! Label have_scaled_length, need_multiply; ! compute_array_size(arr_size, klass, length, ! have_scaled_length, need_multiply, ! t1, t2, sasm, true); __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size __ initialize_header(obj, klass, length, t1, t2); ! initialize_array_body(obj, arr_size, t1, t2, sasm); __ verify_oop(obj); __ ret(0); ! // generate side path, if any ! compute_array_size(arr_size, klass, length, ! have_scaled_length, need_multiply, ! t1, t2, sasm, false); + __ bind(try_eden); + Label have_scaled_length_2, need_multiply_2; + compute_array_size(arr_size, klass, length, + have_scaled_length_2, need_multiply_2, + t1, t2, sasm, true); __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size __ initialize_header(obj, klass, length, t1, t2); ! initialize_array_body(obj, arr_size, t1, t2, sasm); __ verify_oop(obj); __ ret(0); + // generate side path, if any + compute_array_size(arr_size, klass, length, + have_scaled_length_2, need_multiply_2, + t1, t2, sasm, false); + __ bind(slow_path); } __ enter(); OopMap* map = save_live_registers(sasm, 3);