src/cpu/sparc/vm/stubGenerator_sparc.cpp

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

*** 2698,2711 **** } #endif // Load layout helper // ! // |array_tag| | header_size | element_type | |log2_element_size| ! // 32 30 24 16 8 2 0 // ! // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0 // int lh_offset = klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes(); --- 2698,2711 ---- } #endif // Load layout helper // ! // | array_tag | element_type | log2_element_size | header_size | ! // 32 28 24 16 0 // ! // array_tag: typeArray = 0xF, objArray = 0xD, normal instance = 0x0 // int lh_offset = klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes();
*** 2714,2724 **** if (UseCompressedOops) { __ load_klass(dst, G4_dst_klass); } // Handle objArrays completely differently... ! juint objArray_lh = Klass::array_layout_helper(T_OBJECT); __ set(objArray_lh, O5_temp); __ cmp(G5_lh, O5_temp); __ br(Assembler::equal, false, Assembler::pt, L_objArray); if (UseCompressedOops) { __ delayed()->nop(); --- 2714,2727 ---- if (UseCompressedOops) { __ load_klass(dst, G4_dst_klass); } // Handle objArrays completely differently... ! // This is necessary because they have covariant element types. ! // The next type check (for src.klass == dst.klass), can get a ! // false negative in the case of object arrays. ! jint objArray_lh = LayoutHelper::for_array(T_OBJECT).as_int(); __ set(objArray_lh, O5_temp); __ cmp(G5_lh, O5_temp); __ br(Assembler::equal, false, Assembler::pt, L_objArray); if (UseCompressedOops) { __ delayed()->nop();
*** 2729,2757 **** // if (src->klass() != dst->klass()) return -1; __ cmp(G3_src_klass, G4_dst_klass); __ brx(Assembler::notEqual, false, Assembler::pn, L_failed); __ delayed()->nop(); ! // if (!src->is_Array()) return -1; ! __ cmp(G5_lh, Klass::_lh_neutral_value); // < 0 __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed); - // At this point, it is known to be a typeArray (array_tag 0x3). - #ifdef ASSERT - __ delayed()->nop(); - { Label L; - jint lh_prim_tag_in_place = (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift); - __ set(lh_prim_tag_in_place, O5_temp); - __ cmp(G5_lh, O5_temp); - __ br(Assembler::greaterEqual, false, Assembler::pt, L); - __ delayed()->nop(); - __ stop("must be a primitive array"); - __ bind(L); - } - #else __ delayed(); // match next insn to prev branch - #endif arraycopy_range_checks(src, src_pos, dst, dst_pos, length, O5_temp, G4_dst_klass, L_failed); // typeArrayKlass --- 2732,2746 ---- // if (src->klass() != dst->klass()) return -1; __ cmp(G3_src_klass, G4_dst_klass); __ brx(Assembler::notEqual, false, Assembler::pn, L_failed); __ delayed()->nop(); ! // if (!src->has_length_field()) return -1; ! __ cmp(G5_lh, LayoutHelper::_neutral_value); // < 0 __ br(Assembler::greaterEqual, false, Assembler::pn, L_failed); __ delayed(); // match next insn to prev branch arraycopy_range_checks(src, src_pos, dst, dst_pos, length, O5_temp, G4_dst_klass, L_failed); // typeArrayKlass
*** 2761,2775 **** // const Register G4_offset = G4_dst_klass; // array offset const Register G3_elsize = G3_src_klass; // log2 element size ! __ srl(G5_lh, Klass::_lh_header_size_shift, G4_offset); ! __ and3(G4_offset, Klass::_lh_header_size_mask, G4_offset); // array_offset __ add(src, G4_offset, src); // src array offset __ add(dst, G4_offset, dst); // dst array offset ! __ and3(G5_lh, Klass::_lh_log2_element_size_mask, G3_elsize); // log2 element size // next registers should be set before the jump to corresponding stub const Register from = O0; // source array address const Register to = O1; // destination array address const Register count = O2; // elements count --- 2750,2766 ---- // const Register G4_offset = G4_dst_klass; // array offset const Register G3_elsize = G3_src_klass; // log2 element size ! assert(LayoutHelper::_header_size_shift == 0, ""); ! __ set(LayoutHelper::_header_size_mask, G4_offset); ! __ and3(G5_lh, G4_offset, G4_offset); // array_offset __ add(src, G4_offset, src); // src array offset __ add(dst, G4_offset, dst); // dst array offset ! __ srl( G5_lh, LayoutHelper::_element_size_shift, G3_elsize); ! __ and3(G3_elsize, LayoutHelper::_element_size_mask, G3_elsize); // log2 element size // next registers should be set before the jump to corresponding stub const Register from = O0; // source array address const Register to = O1; // destination array address const Register count = O2; // elements count
*** 2805,2822 **** } #endif __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy); __ delayed()->signx(length, count); // length // objArrayKlass __ BIND(L_objArray); // live at this point: G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length - Label L_plain_copy, L_checkcast_copy; // test array classes for subtyping __ cmp(G3_src_klass, G4_dst_klass); // usual case is exact equality ! __ brx(Assembler::notEqual, true, Assembler::pn, L_checkcast_copy); __ delayed()->lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted from below // Identically typed arrays can be copied without element-wise checks. arraycopy_range_checks(src, src_pos, dst, dst_pos, length, O5_temp, G5_lh, L_failed); --- 2796,2814 ---- } #endif __ br(Assembler::always,false,Assembler::pt,StubRoutines::_jlong_arraycopy); __ delayed()->signx(length, count); // length + Label L_different_objArray, L_plain_copy, L_checkcast_copy; + // objArrayKlass __ BIND(L_objArray); // live at this point: G3_src_klass, G4_dst_klass, src[_pos], dst[_pos], length // test array classes for subtyping __ cmp(G3_src_klass, G4_dst_klass); // usual case is exact equality ! __ brx(Assembler::notEqual, true, Assembler::pn, L_different_objArray); __ delayed()->lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted from below // Identically typed arrays can be copied without element-wise checks. arraycopy_range_checks(src, src_pos, dst, dst_pos, length, O5_temp, G5_lh, L_failed);
*** 2829,2839 **** __ add(dst, dst_pos, to); // dst_addr __ BIND(L_plain_copy); __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy); __ delayed()->signx(length, count); // length ! __ BIND(L_checkcast_copy); // live at this point: G3_src_klass, G4_dst_klass { // Before looking at dst.length, make sure dst is also an objArray. // lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted to delay slot __ cmp(G5_lh, O5_temp); --- 2821,2831 ---- __ add(dst, dst_pos, to); // dst_addr __ BIND(L_plain_copy); __ br(Assembler::always, false, Assembler::pt,StubRoutines::_oop_arraycopy); __ delayed()->signx(length, count); // length ! __ BIND(L_different_objArray); // live at this point: G3_src_klass, G4_dst_klass { // Before looking at dst.length, make sure dst is also an objArray. // lduw(G4_dst_klass, lh_offset, O5_temp); // hoisted to delay slot __ cmp(G5_lh, O5_temp);