From 2750149dfd427c7db30c4e9c4ad7bdfbcae9a22f Mon Sep 17 00:00:00 2001 From: never Date: Wed, 27 Apr 2011 15:40:36 -0700 Subject: [PATCH] 7029167: add support for conditional card marks Reviewed-by: iveresov, kvn --- src/share/vm/opto/graphKit.cpp | 21 +++++++++++++++++++-- src/share/vm/opto/macro.cpp | 13 ++++++++++--- src/share/vm/runtime/globals.hpp | 3 +++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp index e1612b843..4df081990 100644 --- a/src/share/vm/opto/graphKit.cpp +++ b/src/share/vm/opto/graphKit.cpp @@ -3447,9 +3447,22 @@ void GraphKit::write_barrier_post(Node* oop_store, // Get the alias_index for raw card-mark memory int adr_type = Compile::AliasIdxRaw; - // Smash zero into card - Node* zero = __ ConI(0); + 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 if( !UseConcMarkSweepGC ) { __ store(__ ctrl(), card_adr, zero, bt, adr_type); } else { @@ -3457,6 +3470,10 @@ void GraphKit::write_barrier_post(Node* oop_store, __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type); } + if (UseCondCardMark) { + __ end_if(); + } + // Final sync IdealKit and GraphKit. final_sync(ideal); } diff --git a/src/share/vm/opto/macro.cpp b/src/share/vm/opto/macro.cpp index 465c8babd..a35f3342b 100644 --- a/src/share/vm/opto/macro.cpp +++ b/src/share/vm/opto/macro.cpp @@ -221,9 +221,16 @@ void PhaseMacroExpand::eliminate_card_mark(Node* p2x) { 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 diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index 96f0abbb0..eb5bec200 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -620,6 +620,9 @@ class CommandLineFlags { 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") \ \ -- GitLab