--- old/src/share/vm/opto/macro.cpp 2017-04-25 16:45:34.731173112 +0200 +++ new/src/share/vm/opto/macro.cpp 2017-04-25 16:45:34.587173117 +0200 @@ -224,104 +224,9 @@ } // Eliminate a card mark sequence. p2x is a ConvP2XNode -void PhaseMacroExpand::eliminate_card_mark(Node* p2x) { - assert(p2x->Opcode() == Op_CastP2X, "ConvP2XNode required"); - if (!UseG1GC) { - // vanilla/CMS post barrier - Node *shift = p2x->unique_out(); - Node *addp = shift->unique_out(); - for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) { - 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 - assert(p2x->outcnt() <= 2, "expects 1 or 2 users: Xor and URShift nodes"); - // It could be only one user, URShift node, in Object.clone() intrinsic - // but the new allocation is passed to arraycopy stub and it could not - // be scalar replaced. So we don't check the case. - - // An other case of only one user (Xor) is when the value check for NULL - // in G1 post barrier is folded after CCP so the code which used URShift - // is removed. - - // Take Region node before eliminating post barrier since it also - // eliminates CastP2X node when it has only one user. - Node* this_region = p2x->in(0); - assert(this_region != NULL, ""); - - // Remove G1 post barrier. - - // Search for CastP2X->Xor->URShift->Cmp path which - // checks if the store done to a different from the value's region. - // And replace Cmp with #0 (false) to collapse G1 post barrier. - Node* xorx = p2x->find_out_with(Op_XorX); - if (xorx != NULL) { - Node* shift = xorx->unique_out(); - Node* cmpx = shift->unique_out(); - assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() && - cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne, - "missing region check in G1 post barrier"); - _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); - - // Remove G1 pre barrier. - - // Search "if (marking != 0)" check and set it to "false". - // There is no G1 pre barrier if previous stored value is NULL - // (for example, after initialization). - if (this_region->is_Region() && this_region->req() == 3) { - int ind = 1; - if (!this_region->in(ind)->is_IfFalse()) { - ind = 2; - } - if (this_region->in(ind)->is_IfFalse()) { - Node* bol = this_region->in(ind)->in(0)->in(1); - assert(bol->is_Bool(), ""); - cmpx = bol->in(1); - if (bol->as_Bool()->_test._test == BoolTest::ne && - cmpx->is_Cmp() && cmpx->in(2) == intcon(0) && - cmpx->in(1)->is_Load()) { - Node* adr = cmpx->in(1)->as_Load()->in(MemNode::Address); - const int marking_offset = in_bytes(JavaThread::satb_mark_queue_offset() + - SATBMarkQueue::byte_offset_of_active()); - if (adr->is_AddP() && adr->in(AddPNode::Base) == top() && - adr->in(AddPNode::Address)->Opcode() == Op_ThreadLocal && - adr->in(AddPNode::Offset) == MakeConX(marking_offset)) { - _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); - } - } - } - } - } else { - assert(!GraphKit::use_ReduceInitialCardMarks(), "can only happen with card marking"); - // This is a G1 post barrier emitted by the Object.clone() intrinsic. - // Search for the CastP2X->URShiftX->AddP->LoadB->Cmp path which checks if the card - // is marked as young_gen and replace the Cmp with 0 (false) to collapse the barrier. - Node* shift = p2x->find_out_with(Op_URShiftX); - assert(shift != NULL, "missing G1 post barrier"); - Node* addp = shift->unique_out(); - Node* load = addp->find_out_with(Op_LoadB); - assert(load != NULL, "missing G1 post barrier"); - Node* cmpx = load->unique_out(); - assert(cmpx->is_Cmp() && cmpx->unique_out()->is_Bool() && - cmpx->unique_out()->as_Bool()->_test._test == BoolTest::ne, - "missing card value check in G1 post barrier"); - _igvn.replace_node(cmpx, makecon(TypeInt::CC_EQ)); - // There is no G1 pre barrier in this case - } - // Now CastP2X can be removed since it is used only on dead path - // which currently still alive until igvn optimize it. - assert(p2x->outcnt() == 0 || p2x->unique_out()->Opcode() == Op_URShiftX, ""); - _igvn.replace_node(p2x, top()); - } +void PhaseMacroExpand::eliminate_gc_barrier(Node* p2x) { + C2BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->c2_code_gen(); + code_gen->eliminate_gc_barrier(this, p2x); } // Search for a memory operation for the specified memory slice. @@ -1022,7 +927,7 @@ disconnect_projections(membar_after->as_MemBar(), _igvn); } } else { - eliminate_card_mark(n); + eliminate_gc_barrier(n); } k -= (oc2 - use->outcnt()); } @@ -1053,7 +958,7 @@ _igvn._worklist.push(ac); } else { - eliminate_card_mark(use); + eliminate_gc_barrier(use); } j -= (oc1 - res->outcnt()); }