src/cpu/x86/vm/assembler_x86_64.cpp

changeset 777
37f87013dfd8
parent 559
b130b98db9cf
child 779
6aae2f9d0294
     1.1 --- a/src/cpu/x86/vm/assembler_x86_64.cpp	Wed Jun 04 13:51:09 2008 -0700
     1.2 +++ b/src/cpu/x86/vm/assembler_x86_64.cpp	Thu Jun 05 15:57:56 2008 -0700
     1.3 @@ -4405,6 +4405,129 @@
     1.4    call_VM_leaf(entry_point, 3);
     1.5  }
     1.6  
     1.7 +/////////////////////////////////////////////////////////////////////////////
     1.8 +#ifndef SERIALGC
     1.9 +
    1.10 +void MacroAssembler::g1_write_barrier_pre(Register obj, Register tmp, Register tmp2, bool tosca_live ) {
    1.11 +  Address in_progress(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
    1.12 +                                           PtrQueue::byte_offset_of_active()));
    1.13 +
    1.14 +  Address index(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
    1.15 +                                     PtrQueue::byte_offset_of_index()));
    1.16 +  Address buffer(r15_thread, in_bytes(JavaThread::satb_mark_queue_offset() +
    1.17 +                                      PtrQueue::byte_offset_of_buf()));
    1.18 +
    1.19 +
    1.20 +  Label done;
    1.21 +  Label runtime;
    1.22 +
    1.23 +  // if (!marking_in_progress) goto done;
    1.24 +  if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
    1.25 +    cmpl(in_progress, 0);
    1.26 +  } else {
    1.27 +    assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
    1.28 +    cmpb(in_progress, 0);
    1.29 +  }
    1.30 +  jcc(Assembler::equal, done);
    1.31 +
    1.32 +  // if (x.f == NULL) goto done;
    1.33 +  cmpq(Address(obj, 0), (int)NULL_WORD);
    1.34 +  jcc(Assembler::equal, done);
    1.35 +
    1.36 +  // Can we store original value in the thread's buffer?
    1.37 +
    1.38 +  movslq(tmp, index);
    1.39 +  movq(tmp2, Address(obj, 0));
    1.40 +  cmpq(tmp, 0);
    1.41 +  jcc(Assembler::equal, runtime);
    1.42 +  subq(tmp, wordSize);
    1.43 +  movl(index, tmp);
    1.44 +  addq(tmp, buffer);
    1.45 +  movq(Address(tmp, 0), tmp2);
    1.46 +  jmp(done);
    1.47 +  bind(runtime);
    1.48 +  // save live inputs
    1.49 +  if (tosca_live) pushq(rax);
    1.50 +  pushq(obj);
    1.51 +  movq(c_rarg0, Address(obj, 0));
    1.52 +  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), c_rarg0, r15_thread);
    1.53 +  popq(obj);
    1.54 +  if (tosca_live) popq(rax);
    1.55 +  bind(done);
    1.56 +}
    1.57 +
    1.58 +void MacroAssembler::g1_write_barrier_post(Register store_addr,
    1.59 +                                           Register new_val,
    1.60 +                                           Register tmp,
    1.61 +                                           Register tmp2) {
    1.62 +
    1.63 +  Address index(r15_thread, in_bytes(JavaThread::dirty_card_queue_offset() +
    1.64 +                                     PtrQueue::byte_offset_of_index()));
    1.65 +  Address buffer(r15_thread, in_bytes(JavaThread::dirty_card_queue_offset() +
    1.66 +                                     PtrQueue::byte_offset_of_buf()));
    1.67 +  BarrierSet* bs = Universe::heap()->barrier_set();
    1.68 +  CardTableModRefBS* ct = (CardTableModRefBS*)bs;
    1.69 +  Label done;
    1.70 +  Label runtime;
    1.71 +
    1.72 +  // Does store cross heap regions?
    1.73 +
    1.74 +  movq(tmp, store_addr);
    1.75 +  xorq(tmp, new_val);
    1.76 +  shrq(tmp, HeapRegion::LogOfHRGrainBytes);
    1.77 +  jcc(Assembler::equal, done);
    1.78 +
    1.79 +  // crosses regions, storing NULL?
    1.80 +
    1.81 +  cmpq(new_val, (int)NULL_WORD);
    1.82 +  jcc(Assembler::equal, done);
    1.83 +
    1.84 +  // storing region crossing non-NULL, is card already dirty?
    1.85 +  const Register card_addr = tmp;
    1.86 +
    1.87 +  movq(card_addr, store_addr);
    1.88 +  shrq(card_addr, CardTableModRefBS::card_shift);
    1.89 +
    1.90 +  ExternalAddress  cardtable((address) ct->byte_map_base);
    1.91 +  lea(tmp2, cardtable);
    1.92 +
    1.93 +  // get the address of the card
    1.94 +  addq(card_addr, tmp2);
    1.95 +
    1.96 +  assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
    1.97 +  cmpb(Address(card_addr, 0), 0);
    1.98 +  jcc(Assembler::equal, done);
    1.99 +
   1.100 +  // storing region crossing non-NULL, card is clean.
   1.101 +  // dirty card and log.
   1.102 +
   1.103 +  movb(Address(card_addr, 0), 0);
   1.104 +
   1.105 +  cmpl(index, 0);
   1.106 +  jcc(Assembler::equal, runtime);
   1.107 +  subl(index, wordSize);
   1.108 +  movq(tmp2, buffer);
   1.109 +  movslq(rscratch1, index);
   1.110 +  addq(tmp2, rscratch1);
   1.111 +  // log the card
   1.112 +  movq(Address(tmp2, 0), card_addr);
   1.113 +  jmp(done);
   1.114 +
   1.115 +  bind(runtime);
   1.116 +  // save live inputs
   1.117 +  pushq(store_addr);
   1.118 +  pushq(new_val);
   1.119 +  call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, r15_thread);
   1.120 +  popq(new_val);
   1.121 +  popq(store_addr);
   1.122 +
   1.123 +  bind(done);
   1.124 +
   1.125 +
   1.126 +}
   1.127 +
   1.128 +#endif // SERIALGC
   1.129 +/////////////////////////////////////////////////////////////////////////////
   1.130  
   1.131  // Calls to C land
   1.132  //
   1.133 @@ -4802,32 +4925,36 @@
   1.134                                     Label& slow_case) {
   1.135    assert(obj == rax, "obj must be in rax for cmpxchg");
   1.136    assert_different_registers(obj, var_size_in_bytes, t1);
   1.137 -  Register end = t1;
   1.138 -  Label retry;
   1.139 -  bind(retry);
   1.140 -  ExternalAddress heap_top((address) Universe::heap()->top_addr());
   1.141 -  movptr(obj, heap_top);
   1.142 -  if (var_size_in_bytes == noreg) {
   1.143 -    leaq(end, Address(obj, con_size_in_bytes));
   1.144 +  if (CMSIncrementalMode || !Universe::heap()->supports_inline_contig_alloc()) {
   1.145 +    jmp(slow_case);
   1.146    } else {
   1.147 -    leaq(end, Address(obj, var_size_in_bytes, Address::times_1));
   1.148 +    Register end = t1;
   1.149 +    Label retry;
   1.150 +    bind(retry);
   1.151 +    ExternalAddress heap_top((address) Universe::heap()->top_addr());
   1.152 +    movptr(obj, heap_top);
   1.153 +    if (var_size_in_bytes == noreg) {
   1.154 +      leaq(end, Address(obj, con_size_in_bytes));
   1.155 +    } else {
   1.156 +      leaq(end, Address(obj, var_size_in_bytes, Address::times_1));
   1.157 +    }
   1.158 +    // if end < obj then we wrapped around => object too long => slow case
   1.159 +    cmpq(end, obj);
   1.160 +    jcc(Assembler::below, slow_case);
   1.161 +    cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr()));
   1.162 +
   1.163 +    jcc(Assembler::above, slow_case);
   1.164 +    // Compare obj with the top addr, and if still equal, store the new
   1.165 +    // top addr in end at the address of the top addr pointer. Sets ZF
   1.166 +    // if was equal, and clears it otherwise. Use lock prefix for
   1.167 +    // atomicity on MPs.
   1.168 +    if (os::is_MP()) {
   1.169 +      lock();
   1.170 +    }
   1.171 +    cmpxchgptr(end, heap_top);
   1.172 +    // if someone beat us on the allocation, try again, otherwise continue
   1.173 +    jcc(Assembler::notEqual, retry);
   1.174    }
   1.175 -  // if end < obj then we wrapped around => object too long => slow case
   1.176 -  cmpq(end, obj);
   1.177 -  jcc(Assembler::below, slow_case);
   1.178 -  cmpptr(end, ExternalAddress((address) Universe::heap()->end_addr()));
   1.179 -
   1.180 -  jcc(Assembler::above, slow_case);
   1.181 -  // Compare obj with the top addr, and if still equal, store the new
   1.182 -  // top addr in end at the address of the top addr pointer. Sets ZF
   1.183 -  // if was equal, and clears it otherwise. Use lock prefix for
   1.184 -  // atomicity on MPs.
   1.185 -  if (os::is_MP()) {
   1.186 -    lock();
   1.187 -  }
   1.188 -  cmpxchgptr(end, heap_top);
   1.189 -  // if someone beat us on the allocation, try again, otherwise continue
   1.190 -  jcc(Assembler::notEqual, retry);
   1.191  }
   1.192  
   1.193  // Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.

mercurial