8242895: failed: sanity at src/hotspot/share/opto/escape.cpp:2361

The address_offset code in EA was improved to detect raw stores(init captured ones) after loopopt.

Reviewed-by: kvn, thartmann
This commit is contained in:
Jamsheed Mohammed C M 2020-07-21 08:03:20 -07:00
parent c7b074a9db
commit 39b22d134f
3 changed files with 113 additions and 15 deletions
src/hotspot/share/opto
test/hotspot/jtreg/compiler/escapeAnalysis

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -723,8 +723,7 @@ void ConnectionGraph::add_to_congraph_unsafe_access(Node* n, uint opcode, Unique
if (adr_type->isa_oopptr()
|| ((opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass)
&& adr_type == TypeRawPtr::NOTNULL
&& adr->in(AddPNode::Address)->is_Proj()
&& adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
&& is_captured_store_address(adr))) {
delayed_worklist->push(n); // Process it later.
#ifdef ASSERT
assert (adr->is_AddP(), "expecting an AddP");
@ -771,8 +770,7 @@ bool ConnectionGraph::add_final_edges_unsafe_access(Node* n, uint opcode) {
if (adr_type->isa_oopptr()
|| ((opcode == Op_StoreP || opcode == Op_StoreN || opcode == Op_StoreNKlass)
&& adr_type == TypeRawPtr::NOTNULL
&& adr->in(AddPNode::Address)->is_Proj()
&& adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
&& is_captured_store_address(adr))) {
// Point Address to Value
PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
assert(adr_ptn != NULL &&
@ -1584,8 +1582,7 @@ int ConnectionGraph::find_init_values(JavaObjectNode* pta, PointsToNode* init_va
// Raw pointers are used for initializing stores so skip it
// since it should be recorded already
Node* base = get_addp_base(field->ideal_node());
assert(adr_type->isa_rawptr() && base->is_Proj() &&
(base->in(0) == alloc),"unexpected pointer type");
assert(adr_type->isa_rawptr() && is_captured_store_address(field->ideal_node()), "unexpected pointer type");
#endif
continue;
}
@ -1916,8 +1913,7 @@ void ConnectionGraph::optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklis
Node *n = storestore_worklist.pop();
MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore();
Node *alloc = storestore->in(MemBarNode::Precedent)->in(0);
assert (alloc->is_Allocate(), "storestore should point to AllocateNode");
if (not_global_escape(alloc)) {
if (alloc->is_Allocate() && not_global_escape(alloc)) {
MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot);
mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory));
mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control));
@ -2251,11 +2247,29 @@ bool FieldNode::has_base(JavaObjectNode* jobj) const {
}
#endif
bool ConnectionGraph::is_captured_store_address(Node* addp) {
// Handle simple case first.
assert(_igvn->type(addp)->isa_oopptr() == NULL, "should be raw access");
if (addp->in(AddPNode::Address)->is_Proj() && addp->in(AddPNode::Address)->in(0)->is_Allocate()) {
return true;
} else if (addp->in(AddPNode::Address)->is_Phi()) {
for (DUIterator_Fast imax, i = addp->fast_outs(imax); i < imax; i++) {
Node* addp_use = addp->fast_out(i);
if (addp_use->is_Store()) {
for (DUIterator_Fast jmax, j = addp_use->fast_outs(jmax); j < jmax; j++) {
if (addp_use->fast_out(j)->is_Initialize()) {
return true;
}
}
}
}
}
return false;
}
int ConnectionGraph::address_offset(Node* adr, PhaseTransform *phase) {
const Type *adr_type = phase->type(adr);
if (adr->is_AddP() && adr_type->isa_oopptr() == NULL &&
adr->in(AddPNode::Address)->is_Proj() &&
adr->in(AddPNode::Address)->in(0)->is_Allocate()) {
if (adr->is_AddP() && adr_type->isa_oopptr() == NULL && is_captured_store_address(adr)) {
// We are computing a raw address for a store captured by an Initialize
// compute an appropriate address type. AddP cases #3 and #5 (see below).
int offs = (int)phase->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
@ -2358,7 +2372,7 @@ Node* ConnectionGraph::get_addp_base(Node *addp) {
assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
(uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
(uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
is_captured_store_address(addp), "sanity");
}
}
return base;
@ -2975,7 +2989,10 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist,
continue;
}
if (!n->is_CheckCastPP()) { // not unique CheckCastPP.
assert(!alloc->is_Allocate(), "allocation should have unique type");
// we could reach here for allocate case if one init is associated with many allocs.
if (alloc->is_Allocate()) {
alloc->as_Allocate()->_is_scalar_replaceable = false;
}
continue;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -512,6 +512,7 @@ private:
// offset of a field reference
int address_offset(Node* adr, PhaseTransform *phase);
bool is_captured_store_address(Node* addp);
// Propagate unique types created for unescaped allocated objects
// through the graph

@ -0,0 +1,80 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8242895
* @summary full loop unroll before EA creates phis between allocs projs and init
* @run main/othervm -Xbatch -XX:CompileCommand=dontinline,*DataA.m1 compiler.escapeAnalysis.TestIdealAllocShape
*/
package compiler.escapeAnalysis;
public class TestIdealAllocShape {
static volatile DataA f1;
static class DataA {
DataA f1;
DataA(DataA p1) {
this.f1 = p1;
}
public void m1() {}
}
public static DataA test1() {
DataA l1 = new DataA(null);
for (int i=0; i<2; i++) {
try {
return new DataA(l1); // l1 is a GlobalEscape. // control break.
} catch (Exception e) {
}
}
return null;
}
public static DataA test2() {
DataA l1 = new DataA(null);
for (int i=0; i<2; i++) {
try {
f1 = new DataA(l1); // l1 is a GlobalEscape.
break; // control break.
} catch (Exception e) {
}
}
synchronized(l1) { // elided sync
l1.m1();
}
return null;
}
public static void main(String argv[]) {
for (int i=0; i<20000; i++) {
TestIdealAllocShape.test1();
}
for (int i=0; i<20000; i++) {
TestIdealAllocShape.test2();
}
}
}