188 } 189 st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); 190 if (UseCompressedClassPointers) { 191 // Save klass 192 mov(klass, t1); 193 encode_klass_not_null(t1); 194 stw(t1, obj, oopDesc::klass_offset_in_bytes()); 195 } else { 196 st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); 197 } 198 if (len->is_valid()) { 199 st(len, obj, arrayOopDesc::length_offset_in_bytes()); 200 } else if (UseCompressedClassPointers) { 201 // otherwise length is in the class gap 202 store_klass_gap(G0, obj); 203 } 204 } 205 206 207 void C1_MacroAssembler::initialize_body(Register base, Register index) { 208 assert_different_registers(base, index); 209 Label loop; 210 bind(loop); 211 subcc(index, HeapWordSize, index); 212 brx(Assembler::greaterEqual, true, Assembler::pt, loop); 213 delayed()->st_ptr(G0, base, index); 214 } 215 216 217 void C1_MacroAssembler::allocate_object( 218 Register obj, // result: pointer to object after successful allocation 219 Register t1, // temp register 220 Register t2, // temp register, must be a global register for try_allocate 221 Register t3, // temp register 222 int hdr_size, // object header size in words 223 int obj_size, // object size in words 224 Register klass, // object klass 225 Label& slow_case // continuation point if fast allocation fails 226 ) { 227 assert_different_registers(obj, t1, t2, t3, klass); 228 assert(klass == G5, "must be G5"); 229 230 // allocate space & initialize header 231 if (!is_simm13(obj_size * wordSize)) { 232 // would need to use extra register to load 233 // object size => go the slow case for now 234 ba(slow_case); 235 delayed()->nop(); 236 return; 237 } 238 try_allocate(obj, noreg, obj_size * wordSize, t2, t3, slow_case); 239 240 initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2); 241 } 242 243 void C1_MacroAssembler::initialize_object( 244 Register obj, // result: pointer to object after successful allocation 245 Register klass, // object klass 246 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise 247 int con_size_in_bytes, // object size in bytes if known at compile time 248 Register t1, // temp register 249 Register t2 // temp register 250 ) { 251 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 252 253 initialize_header(obj, klass, noreg, t1, t2); 254 255 #ifdef ASSERT 256 { 257 Label ok; 258 ld(klass, in_bytes(Klass::layout_helper_offset()), t1); 259 if (var_size_in_bytes != noreg) { 260 cmp_and_brx_short(t1, var_size_in_bytes, Assembler::equal, Assembler::pt, ok); 261 } else { 262 cmp_and_brx_short(t1, con_size_in_bytes, Assembler::equal, Assembler::pt, ok); 263 } 264 stop("bad size in initialize_object"); 265 should_not_reach_here(); 266 267 bind(ok); 268 } 269 270 #endif 271 272 // initialize body 273 const int threshold = 5 * HeapWordSize; // approximate break even point for code size 274 if (var_size_in_bytes != noreg) { 275 // use a loop 276 add(obj, hdr_size_in_bytes, t1); // compute address of first element 277 sub(var_size_in_bytes, hdr_size_in_bytes, t2); // compute size of body 278 initialize_body(t1, t2); 279 #ifndef _LP64 280 } else if (con_size_in_bytes < threshold * 2) { 281 // on v9 we can do double word stores to fill twice as much space. 282 assert(hdr_size_in_bytes % 8 == 0, "double word aligned"); 283 assert(con_size_in_bytes % 8 == 0, "double word aligned"); 284 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += 2 * HeapWordSize) stx(G0, obj, i); 285 #endif 286 } else if (con_size_in_bytes <= threshold) { 287 // use explicit NULL stores 288 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += HeapWordSize) st_ptr(G0, obj, i); 289 } else if (con_size_in_bytes > hdr_size_in_bytes) { 290 // use a loop 291 const Register base = t1; 292 const Register index = t2; 293 add(obj, hdr_size_in_bytes, base); // compute address of first element 294 // compute index = number of words to clear 295 set(con_size_in_bytes - hdr_size_in_bytes, index); 296 initialize_body(base, index); 297 } 298 299 if (CURRENT_ENV->dtrace_alloc_probes()) { 300 assert(obj == O0, "must be"); 301 call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), 302 relocInfo::runtime_call_type); 303 delayed()->nop(); 304 } 305 306 verify_oop(obj); 307 } 308 309 310 void C1_MacroAssembler::allocate_array( 311 Register obj, // result: pointer to array after successful allocation 312 Register len, // array length 313 Register t1, // temp register 314 Register t2, // temp register 315 Register t3, // temp register 316 int hdr_size, // object header size in words | 188 } 189 st_ptr(t1, obj, oopDesc::mark_offset_in_bytes()); 190 if (UseCompressedClassPointers) { 191 // Save klass 192 mov(klass, t1); 193 encode_klass_not_null(t1); 194 stw(t1, obj, oopDesc::klass_offset_in_bytes()); 195 } else { 196 st_ptr(klass, obj, oopDesc::klass_offset_in_bytes()); 197 } 198 if (len->is_valid()) { 199 st(len, obj, arrayOopDesc::length_offset_in_bytes()); 200 } else if (UseCompressedClassPointers) { 201 // otherwise length is in the class gap 202 store_klass_gap(G0, obj); 203 } 204 } 205 206 207 void C1_MacroAssembler::initialize_body(Register base, Register index) { 208 zero_memory(base, index); 209 } 210 211 212 void C1_MacroAssembler::allocate_object( 213 Register obj, // result: pointer to object after successful allocation 214 Register t1, // temp register 215 Register t2, // temp register, must be a global register for try_allocate 216 Register t3, // temp register 217 int hdr_size, // object header size in words 218 int obj_size, // object size in words 219 Register klass, // object klass 220 Label& slow_case // continuation point if fast allocation fails 221 ) { 222 assert_different_registers(obj, t1, t2, t3, klass); 223 assert(klass == G5, "must be G5"); 224 225 // allocate space & initialize header 226 if (!is_simm13(obj_size * wordSize)) { 227 // would need to use extra register to load 228 // object size => go the slow case for now 229 ba(slow_case); 230 delayed()->nop(); 231 return; 232 } 233 try_allocate(obj, noreg, obj_size * wordSize, t2, t3, slow_case); 234 235 initialize_object(obj, klass, noreg, obj_size * HeapWordSize, t1, t2, /* is_tlab_allocated */ UseTLAB); 236 } 237 238 void C1_MacroAssembler::initialize_object( 239 Register obj, // result: pointer to object after successful allocation 240 Register klass, // object klass 241 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise 242 int con_size_in_bytes, // object size in bytes if known at compile time 243 Register t1, // temp register 244 Register t2, // temp register 245 bool is_tlab_allocated // the object was allocated in a TLAB; relevant for the implementation of ZeroTLAB 246 ) { 247 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 248 249 initialize_header(obj, klass, noreg, t1, t2); 250 251 #ifdef ASSERT 252 { 253 Label ok; 254 ld(klass, in_bytes(Klass::layout_helper_offset()), t1); 255 if (var_size_in_bytes != noreg) { 256 cmp_and_brx_short(t1, var_size_in_bytes, Assembler::equal, Assembler::pt, ok); 257 } else { 258 cmp_and_brx_short(t1, con_size_in_bytes, Assembler::equal, Assembler::pt, ok); 259 } 260 stop("bad size in initialize_object"); 261 should_not_reach_here(); 262 263 bind(ok); 264 } 265 266 #endif 267 268 if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) { 269 // initialize body 270 const int threshold = 5 * HeapWordSize; // approximate break even point for code size 271 if (var_size_in_bytes != noreg) { 272 // use a loop 273 add(obj, hdr_size_in_bytes, t1); // compute address of first element 274 sub(var_size_in_bytes, hdr_size_in_bytes, t2); // compute size of body 275 initialize_body(t1, t2); 276 #ifndef _LP64 277 } else if (con_size_in_bytes < threshold * 2) { 278 // on v9 we can do double word stores to fill twice as much space. 279 assert(hdr_size_in_bytes % 8 == 0, "double word aligned"); 280 assert(con_size_in_bytes % 8 == 0, "double word aligned"); 281 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += 2 * HeapWordSize) stx(G0, obj, i); 282 #endif 283 } else if (con_size_in_bytes <= threshold) { 284 // use explicit NULL stores 285 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += HeapWordSize) st_ptr(G0, obj, i); 286 } else if (con_size_in_bytes > hdr_size_in_bytes) { 287 // use a loop 288 const Register base = t1; 289 const Register index = t2; 290 add(obj, hdr_size_in_bytes, base); // compute address of first element 291 // compute index = number of words to clear 292 set(con_size_in_bytes - hdr_size_in_bytes, index); 293 initialize_body(base, index); 294 } 295 } 296 297 if (CURRENT_ENV->dtrace_alloc_probes()) { 298 assert(obj == O0, "must be"); 299 call(CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), 300 relocInfo::runtime_call_type); 301 delayed()->nop(); 302 } 303 304 verify_oop(obj); 305 } 306 307 308 void C1_MacroAssembler::allocate_array( 309 Register obj, // result: pointer to array after successful allocation 310 Register len, // array length 311 Register t1, // temp register 312 Register t2, // temp register 313 Register t3, // temp register 314 int hdr_size, // object header size in words |