src/cpu/sparc/vm/assembler_sparc.cpp
Print this page
rev 2237 : [mq]: initial-intrinsification-changes
rev 2238 : [mq]: code-review-comments-vladimir
rev 2239 : [mq]: client_assertion_fauilure
@@ -4255,38 +4255,18 @@
}
///////////////////////////////////////////////////////////////////////////////////
#ifndef SERIALGC
-static uint num_stores = 0;
-static uint num_null_pre_stores = 0;
+static address satb_log_enqueue_with_frame = NULL;
+static u_char* satb_log_enqueue_with_frame_end = NULL;
-static void count_null_pre_vals(void* pre_val) {
- num_stores++;
- if (pre_val == NULL) num_null_pre_stores++;
- if ((num_stores % 1000000) == 0) {
- tty->print_cr(UINT32_FORMAT " stores, " UINT32_FORMAT " (%5.2f%%) with null pre-vals.",
- num_stores, num_null_pre_stores,
- 100.0*(float)num_null_pre_stores/(float)num_stores);
- }
-}
-
-static address satb_log_enqueue_with_frame = 0;
-static u_char* satb_log_enqueue_with_frame_end = 0;
-
-static address satb_log_enqueue_frameless = 0;
-static u_char* satb_log_enqueue_frameless_end = 0;
+static address satb_log_enqueue_frameless = NULL;
+static u_char* satb_log_enqueue_frameless_end = NULL;
static int EnqueueCodeSize = 128 DEBUG_ONLY( + 256); // Instructions?
-// The calls to this don't work. We'd need to do a fair amount of work to
-// make it work.
-static void check_index(int ind) {
- assert(0 <= ind && ind <= 64*K && ((ind % oopSize) == 0),
- "Invariants.");
-}
-
static void generate_satb_log_enqueue(bool with_frame) {
BufferBlob* bb = BufferBlob::create("enqueue_with_frame", EnqueueCodeSize);
CodeBuffer buf(bb);
MacroAssembler masm(&buf);
address start = masm.pc();
@@ -4386,17 +4366,31 @@
}
}
}
}
-void MacroAssembler::g1_write_barrier_pre(Register obj, Register index, int offset, Register tmp, bool preserve_o_regs) {
+void MacroAssembler::g1_write_barrier_pre(Register obj,
+ Register index,
+ int offset,
+ Register pre_val,
+ Register tmp,
+ bool preserve_o_regs) {
+ Label filtered;
+
+ if (obj == noreg) {
+ // We are not loading the previous value so make
+ // sure that we don't trash the value in pre_val
+ // with the code below.
+ assert_different_registers(pre_val, tmp);
+ } else {
+ // We will be loading the previous value
+ // in this code so...
assert(offset == 0 || index == noreg, "choose one");
+ assert(pre_val == noreg, "check this code");
+ }
- if (G1DisablePreBarrier) return;
- // satb_log_barrier(tmp, obj, offset, preserve_o_regs);
- Label filtered;
- // satb_log_barrier_work0(tmp, filtered);
+ // Is marking active?
if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
ld(G2,
in_bytes(JavaThread::satb_mark_queue_offset() +
PtrQueue::byte_offset_of_active()),
tmp);
@@ -4411,65 +4405,50 @@
// Check on whether to annul.
br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, tmp, filtered);
delayed() -> nop();
- // satb_log_barrier_work1(tmp, offset);
+ // Do we need to load the previous value?
+ if (obj != noreg) {
+ // Load the previous value...
if (index == noreg) {
if (Assembler::is_simm13(offset)) {
load_heap_oop(obj, offset, tmp);
} else {
set(offset, tmp);
load_heap_oop(obj, tmp, tmp);
}
} else {
load_heap_oop(obj, index, tmp);
}
-
- // satb_log_barrier_work2(obj, tmp, offset);
-
- // satb_log_barrier_work3(tmp, filtered, preserve_o_regs);
-
- const Register pre_val = tmp;
-
- if (G1SATBBarrierPrintNullPreVals) {
- save_frame(0);
- mov(pre_val, O0);
- // Save G-regs that target may use.
- mov(G1, L1);
- mov(G2, L2);
- mov(G3, L3);
- mov(G4, L4);
- mov(G5, L5);
- call(CAST_FROM_FN_PTR(address, &count_null_pre_vals));
- delayed()->nop();
- // Restore G-regs that target may have used.
- mov(L1, G1);
- mov(L2, G2);
- mov(L3, G3);
- mov(L4, G4);
- mov(L5, G5);
- restore(G0, G0, G0);
+ // Previous value has been loaded into tmp
+ pre_val = tmp;
}
+ assert(pre_val != noreg, "must have a real register");
+
+ // Is the previous value null?
// Check on whether to annul.
br_on_reg_cond(rc_z, /*annul*/false, Assembler::pt, pre_val, filtered);
delayed() -> nop();
// OK, it's not filtered, so we'll need to call enqueue. In the normal
- // case, pre_val will be a scratch G-reg, but there's some cases in which
- // it's an O-reg. In the first case, do a normal call. In the latter,
- // do a save here and call the frameless version.
+ // case, pre_val will be a scratch G-reg, but there are some cases in
+ // which it's an O-reg. In the first case, do a normal call. In the
+ // latter, do a save here and call the frameless version.
guarantee(pre_val->is_global() || pre_val->is_out(),
"Or we need to think harder.");
+
if (pre_val->is_global() && !preserve_o_regs) {
- generate_satb_log_enqueue_if_necessary(true); // with frame.
+ generate_satb_log_enqueue_if_necessary(true); // with frame
+
call(satb_log_enqueue_with_frame);
delayed()->mov(pre_val, O0);
} else {
- generate_satb_log_enqueue_if_necessary(false); // with frameless.
+ generate_satb_log_enqueue_if_necessary(false); // frameless
+
save_frame(0);
call(satb_log_enqueue_frameless);
delayed()->mov(pre_val->after_save(), O0);
restore();
}
@@ -4612,11 +4591,10 @@
Label filtered;
MacroAssembler* post_filter_masm = this;
if (new_val == G0) return;
- if (G1DisablePostBarrier) return;
G1SATBCardTableModRefBS* bs = (G1SATBCardTableModRefBS*) Universe::heap()->barrier_set();
assert(bs->kind() == BarrierSet::G1SATBCT ||
bs->kind() == BarrierSet::G1SATBCTLogging, "wrong barrier");
if (G1RSBarrierRegionFilter) {
@@ -4624,10 +4602,11 @@
#ifdef _LP64
srlx(tmp, HeapRegion::LogOfHRGrainBytes, tmp);
#else
srl(tmp, HeapRegion::LogOfHRGrainBytes, tmp);
#endif
+
if (G1PrintCTFilterStats) {
guarantee(tmp->is_global(), "Or stats won't work...");
// This is a sleazy hack: I'm temporarily hijacking G2, which I
// promise to restore.
mov(new_val, G2);