165 } else 166 #endif 167 { 168 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); 169 } 170 171 if (len->is_valid()) { 172 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); 173 } 174 #ifdef _LP64 175 else if (UseCompressedClassPointers) { 176 xorptr(t1, t1); 177 store_klass_gap(obj, t1); 178 } 179 #endif 180 } 181 182 183 // preserves obj, destroys len_in_bytes 184 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) { 185 Label done; 186 assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different"); 187 assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord"); 188 Register index = len_in_bytes; 189 // index is positive and ptr sized 190 subptr(index, hdr_size_in_bytes); 191 jcc(Assembler::zero, done); 192 // initialize topmost word, divide index by 2, check if odd and test if zero 193 // note: for the remaining code to work, index must be a multiple of BytesPerWord 194 #ifdef ASSERT 195 { Label L; 196 testptr(index, BytesPerWord - 1); 197 jcc(Assembler::zero, L); 198 stop("index is not a multiple of BytesPerWord"); 199 bind(L); 200 } 201 #endif 202 xorptr(t1, t1); // use _zero reg to clear memory (shorter code) 203 if (UseIncDec) { 204 shrptr(index, 3); // divide by 8/16 and set carry flag if bit 2 was set 205 } else { 206 shrptr(index, 2); // use 2 instructions to avoid partial flag stall 207 shrptr(index, 1); 208 } 209 #ifndef _LP64 210 // index could have been not a multiple of 8 (i.e., bit 2 was set) 211 { Label even; 212 // note: if index was a multiple of 8, than it cannot 213 // be 0 now otherwise it must have been 0 before 214 // => if it is even, we don't need to check for 0 again 215 jcc(Assembler::carryClear, even); 216 // clear topmost word (no jump needed if conditional assignment would work here) 217 movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 0*BytesPerWord), t1); 218 // index could be 0 now, need to check again 219 jcc(Assembler::zero, done); 220 bind(even); 221 } 222 #endif // !_LP64 223 // initialize remaining object fields: rdx is a multiple of 2 now 224 { Label loop; 225 bind(loop); 226 movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 1*BytesPerWord), t1); 227 NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - 2*BytesPerWord), t1);) 228 decrement(index); 229 jcc(Assembler::notZero, loop); 230 } 231 232 // done 233 bind(done); 234 } 235 236 237 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) { 238 assert(obj == rax, "obj must be in rax, for cmpxchg"); 239 assert_different_registers(obj, t1, t2); // XXX really? 240 assert(header_size >= 0 && object_size >= header_size, "illegal sizes"); 241 242 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case); 243 244 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2); 245 } 246 247 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) { 248 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, 249 "con_size_in_bytes is not multiple of alignment"); 250 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 251 252 initialize_header(obj, klass, noreg, t1, t2); 253 254 // clear rest of allocated space 255 const Register t1_zero = t1; 256 const Register index = t2; 257 const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below) 258 if (var_size_in_bytes != noreg) { 259 mov(index, var_size_in_bytes); 260 initialize_body(obj, index, hdr_size_in_bytes, t1_zero); 261 } else if (con_size_in_bytes <= threshold) { 262 // use explicit null stores 263 // code size = 2 + 3*n bytes (n = number of fields to clear) 264 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) 265 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord) 266 movptr(Address(obj, i), t1_zero); 267 } else if (con_size_in_bytes > hdr_size_in_bytes) { 268 // use loop to null out the fields 269 // code size = 16 bytes for even n (n = number of fields to clear) 270 // initialize last object field first if odd number of fields 271 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) 272 movptr(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); 273 // initialize last object field if constant size is odd 274 if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0) 275 movptr(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero); 276 // initialize remaining object fields: rdx is a multiple of 2 277 { Label loop; 278 bind(loop); 279 movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (1*BytesPerWord)), 280 t1_zero); 281 NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (2*BytesPerWord)), 282 t1_zero);) 283 decrement(index); 284 jcc(Assembler::notZero, loop); 285 } 286 } 287 288 if (CURRENT_ENV->dtrace_alloc_probes()) { 289 assert(obj == rax, "must be"); 290 call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id))); 291 } 292 293 verify_oop(obj); 294 } 295 296 void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, Address::ScaleFactor f, Register klass, Label& slow_case) { 297 assert(obj == rax, "obj must be in rax, for cmpxchg"); 298 assert_different_registers(obj, len, t1, t2, klass); 299 300 // determine alignment mask 301 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work"); 302 303 // check for negative or excessive length 304 cmpptr(len, (int32_t)max_array_allocation_length); | 165 } else 166 #endif 167 { 168 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass); 169 } 170 171 if (len->is_valid()) { 172 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len); 173 } 174 #ifdef _LP64 175 else if (UseCompressedClassPointers) { 176 xorptr(t1, t1); 177 store_klass_gap(obj, t1); 178 } 179 #endif 180 } 181 182 183 // preserves obj, destroys len_in_bytes 184 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) { 185 assert(hdr_size_in_bytes >= 0, "header size must be positive or 0"); 186 Label done; 187 188 // len_in_bytes is positive and ptr sized 189 subptr(len_in_bytes, hdr_size_in_bytes); 190 jcc(Assembler::zero, done); 191 zero_memory(obj, len_in_bytes, hdr_size_in_bytes, t1); 192 bind(done); 193 } 194 195 196 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) { 197 assert(obj == rax, "obj must be in rax, for cmpxchg"); 198 assert_different_registers(obj, t1, t2); // XXX really? 199 assert(header_size >= 0 && object_size >= header_size, "illegal sizes"); 200 201 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case); 202 203 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2, UseTLAB); 204 } 205 206 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, bool is_tlab_allocated) { 207 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0, 208 "con_size_in_bytes is not multiple of alignment"); 209 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize; 210 211 initialize_header(obj, klass, noreg, t1, t2); 212 213 if (!(UseTLAB && ZeroTLAB && is_tlab_allocated)) { 214 // clear rest of allocated space 215 const Register t1_zero = t1; 216 const Register index = t2; 217 const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below) 218 if (var_size_in_bytes != noreg) { 219 mov(index, var_size_in_bytes); 220 initialize_body(obj, index, hdr_size_in_bytes, t1_zero); 221 } else if (con_size_in_bytes <= threshold) { 222 // use explicit null stores 223 // code size = 2 + 3*n bytes (n = number of fields to clear) 224 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) 225 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord) 226 movptr(Address(obj, i), t1_zero); 227 } else if (con_size_in_bytes > hdr_size_in_bytes) { 228 // use loop to null out the fields 229 // code size = 16 bytes for even n (n = number of fields to clear) 230 // initialize last object field first if odd number of fields 231 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code) 232 movptr(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3); 233 // initialize last object field if constant size is odd 234 if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0) 235 movptr(Address(obj, con_size_in_bytes - (1*BytesPerWord)), t1_zero); 236 // initialize remaining object fields: rdx is a multiple of 2 237 { Label loop; 238 bind(loop); 239 movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (1*BytesPerWord)), 240 t1_zero); 241 NOT_LP64(movptr(Address(obj, index, Address::times_8, hdr_size_in_bytes - (2*BytesPerWord)), 242 t1_zero);) 243 decrement(index); 244 jcc(Assembler::notZero, loop); 245 } 246 } 247 } 248 249 if (CURRENT_ENV->dtrace_alloc_probes()) { 250 assert(obj == rax, "must be"); 251 call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id))); 252 } 253 254 verify_oop(obj); 255 } 256 257 void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, int header_size, Address::ScaleFactor f, Register klass, Label& slow_case) { 258 assert(obj == rax, "obj must be in rax, for cmpxchg"); 259 assert_different_registers(obj, len, t1, t2, klass); 260 261 // determine alignment mask 262 assert(!(BytesPerWord & 1), "must be a multiple of 2 for masking code to work"); 263 264 // check for negative or excessive length 265 cmpptr(len, (int32_t)max_array_allocation_length); |