src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp
changeset 50693 db0a17475826
parent 50599 ecc2af326b5f
child 50728 9375184cec98
equal deleted inserted replaced
50692:5b75d7485f2a 50693:db0a17475826
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "gc/shared/barrierSetAssembler.hpp"
    26 #include "gc/shared/barrierSetAssembler.hpp"
       
    27 #include "gc/shared/collectedHeap.hpp"
    27 #include "interpreter/interp_masm.hpp"
    28 #include "interpreter/interp_masm.hpp"
    28 #include "runtime/jniHandles.hpp"
    29 #include "runtime/jniHandles.hpp"
       
    30 #include "runtime/thread.hpp"
    29 
    31 
    30 #define __ masm->
    32 #define __ masm->
    31 
    33 
    32 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
    34 void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
    33                                   Register dst, Address src, Register tmp1, Register tmp_thread) {
    35                                   Register dst, Address src, Register tmp1, Register tmp_thread) {
   211 void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
   213 void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
   212                                                         Register obj, Register tmp, Label& slowpath) {
   214                                                         Register obj, Register tmp, Label& slowpath) {
   213   __ clear_jweak_tag(obj);
   215   __ clear_jweak_tag(obj);
   214   __ movptr(obj, Address(obj, 0));
   216   __ movptr(obj, Address(obj, 0));
   215 }
   217 }
       
   218 
       
   219 void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm,
       
   220                                         Register thread, Register obj,
       
   221                                         Register var_size_in_bytes,
       
   222                                         int con_size_in_bytes,
       
   223                                         Register t1,
       
   224                                         Register t2,
       
   225                                         Label& slow_case) {
       
   226   assert_different_registers(obj, t1, t2);
       
   227   assert_different_registers(obj, var_size_in_bytes, t1);
       
   228   Register end = t2;
       
   229   if (!thread->is_valid()) {
       
   230 #ifdef _LP64
       
   231     thread = r15_thread;
       
   232 #else
       
   233     assert(t1->is_valid(), "need temp reg");
       
   234     thread = t1;
       
   235     __ get_thread(thread);
       
   236 #endif
       
   237   }
       
   238 
       
   239   __ verify_tlab();
       
   240 
       
   241   __ movptr(obj, Address(thread, JavaThread::tlab_top_offset()));
       
   242   if (var_size_in_bytes == noreg) {
       
   243     __ lea(end, Address(obj, con_size_in_bytes));
       
   244   } else {
       
   245     __ lea(end, Address(obj, var_size_in_bytes, Address::times_1));
       
   246   }
       
   247   __ cmpptr(end, Address(thread, JavaThread::tlab_end_offset()));
       
   248   __ jcc(Assembler::above, slow_case);
       
   249 
       
   250   // update the tlab top pointer
       
   251   __ movptr(Address(thread, JavaThread::tlab_top_offset()), end);
       
   252 
       
   253   // recover var_size_in_bytes if necessary
       
   254   if (var_size_in_bytes == end) {
       
   255     __ subptr(var_size_in_bytes, obj);
       
   256   }
       
   257   __ verify_tlab();
       
   258 }
       
   259 
       
   260 // Defines obj, preserves var_size_in_bytes
       
   261 void BarrierSetAssembler::eden_allocate(MacroAssembler* masm,
       
   262                                         Register thread, Register obj,
       
   263                                         Register var_size_in_bytes,
       
   264                                         int con_size_in_bytes,
       
   265                                         Register t1,
       
   266                                         Label& slow_case) {
       
   267   assert(obj == rax, "obj must be in rax, for cmpxchg");
       
   268   assert_different_registers(obj, var_size_in_bytes, t1);
       
   269   if (!Universe::heap()->supports_inline_contig_alloc()) {
       
   270     __ jmp(slow_case);
       
   271   } else {
       
   272     Register end = t1;
       
   273     Label retry;
       
   274     __ bind(retry);
       
   275     ExternalAddress heap_top((address) Universe::heap()->top_addr());
       
   276     __ movptr(obj, heap_top);
       
   277     if (var_size_in_bytes == noreg) {
       
   278       __ lea(end, Address(obj, con_size_in_bytes));
       
   279     } else {
       
   280       __ lea(end, Address(obj, var_size_in_bytes, Address::times_1));
       
   281     }
       
   282     // if end < obj then we wrapped around => object too long => slow case
       
   283     __ cmpptr(end, obj);
       
   284     __ jcc(Assembler::below, slow_case);
       
   285     __ cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr()));
       
   286     __ jcc(Assembler::above, slow_case);
       
   287     // Compare obj with the top addr, and if still equal, store the new top addr in
       
   288     // end at the address of the top addr pointer. Sets ZF if was equal, and clears
       
   289     // it otherwise. Use lock prefix for atomicity on MPs.
       
   290     __ locked_cmpxchgptr(end, heap_top);
       
   291     __ jcc(Assembler::notEqual, retry);
       
   292     incr_allocated_bytes(masm, thread, var_size_in_bytes, con_size_in_bytes, thread->is_valid() ? noreg : t1);
       
   293   }
       
   294 }
       
   295 
       
   296 void BarrierSetAssembler::incr_allocated_bytes(MacroAssembler* masm, Register thread,
       
   297                                                Register var_size_in_bytes,
       
   298                                                int con_size_in_bytes,
       
   299                                                Register t1) {
       
   300   if (!thread->is_valid()) {
       
   301 #ifdef _LP64
       
   302     thread = r15_thread;
       
   303 #else
       
   304     assert(t1->is_valid(), "need temp reg");
       
   305     thread = t1;
       
   306     __ get_thread(thread);
       
   307 #endif
       
   308   }
       
   309 
       
   310 #ifdef _LP64
       
   311   if (var_size_in_bytes->is_valid()) {
       
   312     __ addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
       
   313   } else {
       
   314     __ addq(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
       
   315   }
       
   316 #else
       
   317   if (var_size_in_bytes->is_valid()) {
       
   318     __ addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), var_size_in_bytes);
       
   319   } else {
       
   320     __ addl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())), con_size_in_bytes);
       
   321   }
       
   322   __ adcl(Address(thread, in_bytes(JavaThread::allocated_bytes_offset())+4), 0);
       
   323 #endif
       
   324 }