1.1 --- a/src/share/vm/opto/macro.cpp Wed Jul 15 13:37:35 2009 -0700 1.2 +++ b/src/share/vm/opto/macro.cpp Thu Jul 16 14:10:42 2009 -0700 1.3 @@ -198,14 +198,79 @@ 1.4 } 1.5 1.6 // Eliminate a card mark sequence. p2x is a ConvP2XNode 1.7 -void PhaseMacroExpand::eliminate_card_mark(Node *p2x) { 1.8 +void PhaseMacroExpand::eliminate_card_mark(Node* p2x) { 1.9 assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required"); 1.10 - Node *shift = p2x->unique_out(); 1.11 - Node *addp = shift->unique_out(); 1.12 - for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) { 1.13 - Node *st = addp->last_out(j); 1.14 - assert(st->is_Store(), "store required"); 1.15 - _igvn.replace_node(st, st->in(MemNode::Memory)); 1.16 + if (!UseG1GC) { 1.17 + // vanilla/CMS post barrier 1.18 + Node *shift = p2x->unique_out(); 1.19 + Node *addp = shift->unique_out(); 1.20 + for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) { 1.21 + Node *st = addp->last_out(j); 1.22 + assert(st->is_Store(), "store required"); 1.23 + _igvn.replace_node(st, st->in(MemNode::Memory)); 1.24 + } 1.25 + } else { 1.26 + // G1 pre/post barriers 1.27 + assert(p2x->outcnt() == 2, "expects 2 users: Xor and URShift nodes"); 1.28 + // It could be only one user, URShift node, in Object.clone() instrinsic 1.29 + // but the new allocation is passed to arraycopy stub and it could not 1.30 + // be scalar replaced. So we don't check the case. 1.31 + 1.32 + // Remove G1 post barrier. 1.33 + 1.34 + // Search for CastP2X->Xor->URShift->Cmp path which 1.35 + // checks if the store done to a different from the value's region. 1.36 + // And replace Cmp with #0 (false) to collapse G1 post barrier. 1.37 + Node* xorx = NULL; 1.38 + for (DUIterator_Fast imax, i = p2x->fast_outs(imax); i < imax; i++) { 1.39 + Node* u = p2x->fast_out(i); 1.40 + if (u->Opcode() == Op_XorX) { 1.41 + xorx = u; 1.42 + break; 1.43 + } 1.44 + } 1.45 + assert(xorx != NULL, "missing G1 post barrier"); 1.46 + Node* shift = xorx->unique_out(); 1.47 + Node* cmpx = shift->unique_out(); 1.48 + assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() && 1.49 + cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne, 1.50 + "missing region check in G1 post barrier"); 1.51 + _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); 1.52 + 1.53 + // Remove G1 pre barrier. 1.54 + 1.55 + // Search "if (marking != 0)" check and set it to "false". 1.56 + Node* this_region = p2x->in(0); 1.57 + assert(this_region != NULL, ""); 1.58 + // There is no G1 pre barrier if previous stored value is NULL 1.59 + // (for example, after initialization). 1.60 + if (this_region->is_Region() && this_region->req() == 3) { 1.61 + int ind = 1; 1.62 + if (!this_region->in(ind)->is_IfFalse()) { 1.63 + ind = 2; 1.64 + } 1.65 + if (this_region->in(ind)->is_IfFalse()) { 1.66 + Node* bol = this_region->in(ind)->in(0)->in(1); 1.67 + assert(bol->is_Bool(), ""); 1.68 + cmpx = bol->in(1); 1.69 + if (bol->as_Bool()->_test._test == BoolTest::ne && 1.70 + cmpx->is_Cmp() && cmpx->in(2) == intcon(0) && 1.71 + cmpx->in(1)->is_Load()) { 1.72 + Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address); 1.73 + const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + 1.74 + PtrQueue::byte_offset_of_active()); 1.75 + if (adr->is_AddP() && adr->in(AddPNode::Base) == top() && 1.76 + adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && 1.77 + adr->in(AddPNode::Offset) == MakeConX(marking_offset)) { 1.78 + _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); 1.79 + } 1.80 + } 1.81 + } 1.82 + } 1.83 + // Now CastP2X can be removed since it is used only on dead path 1.84 + // which currently still alive until igvn optimize it. 1.85 + assert(p2x->unique_out()->Opcode() == Op_URShiftX, ""); 1.86 + _igvn.replace_node(p2x, top()); 1.87 } 1.88 } 1.89 1.90 @@ -760,14 +825,11 @@ 1.91 if (n->is_Store()) { 1.92 _igvn.replace_node(n, n->in(MemNode::Memory)); 1.93 } else { 1.94 - assert( n->Opcode() == Op_CastP2X, "CastP2X required"); 1.95 eliminate_card_mark(n); 1.96 } 1.97 k -= (oc2 - use->outcnt()); 1.98 } 1.99 } else { 1.100 - assert( !use->is_SafePoint(), "safepoint uses must have been already elimiated"); 1.101 - assert( use->Opcode() == Op_CastP2X, "CastP2X required"); 1.102 eliminate_card_mark(use); 1.103 } 1.104 j -= (oc1 - res->outcnt());