src/cpu/sparc/vm/assembler_sparc.cpp

changeset 2781
e1162778c1c8
parent 2639
8033953d67ff
child 2950
cba7b5c2d53f
     1.1 --- a/src/cpu/sparc/vm/assembler_sparc.cpp	Tue Apr 05 19:14:03 2011 -0700
     1.2 +++ b/src/cpu/sparc/vm/assembler_sparc.cpp	Thu Apr 07 09:53:20 2011 -0700
     1.3 @@ -4257,34 +4257,14 @@
     1.4  ///////////////////////////////////////////////////////////////////////////////////
     1.5  #ifndef SERIALGC
     1.6  
     1.7 -static uint num_stores = 0;
     1.8 -static uint num_null_pre_stores = 0;
     1.9 -
    1.10 -static void count_null_pre_vals(void* pre_val) {
    1.11 -  num_stores++;
    1.12 -  if (pre_val == NULL) num_null_pre_stores++;
    1.13 -  if ((num_stores % 1000000) == 0) {
    1.14 -    tty->print_cr(UINT32_FORMAT " stores, " UINT32_FORMAT " (%5.2f%%) with null pre-vals.",
    1.15 -                  num_stores, num_null_pre_stores,
    1.16 -                  100.0*(float)num_null_pre_stores/(float)num_stores);
    1.17 -  }
    1.18 -}
    1.19 -
    1.20 -static address satb_log_enqueue_with_frame = 0;
    1.21 -static u_char* satb_log_enqueue_with_frame_end = 0;
    1.22 -
    1.23 -static address satb_log_enqueue_frameless = 0;
    1.24 -static u_char* satb_log_enqueue_frameless_end = 0;
    1.25 +static address satb_log_enqueue_with_frame = NULL;
    1.26 +static u_char* satb_log_enqueue_with_frame_end = NULL;
    1.27 +
    1.28 +static address satb_log_enqueue_frameless = NULL;
    1.29 +static u_char* satb_log_enqueue_frameless_end = NULL;
    1.30  
    1.31  static int EnqueueCodeSize = 128 DEBUG_ONLY( + 256); // Instructions?
    1.32  
    1.33 -// The calls to this don't work.  We'd need to do a fair amount of work to
    1.34 -// make it work.
    1.35 -static void check_index(int ind) {
    1.36 -  assert(0 <= ind && ind <= 64*K && ((ind % oopSize) == 0),
    1.37 -         "Invariants.");
    1.38 -}
    1.39 -
    1.40  static void generate_satb_log_enqueue(bool with_frame) {
    1.41    BufferBlob* bb = BufferBlob::create("enqueue_with_frame", EnqueueCodeSize);
    1.42    CodeBuffer buf(bb);
    1.43 @@ -4388,13 +4368,27 @@
    1.44    }
    1.45  }
    1.46  
    1.47 -void MacroAssembler::g1_write_barrier_pre(Register obj, Register index, int offset, Register tmp, bool preserve_o_regs) {
    1.48 -  assert(offset == 0 || index == noreg, "choose one");
    1.49 -
    1.50 -  if (G1DisablePreBarrier) return;
    1.51 -  // satb_log_barrier(tmp, obj, offset, preserve_o_regs);
    1.52 +void MacroAssembler::g1_write_barrier_pre(Register obj,
    1.53 +                                          Register index,
    1.54 +                                          int offset,
    1.55 +                                          Register pre_val,
    1.56 +                                          Register tmp,
    1.57 +                                          bool preserve_o_regs) {
    1.58    Label filtered;
    1.59 -  // satb_log_barrier_work0(tmp, filtered);
    1.60 +
    1.61 +  if (obj == noreg) {
    1.62 +    // We are not loading the previous value so make
    1.63 +    // sure that we don't trash the value in pre_val
    1.64 +    // with the code below.
    1.65 +    assert_different_registers(pre_val, tmp);
    1.66 +  } else {
    1.67 +    // We will be loading the previous value
    1.68 +    // in this code so...
    1.69 +    assert(offset == 0 || index == noreg, "choose one");
    1.70 +    assert(pre_val == noreg, "check this code");
    1.71 +  }
    1.72 +
    1.73 +  // Is marking active?
    1.74    if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
    1.75      ld(G2,
    1.76         in_bytes(JavaThread::satb_mark_queue_offset() +
    1.77 @@ -4413,61 +4407,46 @@
    1.78    br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, tmp, filtered);
    1.79    delayed() -> nop();
    1.80  
    1.81 -  // satb_log_barrier_work1(tmp, offset);
    1.82 -  if (index == noreg) {
    1.83 -    if (Assembler::is_simm13(offset)) {
    1.84 -      load_heap_oop(obj, offset, tmp);
    1.85 +  // Do we need to load the previous value?
    1.86 +  if (obj != noreg) {
    1.87 +    // Load the previous value...
    1.88 +    if (index == noreg) {
    1.89 +      if (Assembler::is_simm13(offset)) {
    1.90 +        load_heap_oop(obj, offset, tmp);
    1.91 +      } else {
    1.92 +        set(offset, tmp);
    1.93 +        load_heap_oop(obj, tmp, tmp);
    1.94 +      }
    1.95      } else {
    1.96 -      set(offset, tmp);
    1.97 -      load_heap_oop(obj, tmp, tmp);
    1.98 +      load_heap_oop(obj, index, tmp);
    1.99      }
   1.100 -  } else {
   1.101 -    load_heap_oop(obj, index, tmp);
   1.102 +    // Previous value has been loaded into tmp
   1.103 +    pre_val = tmp;
   1.104    }
   1.105  
   1.106 -  // satb_log_barrier_work2(obj, tmp, offset);
   1.107 -
   1.108 -  // satb_log_barrier_work3(tmp, filtered, preserve_o_regs);
   1.109 -
   1.110 -  const Register pre_val = tmp;
   1.111 -
   1.112 -  if (G1SATBBarrierPrintNullPreVals) {
   1.113 -    save_frame(0);
   1.114 -    mov(pre_val, O0);
   1.115 -    // Save G-regs that target may use.
   1.116 -    mov(G1, L1);
   1.117 -    mov(G2, L2);
   1.118 -    mov(G3, L3);
   1.119 -    mov(G4, L4);
   1.120 -    mov(G5, L5);
   1.121 -    call(CAST_FROM_FN_PTR(address, &count_null_pre_vals));
   1.122 -    delayed()->nop();
   1.123 -    // Restore G-regs that target may have used.
   1.124 -    mov(L1, G1);
   1.125 -    mov(L2, G2);
   1.126 -    mov(L3, G3);
   1.127 -    mov(L4, G4);
   1.128 -    mov(L5, G5);
   1.129 -    restore(G0, G0, G0);
   1.130 -  }
   1.131 -
   1.132 +  assert(pre_val != noreg, "must have a real register");
   1.133 +
   1.134 +  // Is the previous value null?
   1.135    // Check on whether to annul.
   1.136    br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, pre_val, filtered);
   1.137    delayed() -> nop();
   1.138  
   1.139    // OK, it's not filtered, so we'll need to call enqueue.  In the normal
   1.140 -  // case, pre_val will be a scratch G-reg, but there's some cases in which
   1.141 -  // it's an O-reg.  In the first case, do a normal call.  In the latter,
   1.142 -  // do a save here and call the frameless version.
   1.143 +  // case, pre_val will be a scratch G-reg, but there are some cases in
   1.144 +  // which it's an O-reg.  In the first case, do a normal call.  In the
   1.145 +  // latter, do a save here and call the frameless version.
   1.146  
   1.147    guarantee(pre_val->is_global() || pre_val->is_out(),
   1.148              "Or we need to think harder.");
   1.149 +
   1.150    if (pre_val->is_global() && !preserve_o_regs) {
   1.151 -    generate_satb_log_enqueue_if_necessary(true); // with frame.
   1.152 +    generate_satb_log_enqueue_if_necessary(true); // with frame
   1.153 +
   1.154      call(satb_log_enqueue_with_frame);
   1.155      delayed()->mov(pre_val, O0);
   1.156    } else {
   1.157 -    generate_satb_log_enqueue_if_necessary(false); // with frameless.
   1.158 +    generate_satb_log_enqueue_if_necessary(false); // frameless
   1.159 +
   1.160      save_frame(0);
   1.161      call(satb_log_enqueue_frameless);
   1.162      delayed()->mov(pre_val->after_save(), O0);
   1.163 @@ -4614,7 +4593,6 @@
   1.164    MacroAssembler* post_filter_masm = this;
   1.165  
   1.166    if (new_val == G0) return;
   1.167 -  if (G1DisablePostBarrier) return;
   1.168  
   1.169    G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set();
   1.170    assert(bs->kind() == BarrierSet::G1SATBCT ||
   1.171 @@ -4626,6 +4604,7 @@
   1.172  #else
   1.173      srl(tmp, HeapRegion::LogOfHRGrainBytes, tmp);
   1.174  #endif
   1.175 +
   1.176      if (G1PrintCTFilterStats) {
   1.177        guarantee(tmp->is_global(), "Or stats won't work...");
   1.178        // This is a sleazy hack: I'm temporarily hijacking G2, which I

mercurial