src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File c1-coops Sdiff src/cpu/x86/vm

src/cpu/x86/vm/c1_MacroAssembler_x86.cpp

Print this page




 128 // Defines obj, preserves var_size_in_bytes
 129 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
 130   if (UseTLAB) {
 131     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
 132   } else {
 133     eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
 134   }
 135 }
 136 
 137 
 138 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
 139   assert_different_registers(obj, klass, len);
 140   if (UseBiasedLocking && !len->is_valid()) {
 141     assert_different_registers(obj, klass, len, t1, t2);
 142     movptr(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
 143     movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
 144   } else {
 145     // This assumes that all prototype bits fit in an int32_t
 146     movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
 147   }
 148 







 149   movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);


 150   if (len->is_valid()) {
 151     movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
 152   }






 153 }
 154 
 155 
 156 // preserves obj, destroys len_in_bytes
 157 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
 158   Label done;
 159   assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
 160   assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
 161   Register index = len_in_bytes;
 162   // index is positive and ptr sized
 163   subptr(index, hdr_size_in_bytes);
 164   jcc(Assembler::zero, done);
 165   // initialize topmost word, divide index by 2, check if odd and test if zero
 166   // note: for the remaining code to work, index must be a multiple of BytesPerWord
 167 #ifdef ASSERT
 168   { Label L;
 169     testptr(index, BytesPerWord - 1);
 170     jcc(Assembler::zero, L);
 171     stop("index is not a multiple of BytesPerWord");
 172     bind(L);


 203   }
 204 
 205   // done
 206   bind(done);
 207 }
 208 
 209 
 210 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
 211   assert(obj == rax, "obj must be in rax, for cmpxchg");
 212   assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
 213   assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
 214 
 215   try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
 216 
 217   initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
 218 }
 219 
 220 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
 221   assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
 222          "con_size_in_bytes is not multiple of alignment");
 223   const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes();
 224 
 225   initialize_header(obj, klass, noreg, t1, t2);
 226 
 227   // clear rest of allocated space
 228   const Register t1_zero = t1;
 229   const Register index = t2;
 230   const int threshold = 6 * BytesPerWord;   // approximate break even point for code size (see comments below)
 231   if (var_size_in_bytes != noreg) {
 232     mov(index, var_size_in_bytes);
 233     initialize_body(obj, index, hdr_size_in_bytes, t1_zero);
 234   } else if (con_size_in_bytes <= threshold) {
 235     // use explicit null stores
 236     // code size = 2 + 3*n bytes (n = number of fields to clear)
 237     xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code)
 238     for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord)
 239       movptr(Address(obj, i), t1_zero);
 240   } else if (con_size_in_bytes > hdr_size_in_bytes) {
 241     // use loop to null out the fields
 242     // code size = 16 bytes for even n (n = number of fields to clear)
 243     // initialize last object field first if odd number of fields


 290   // clear rest of allocated space
 291   const Register len_zero = len;
 292   initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
 293 
 294   if (CURRENT_ENV->dtrace_alloc_probes()) {
 295     assert(obj == rax, "must be");
 296     call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
 297   }
 298 
 299   verify_oop(obj);
 300 }
 301 
 302 
 303 
 304 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
 305   verify_oop(receiver);
 306   // explicit NULL check not needed since load from [klass_offset] causes a trap
 307   // check against inline cache
 308   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
 309   int start_offset = offset();






 310   cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
 311   // if icache check fails, then jump to runtime routine
 312   // Note: RECEIVER must still contain the receiver!
 313   jump_cc(Assembler::notEqual,
 314           RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
 315   const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
 316   assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
 317 }
 318 
 319 
 320 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
 321   // Make sure there is enough stack space for this method's activation.
 322   // Note that we do this before doing an enter(). This matches the
 323   // ordering of C2's stack overflow check / rsp decrement and allows
 324   // the SharedRuntime stack overflow handling to be consistent
 325   // between the two compilers.
 326   generate_stack_overflow_check(frame_size_in_bytes);
 327 
 328   push(rbp);
 329 #ifdef TIERED
 330   // c2 leaves fpu stack dirty. Clean it on entry
 331   if (UseSSE < 2 ) {
 332     empty_FPU_stack();
 333   }
 334 #endif // TIERED
 335   decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
 336 }




 128 // Defines obj, preserves var_size_in_bytes
 129 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
 130   if (UseTLAB) {
 131     tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
 132   } else {
 133     eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
 134   }
 135 }
 136 
 137 
 138 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
 139   assert_different_registers(obj, klass, len);
 140   if (UseBiasedLocking && !len->is_valid()) {
 141     assert_different_registers(obj, klass, len, t1, t2);
 142     movptr(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
 143     movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
 144   } else {
 145     // This assumes that all prototype bits fit in an int32_t
 146     movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
 147   }
 148 #ifdef _LP64
 149   if (UseCompressedOops) { // Take care not to kill klass
 150     movptr(t1, klass);
 151     encode_heap_oop_not_null(t1);
 152     movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
 153   } else
 154 #endif
 155   {
 156     movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
 157   }
 158 
 159   if (len->is_valid()) {
 160     movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
 161   }
 162 #ifdef _LP64
 163   else if (UseCompressedOops) {
 164     xorptr(t1, t1);
 165     store_klass_gap(obj, t1);
 166   }
 167 #endif // _LP64
 168 }
 169 
 170 
 171 // preserves obj, destroys len_in_bytes
 172 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
 173   Label done;
 174   assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
 175   assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
 176   Register index = len_in_bytes;
 177   // index is positive and ptr sized
 178   subptr(index, hdr_size_in_bytes);
 179   jcc(Assembler::zero, done);
 180   // initialize topmost word, divide index by 2, check if odd and test if zero
 181   // note: for the remaining code to work, index must be a multiple of BytesPerWord
 182 #ifdef ASSERT
 183   { Label L;
 184     testptr(index, BytesPerWord - 1);
 185     jcc(Assembler::zero, L);
 186     stop("index is not a multiple of BytesPerWord");
 187     bind(L);


 218   }
 219 
 220   // done
 221   bind(done);
 222 }
 223 
 224 
 225 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
 226   assert(obj == rax, "obj must be in rax, for cmpxchg");
 227   assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
 228   assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
 229 
 230   try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
 231 
 232   initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
 233 }
 234 
 235 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
 236   assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
 237          "con_size_in_bytes is not multiple of alignment");
 238   const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
 239 
 240   initialize_header(obj, klass, noreg, t1, t2);
 241 
 242   // clear rest of allocated space
 243   const Register t1_zero = t1;
 244   const Register index = t2;
 245   const int threshold = 6 * BytesPerWord;   // approximate break even point for code size (see comments below)
 246   if (var_size_in_bytes != noreg) {
 247     mov(index, var_size_in_bytes);
 248     initialize_body(obj, index, hdr_size_in_bytes, t1_zero);
 249   } else if (con_size_in_bytes <= threshold) {
 250     // use explicit null stores
 251     // code size = 2 + 3*n bytes (n = number of fields to clear)
 252     xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code)
 253     for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord)
 254       movptr(Address(obj, i), t1_zero);
 255   } else if (con_size_in_bytes > hdr_size_in_bytes) {
 256     // use loop to null out the fields
 257     // code size = 16 bytes for even n (n = number of fields to clear)
 258     // initialize last object field first if odd number of fields


 305   // clear rest of allocated space
 306   const Register len_zero = len;
 307   initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
 308 
 309   if (CURRENT_ENV->dtrace_alloc_probes()) {
 310     assert(obj == rax, "must be");
 311     call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
 312   }
 313 
 314   verify_oop(obj);
 315 }
 316 
 317 
 318 
 319 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
 320   verify_oop(receiver);
 321   // explicit NULL check not needed since load from [klass_offset] causes a trap
 322   // check against inline cache
 323   assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
 324   int start_offset = offset();
 325 #ifdef _LP64
 326   if (UseCompressedOops) {
 327     load_klass(rscratch1, receiver);
 328     cmpptr(rscratch1, iCache);
 329   } else
 330 #endif
 331     cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
 332   // if icache check fails, then jump to runtime routine
 333   // Note: RECEIVER must still contain the receiver!
 334   jump_cc(Assembler::notEqual,
 335           RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
 336   const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
 337   assert(UseCompressedOops || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
 338 }
 339 
 340 
 341 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
 342   // Make sure there is enough stack space for this method's activation.
 343   // Note that we do this before doing an enter(). This matches the
 344   // ordering of C2's stack overflow check / rsp decrement and allows
 345   // the SharedRuntime stack overflow handling to be consistent
 346   // between the two compilers.
 347   generate_stack_overflow_check(frame_size_in_bytes);
 348 
 349   push(rbp);
 350 #ifdef TIERED
 351   // c2 leaves fpu stack dirty. Clean it on entry
 352   if (UseSSE < 2 ) {
 353     empty_FPU_stack();
 354   }
 355 #endif // TIERED
 356   decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
 357 }


src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File