--- a/hotspot/src/share/vm/opto/graphKit.cpp Tue Apr 26 12:14:22 2011 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Apr 27 15:40:36 2011 -0700
@@ -3447,9 +3447,22 @@
// Get the alias_index for raw card-mark memory
int adr_type = Compile::AliasIdxRaw;
+ Node* zero = __ ConI(0); // Dirty card value
+ BasicType bt = T_BYTE;
+
+ if (UseCondCardMark) {
+ // The classic GC reference write barrier is typically implemented
+ // as a store into the global card mark table. Unfortunately
+ // unconditional stores can result in false sharing and excessive
+ // coherence traffic as well as false transactional aborts.
+ // UseCondCardMark enables MP "polite" conditional card mark
+ // stores. In theory we could relax the load from ctrl() to
+ // no_ctrl, but that doesn't buy much latitude.
+ Node* card_val = __ load( __ ctrl(), card_adr, TypeInt::BYTE, bt, adr_type);
+ __ if_then(card_val, BoolTest::ne, zero);
+ }
+
// Smash zero into card
- Node* zero = __ ConI(0);
- BasicType bt = T_BYTE;
if( !UseConcMarkSweepGC ) {
__ store(__ ctrl(), card_adr, zero, bt, adr_type);
} else {
@@ -3457,6 +3470,10 @@
__ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type);
}
+ if (UseCondCardMark) {
+ __ end_if();
+ }
+
// Final sync IdealKit and GraphKit.
final_sync(ideal);
}
--- a/hotspot/src/share/vm/opto/macro.cpp Tue Apr 26 12:14:22 2011 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp Wed Apr 27 15:40:36 2011 -0700
@@ -221,9 +221,16 @@
Node *shift = p2x->unique_out();
Node *addp = shift->unique_out();
for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) {
- Node *st = addp->last_out(j);
- assert(st->is_Store(), "store required");
- _igvn.replace_node(st, st->in(MemNode::Memory));
+ Node *mem = addp->last_out(j);
+ if (UseCondCardMark && mem->is_Load()) {
+ assert(mem->Opcode() == Op_LoadB, "unexpected code shape");
+ // The load is checking if the card has been written so
+ // replace it with zero to fold the test.
+ _igvn.replace_node(mem, intcon(0));
+ continue;
+ }
+ assert(mem->is_Store(), "store required");
+ _igvn.replace_node(mem, mem->in(MemNode::Memory));
}
} else {
// G1 pre/post barriers
--- a/hotspot/src/share/vm/runtime/globals.hpp Tue Apr 26 12:14:22 2011 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Apr 27 15:40:36 2011 -0700
@@ -620,6 +620,9 @@
product(bool, UseSSE42Intrinsics, false, \
"SSE4.2 versions of intrinsics") \
\
+ product(bool, UseCondCardMark, false, \
+ "Check for already marked card before updating card table") \
+ \
develop(bool, TraceCallFixup, false, \
"traces all call fixups") \
\