1.1 --- a/src/share/vm/opto/compile.cpp Fri Feb 18 10:07:34 2011 -0800 1.2 +++ b/src/share/vm/opto/compile.cpp Tue Apr 05 19:14:03 2011 -0700 1.3 @@ -2050,6 +2050,52 @@ 1.4 // Note that OffsetBot and OffsetTop are very negative. 1.5 } 1.6 1.7 +// Eliminate trivially redundant StoreCMs and accumulate their 1.8 +// precedence edges. 1.9 +static void eliminate_redundant_card_marks(Node* n) { 1.10 + assert(n->Opcode() == Op_StoreCM, "expected StoreCM"); 1.11 + if (n->in(MemNode::Address)->outcnt() > 1) { 1.12 + // There are multiple users of the same address so it might be 1.13 + // possible to eliminate some of the StoreCMs 1.14 + Node* mem = n->in(MemNode::Memory); 1.15 + Node* adr = n->in(MemNode::Address); 1.16 + Node* val = n->in(MemNode::ValueIn); 1.17 + Node* prev = n; 1.18 + bool done = false; 1.19 + // Walk the chain of StoreCMs eliminating ones that match. As 1.20 + // long as it's a chain of single users then the optimization is 1.21 + // safe. Eliminating partially redundant StoreCMs would require 1.22 + // cloning copies down the other paths. 1.23 + while (mem->Opcode() == Op_StoreCM && mem->outcnt() == 1 && !done) { 1.24 + if (adr == mem->in(MemNode::Address) && 1.25 + val == mem->in(MemNode::ValueIn)) { 1.26 + // redundant StoreCM 1.27 + if (mem->req() > MemNode::OopStore) { 1.28 + // Hasn't been processed by this code yet. 1.29 + n->add_prec(mem->in(MemNode::OopStore)); 1.30 + } else { 1.31 + // Already converted to precedence edge 1.32 + for (uint i = mem->req(); i < mem->len(); i++) { 1.33 + // Accumulate any precedence edges 1.34 + if (mem->in(i) != NULL) { 1.35 + n->add_prec(mem->in(i)); 1.36 + } 1.37 + } 1.38 + // Everything above this point has been processed. 1.39 + done = true; 1.40 + } 1.41 + // Eliminate the previous StoreCM 1.42 + prev->set_req(MemNode::Memory, mem->in(MemNode::Memory)); 1.43 + assert(mem->outcnt() == 0, "should be dead"); 1.44 + mem->disconnect_inputs(NULL); 1.45 + } else { 1.46 + prev = mem; 1.47 + } 1.48 + mem = prev->in(MemNode::Memory); 1.49 + } 1.50 + } 1.51 +} 1.52 + 1.53 //------------------------------final_graph_reshaping_impl---------------------- 1.54 // Implement items 1-5 from final_graph_reshaping below. 1.55 static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { 1.56 @@ -2176,9 +2222,19 @@ 1.57 frc.inc_float_count(); 1.58 goto handle_mem; 1.59 1.60 + case Op_StoreCM: 1.61 + { 1.62 + // Convert OopStore dependence into precedence edge 1.63 + Node* prec = n->in(MemNode::OopStore); 1.64 + n->del_req(MemNode::OopStore); 1.65 + n->add_prec(prec); 1.66 + eliminate_redundant_card_marks(n); 1.67 + } 1.68 + 1.69 + // fall through 1.70 + 1.71 case Op_StoreB: 1.72 case Op_StoreC: 1.73 - case Op_StoreCM: 1.74 case Op_StorePConditional: 1.75 case Op_StoreI: 1.76 case Op_StoreL: