3029 { Label L_a, L_b;
3030 __ br_notnull_short(G3_src_klass, Assembler::pt, L_b); // it is broken if klass is NULL
3031 __ bind(L_a);
3032 __ stop("broken null klass");
3033 __ bind(L_b);
3034 __ load_klass(dst, G4_dst_klass);
3035 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also
3036 __ delayed()->mov(G0, G4_dst_klass); // scribble the temp
3037 BLOCK_COMMENT("assert done");
3038 }
3039 #endif
3040
3041 // Load layout helper
3042 //
3043 // |array_tag| | header_size | element_type | |log2_element_size|
3044 // 32 30 24 16 8 2 0
3045 //
3046 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3047 //
3048
3049 int lh_offset = klassOopDesc::header_size() * HeapWordSize +
3050 Klass::layout_helper_offset_in_bytes();
3051
3052 // Load 32-bits signed value. Use br() instruction with it to check icc.
3053 __ lduw(G3_src_klass, lh_offset, G5_lh);
3054
3055 if (UseCompressedOops) {
3056 __ load_klass(dst, G4_dst_klass);
3057 }
3058 // Handle objArrays completely differently...
3059 juint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3060 __ set(objArray_lh, O5_temp);
3061 __ cmp(G5_lh, O5_temp);
3062 __ br(Assembler::equal, false, Assembler::pt, L_objArray);
3063 if (UseCompressedOops) {
3064 __ delayed()->nop();
3065 } else {
3066 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
3067 }
3068
3069 // if (src->klass() != dst->klass()) return -1;
3070 __ cmp_and_brx_short(G3_src_klass, G4_dst_klass, Assembler::notEqual, Assembler::pn, L_failed);
3177
3178 // It is safe to examine both src.length and dst.length.
3179 __ delayed(); // match next insn to prev branch
3180 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
3181 O5_temp, G5_lh, L_failed);
3182
3183 // Marshal the base address arguments now, freeing registers.
3184 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
3185 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
3186 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
3187 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
3188 __ add(src, src_pos, from); // src_addr
3189 __ add(dst, dst_pos, to); // dst_addr
3190 __ signx(length, count); // length (reloaded)
3191
3192 Register sco_temp = O3; // this register is free now
3193 assert_different_registers(from, to, count, sco_temp,
3194 G4_dst_klass, G3_src_klass);
3195
3196 // Generate the type check.
3197 int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
3198 Klass::super_check_offset_offset_in_bytes());
3199 __ lduw(G4_dst_klass, sco_offset, sco_temp);
3200 generate_type_check(G3_src_klass, sco_temp, G4_dst_klass,
3201 O5_temp, L_plain_copy);
3202
3203 // Fetch destination element klass from the objArrayKlass header.
3204 int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
3205 objArrayKlass::element_klass_offset_in_bytes());
3206
3207 // the checkcast_copy loop needs two extra arguments:
3208 __ ld_ptr(G4_dst_klass, ek_offset, O4); // dest elem klass
3209 // lduw(O4, sco_offset, O3); // sco of elem klass
3210
3211 __ br(Assembler::always, false, Assembler::pt, entry_checkcast_arraycopy);
3212 __ delayed()->lduw(O4, sco_offset, O3);
3213 }
3214
3215 __ BIND(L_failed);
3216 __ retl();
3217 __ delayed()->sub(G0, 1, O0); // return -1
3218 return start;
3219 }
3220
3221 //
3222 // Generate stub for heap zeroing.
3223 // "to" address is aligned to jlong (8 bytes).
3224 //
3225 // Arguments for generated stub:
|
3029 { Label L_a, L_b;
3030 __ br_notnull_short(G3_src_klass, Assembler::pt, L_b); // it is broken if klass is NULL
3031 __ bind(L_a);
3032 __ stop("broken null klass");
3033 __ bind(L_b);
3034 __ load_klass(dst, G4_dst_klass);
3035 __ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also
3036 __ delayed()->mov(G0, G4_dst_klass); // scribble the temp
3037 BLOCK_COMMENT("assert done");
3038 }
3039 #endif
3040
3041 // Load layout helper
3042 //
3043 // |array_tag| | header_size | element_type | |log2_element_size|
3044 // 32 30 24 16 8 2 0
3045 //
3046 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
3047 //
3048
3049 int lh_offset = Klass::layout_helper_offset_in_bytes();
3050
3051 // Load 32-bits signed value. Use br() instruction with it to check icc.
3052 __ lduw(G3_src_klass, lh_offset, G5_lh);
3053
3054 if (UseCompressedOops) {
3055 __ load_klass(dst, G4_dst_klass);
3056 }
3057 // Handle objArrays completely differently...
3058 juint objArray_lh = Klass::array_layout_helper(T_OBJECT);
3059 __ set(objArray_lh, O5_temp);
3060 __ cmp(G5_lh, O5_temp);
3061 __ br(Assembler::equal, false, Assembler::pt, L_objArray);
3062 if (UseCompressedOops) {
3063 __ delayed()->nop();
3064 } else {
3065 __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
3066 }
3067
3068 // if (src->klass() != dst->klass()) return -1;
3069 __ cmp_and_brx_short(G3_src_klass, G4_dst_klass, Assembler::notEqual, Assembler::pn, L_failed);
3176
3177 // It is safe to examine both src.length and dst.length.
3178 __ delayed(); // match next insn to prev branch
3179 arraycopy_range_checks(src, src_pos, dst, dst_pos, length,
3180 O5_temp, G5_lh, L_failed);
3181
3182 // Marshal the base address arguments now, freeing registers.
3183 __ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
3184 __ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
3185 __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
3186 __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
3187 __ add(src, src_pos, from); // src_addr
3188 __ add(dst, dst_pos, to); // dst_addr
3189 __ signx(length, count); // length (reloaded)
3190
3191 Register sco_temp = O3; // this register is free now
3192 assert_different_registers(from, to, count, sco_temp,
3193 G4_dst_klass, G3_src_klass);
3194
3195 // Generate the type check.
3196 int sco_offset = Klass::super_check_offset_offset_in_bytes();
3197 __ lduw(G4_dst_klass, sco_offset, sco_temp);
3198 generate_type_check(G3_src_klass, sco_temp, G4_dst_klass,
3199 O5_temp, L_plain_copy);
3200
3201 // Fetch destination element klass from the objArrayKlass header.
3202 int ek_offset = objArrayKlass::element_klass_offset_in_bytes();
3203
3204 // the checkcast_copy loop needs two extra arguments:
3205 __ ld_ptr(G4_dst_klass, ek_offset, O4); // dest elem klass
3206 // lduw(O4, sco_offset, O3); // sco of elem klass
3207
3208 __ br(Assembler::always, false, Assembler::pt, entry_checkcast_arraycopy);
3209 __ delayed()->lduw(O4, sco_offset, O3);
3210 }
3211
3212 __ BIND(L_failed);
3213 __ retl();
3214 __ delayed()->sub(G0, 1, O0); // return -1
3215 return start;
3216 }
3217
3218 //
3219 // Generate stub for heap zeroing.
3220 // "to" address is aligned to jlong (8 bytes).
3221 //
3222 // Arguments for generated stub:
|