+{"files":[{"patch":"@@ -1553,1 +1553,0 @@\n- init_req( ValidLengthTest , topnode);\n@@ -1580,0 +1579,48 @@\n+\/\/=============================================================================\n+Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) {\n+ if (remove_dead_region(phase, can_reshape)) return this;\n+ \/\/ Don't bother trying to transform a dead node\n+ if (in(0) && in(0)->is_top()) return NULL;\n+\n+ const Type* type = phase->type(Ideal_length());\n+ if (type->isa_int() && type->is_int()->_hi < 0) {\n+ if (can_reshape) {\n+ PhaseIterGVN *igvn = phase->is_IterGVN();\n+ \/\/ Unreachable fall through path (negative array length),\n+ \/\/ the allocation can only throw so disconnect it.\n+ Node* proj = proj_out_or_null(TypeFunc::Control);\n+ Node* catchproj = NULL;\n+ if (proj != NULL) {\n+ for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) {\n+ Node *cn = proj->fast_out(i);\n+ if (cn->is_Catch()) {\n+ catchproj = cn->as_Multi()->proj_out_or_null(CatchProjNode::fall_through_index);\n+ break;\n+ }\n+ }\n+ }\n+ if (catchproj != NULL && catchproj->outcnt() > 0 &&\n+ (catchproj->outcnt() > 1 ||\n+ catchproj->unique_out()->Opcode() != Op_Halt)) {\n+ assert(catchproj->is_CatchProj(), \"must be a CatchProjNode\");\n+ Node* nproj = catchproj->clone();\n+ igvn->register_new_node_with_optimizer(nproj);\n+\n+ Node *frame = new ParmNode( phase->C->start(), TypeFunc::FramePtr );\n+ frame = phase->transform(frame);\n+ \/\/ Halt & Catch Fire\n+ Node* halt = new HaltNode(nproj, frame, \"unexpected negative array length\");\n+ phase->C->root()->add_req(halt);\n+ phase->transform(halt);\n+\n+ igvn->replace_node(catchproj, phase->C->top());\n+ return this;\n+ }\n+ } else {\n+ \/\/ Can't correct it during regular GVN so register for IGVN\n+ phase->C->record_for_igvn(this);\n+ }\n+ }\n+ return NULL;\n+}\n+\n","filename":"src\/hotspot\/share\/opto\/callnode.cpp","additions":48,"deletions":1,"binary":false,"changes":49,"status":"modified"},{"patch":"@@ -877,1 +877,0 @@\n- ValidLengthTest,\n@@ -887,1 +886,0 @@\n- fields[ValidLengthTest] = TypeInt::BOOL;\n@@ -982,2 +980,4 @@\n- AllocateArrayNode(Compile* C, const TypeFunc* atype, Node* ctrl, Node* mem, Node* abio, Node* size, Node* klass_node,\n- Node* initial_test, Node* count_val, Node* valid_length_test)\n+ AllocateArrayNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio,\n+ Node* size, Node* klass_node, Node* initial_test,\n+ Node* count_val\n+ )\n@@ -989,1 +989,0 @@\n- set_req(AllocateNode::ValidLengthTest, valid_length_test);\n@@ -992,0 +991,1 @@\n+ virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);\n","filename":"src\/hotspot\/share\/opto\/callnode.hpp","additions":5,"deletions":5,"binary":false,"changes":10,"status":"modified"},{"patch":"@@ -2732,11 +2732,0 @@\n- } else if (call->is_AllocateArray()) {\n- Node* klass_node = call->in(AllocateNode::KlassNode);\n- Node* length = call->in(AllocateNode::ALength);\n- const Type* length_type = phase->type(length);\n- const Type* klass_type = phase->type(klass_node);\n- Node* valid_length_test = call->in(AllocateNode::ValidLengthTest);\n- const Type* valid_length_test_t = phase->type(valid_length_test);\n- if (length_type == Type::TOP || klass_type == Type::TOP || valid_length_test_t == Type::TOP ||\n- valid_length_test_t->is_int()->is_con(0)) {\n- f[CatchProjNode::fall_through_index] = Type::TOP;\n- }\n","filename":"src\/hotspot\/share\/opto\/cfgnode.cpp","additions":0,"deletions":11,"binary":false,"changes":11,"status":"modified"},{"patch":"@@ -3888,1 +3888,1 @@\n- CallNode* call = n->in(0)->in(0)->as_Call();\n+ CallNode *call = n->in(0)->in(0)->as_Call();\n@@ -3897,1 +3897,1 @@\n- Node* arg0 = call->in(TypeFunc::Parms);\n+ Node *arg0 = call->in(TypeFunc::Parms);\n@@ -3902,3 +3902,4 @@\n- } else if (call->entry_point() == OptoRuntime::new_array_Java() ||\n- call->entry_point() == OptoRuntime::new_array_nozero_Java()) {\n- \/\/ Check for illegal array length. In such case, the optimizer has\n+ } else if (call->entry_point() == OptoRuntime::new_array_Java() &&\n+ call->req() > TypeFunc::Parms+1 &&\n+ call->is_CallStaticJava()) {\n+ \/\/ Check for negative array length. In such case, the optimizer has\n@@ -3907,5 +3908,3 @@\n- assert(call->is_CallStaticJava(), \"static call expected\");\n- assert(call->req() == call->jvms()->endoff() + 1, \"missing extra input\");\n- Node* valid_length_test = call->in(call->req()-1);\n- call->del_req(call->req()-1);\n- if (valid_length_test->find_int_con(1) == 0) {\n+ Node *arg1 = call->in(TypeFunc::Parms+1);\n+ if (arg1->is_Type() &&\n+ arg1->as_Type()->type()->join(TypeInt::POS)->empty()) {\n@@ -3914,2 +3913,0 @@\n- assert(n->outcnt() == required_outcnt, \"malformed control flow\");\n- continue;\n@@ -3924,8 +3921,0 @@\n- } else if (n->is_PCTable() && n->in(0) && n->in(0)->in(0) && n->in(0)->in(0)->is_Call()) {\n- CallNode* call = n->in(0)->in(0)->as_Call();\n- if (call->entry_point() == OptoRuntime::new_array_Java() ||\n- call->entry_point() == OptoRuntime::new_array_nozero_Java()) {\n- assert(call->is_CallStaticJava(), \"static call expected\");\n- assert(call->req() == call->jvms()->endoff() + 1, \"missing extra input\");\n- call->del_req(call->req()-1); \/\/ valid length test useless now\n- }\n","filename":"src\/hotspot\/share\/opto\/compile.cpp","additions":9,"deletions":20,"binary":false,"changes":29,"status":"modified"},{"patch":"@@ -2603,3 +2603,1 @@\n- Node* norm = new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci);\n- _gvn.set_type_bottom(norm);\n- C->record_for_igvn(norm);\n+ Node* norm = _gvn.transform( new CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) );\n@@ -3856,9 +3854,0 @@\n- const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();\n- Node* valid_length_test = _gvn.intcon(1);\n- if (ary_type->isa_aryptr()) {\n- BasicType bt = ary_type->isa_aryptr()->elem()->array_element_basic_type();\n- jint max = TypeAryPtr::max_array_length(bt);\n- Node* valid_length_cmp = _gvn.transform(new CmpUNode(length, intcon(max)));\n- valid_length_test = _gvn.transform(new BoolNode(valid_length_cmp, BoolTest::le));\n- }\n-\n@@ -3871,1 +3860,1 @@\n- length, valid_length_test);\n+ length);\n@@ -3878,0 +3867,1 @@\n+ const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type();\n","filename":"src\/hotspot\/share\/opto\/graphKit.cpp","additions":3,"deletions":13,"binary":false,"changes":16,"status":"modified"},{"patch":"@@ -1212,2 +1212,1 @@\n- address slow_call_address, \/\/ Address of slow call\n- Node* valid_length_test \/\/ whether length is valid or not\n+ address slow_call_address \/\/ Address of slow call\n@@ -1398,6 +1397,0 @@\n- \/\/ For array allocations, copy the valid length check to the call node so Compile::final_graph_reshaping() can verify\n- \/\/ that the call has the expected number of CatchProj nodes (in case the allocation always fails and the fallthrough\n- \/\/ path dies).\n- if (valid_length_test != NULL) {\n- call->add_req(valid_length_test);\n- }\n@@ -1890,1 +1883,1 @@\n- OptoRuntime::new_instance_Java(), NULL);\n+ OptoRuntime::new_instance_Java());\n@@ -1895,1 +1888,0 @@\n- Node* valid_length_test = alloc->in(AllocateNode::ValidLengthTest);\n@@ -1910,1 +1902,1 @@\n- slow_call_address, valid_length_test);\n+ slow_call_address);\n","filename":"src\/hotspot\/share\/opto\/macro.cpp","additions":3,"deletions":11,"binary":false,"changes":14,"status":"modified"},{"patch":"@@ -95,2 +95,2 @@\n- address slow_call_address,\n- Node* valid_length_test);\n+ address slow_call_address);\n+ void yank_initalize_node(InitializeNode* node);\n","filename":"src\/hotspot\/share\/opto\/macro.hpp","additions":2,"deletions":2,"binary":false,"changes":4,"status":"modified"},{"patch":"@@ -131,2 +131,2 @@\n- assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1 || use->is_AllocateArray(), \"unexpected node type\");\n- Node *use_c = (use->is_If() || use->is_AllocateArray()) ? use->in(0) : get_ctrl(use);\n+ assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, \"unexpected node type\");\n+ Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use);\n@@ -169,3 +169,2 @@\n- assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1 || u->is_AllocateArray(), \"unexpected node type\");\n- assert(u->is_AllocateArray() || u->in(1) == bol, \"\");\n- assert(!u->is_AllocateArray() || u->in(AllocateNode::ValidLengthTest) == bol, \"wrong input to AllocateArray\");\n+ assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, \"unexpected node type\");\n+ assert(u->in(1) == bol, \"\");\n@@ -173,1 +172,1 @@\n- Node *u_ctrl = (u->is_If() || u->is_AllocateArray()) ? u->in(0) : get_ctrl(u);\n+ Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u);\n@@ -177,1 +176,1 @@\n- _igvn.replace_input_of(u, u->is_AllocateArray() ? AllocateNode::ValidLengthTest : 1, x);\n+ _igvn.replace_input_of(u, 1, x);\n","filename":"src\/hotspot\/share\/opto\/split_if.cpp","additions":6,"deletions":7,"binary":false,"changes":13,"status":"modified"},{"patch":"@@ -1,52 +0,0 @@\n-\/*\n- * Copyright (c) 2022, Red Hat, Inc. All rights reserved.\n- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n- *\n- * This code is free software; you can redistribute it and\/or modify it\n- * under the terms of the GNU General Public License version 2 only, as\n- * published by the Free Software Foundation.\n- *\n- * This code is distributed in the hope that it will be useful, but WITHOUT\n- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n- * version 2 for more details (a copy is included in the LICENSE file that\n- * accompanied this code).\n- *\n- * You should have received a copy of the GNU General Public License version\n- * 2 along with this work; if not, write to the Free Software Foundation,\n- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n- *\n- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n- * or visit www.oracle.com if you need additional information or have any\n- * questions.\n- *\/\n-\n-\/**\n- * @test\n- * @bug 8279125\n- * @summary fatal error: no reachable node should have no use\n- * @requires vm.flavor == \"server\"\n- *\n- * @run main\/othervm -XX:-BackgroundCompilation -XX:-DoEscapeAnalysis TestAllocArrayAfterAllocNoUse\n- *\n- *\/\n-\n-public class TestAllocArrayAfterAllocNoUse {\n- private static Object field;\n-\n- public static void main(String[] args) {\n- for (int i = 0; i < 20_000; i++) {\n- test();\n- }\n- }\n-\n- private static void test() {\n- try {\n- final TestAllocArrayAfterAllocNoUse o = new TestAllocArrayAfterAllocNoUse();\n- } catch (Exception e) {\n- final int[] array = new int[100];\n- field = array;\n- }\n-\n- }\n-}\n","filename":"test\/hotspot\/jtreg\/compiler\/allocation\/TestAllocArrayAfterAllocNoUse.java","additions":0,"deletions":52,"binary":false,"changes":52,"status":"deleted"},{"patch":"@@ -1,53 +0,0 @@\n-\/*\n- * Copyright (c) 2022, Red Hat, Inc. All rights reserved.\n- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n- *\n- * This code is free software; you can redistribute it and\/or modify it\n- * under the terms of the GNU General Public License version 2 only, as\n- * published by the Free Software Foundation.\n- *\n- * This code is distributed in the hope that it will be useful, but WITHOUT\n- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n- * version 2 for more details (a copy is included in the LICENSE file that\n- * accompanied this code).\n- *\n- * You should have received a copy of the GNU General Public License version\n- * 2 along with this work; if not, write to the Free Software Foundation,\n- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n- *\n- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n- * or visit www.oracle.com if you need additional information or have any\n- * questions.\n- *\/\n-\n-\/**\n- * @test\n- * @bug 8279062\n- * @summary C2: assert(t->meet(t0) == t) failed: Not monotonic after JDK-8278413\n- *\n- * @run main\/othervm -XX:-BackgroundCompilation TestCCPAllocateArray\n- *\n- *\/\n-\n-public class TestCCPAllocateArray {\n- public static void main(String[] args) {\n- for (int i = 0; i < 20_000; i++) {\n- try {\n- test();\n- } catch (OutOfMemoryError e) {\n- }\n- length(42);\n- }\n- }\n-\n- private static int[] test() {\n- int i = 2;\n- for (; i < 4; i *= 2);\n- return new int[length(i)];\n- }\n-\n- private static int length(int i) {\n- return i == 4 ? Integer.MAX_VALUE : 0;\n- }\n-}\n","filename":"test\/hotspot\/jtreg\/compiler\/allocation\/TestCCPAllocateArray.java","additions":0,"deletions":53,"binary":false,"changes":53,"status":"deleted"},{"patch":"@@ -1,80 +0,0 @@\n-\/*\n- * Copyright (c) 2022, Red Hat, Inc. All rights reserved.\n- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n- *\n- * This code is free software; you can redistribute it and\/or modify it\n- * under the terms of the GNU General Public License version 2 only, as\n- * published by the Free Software Foundation.\n- *\n- * This code is distributed in the hope that it will be useful, but WITHOUT\n- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n- * version 2 for more details (a copy is included in the LICENSE file that\n- * accompanied this code).\n- *\n- * You should have received a copy of the GNU General Public License version\n- * 2 along with this work; if not, write to the Free Software Foundation,\n- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n- *\n- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n- * or visit www.oracle.com if you need additional information or have any\n- * questions.\n- *\/\n-\n-\/*\n- * @test\n- * bug 8279219\n- * @summary C2 crash when allocating array of size too large\n- * @requires vm.compiler2.enabled\n- * @library \/test\/lib \/\n- * @build sun.hotspot.WhiteBox\n- * @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox\n- * @run main\/othervm -ea -Xbootclasspath\/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:-BackgroundCompilation TestFailedAllocationBadGraph\n- *\/\n-\n-import sun.hotspot.WhiteBox;\n-import java.lang.reflect.Method;\n-import compiler.whitebox.CompilerWhiteBoxTest;\n-\n-public class TestFailedAllocationBadGraph {\n- private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();\n-\n- private static long[] array;\n- private static int field;\n- private static volatile int barrier;\n-\n- public static void main(String[] args) throws Exception {\n- run(\"test1\");\n- run(\"test2\");\n- }\n-\n- private static void run(String method) throws Exception {\n- Method m = TestFailedAllocationBadGraph.class.getDeclaredMethod(method);\n- WHITE_BOX.enqueueMethodForCompilation(m, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION);\n- if (!WHITE_BOX.isMethodCompiled(m) || WHITE_BOX.getMethodCompilationLevel(m) != CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION) {\n- throw new RuntimeException(\"should still be compiled\");\n- }\n- }\n-\n- private static int test1() {\n- int length = Integer.MAX_VALUE;\n- try {\n- array = new long[length];\n- } catch (OutOfMemoryError outOfMemoryError) {\n- barrier = 0x42;\n- length = field;\n- }\n- return length;\n- }\n-\n- private static int test2() {\n- int length = -1;\n- try {\n- array = new long[length];\n- } catch (OutOfMemoryError outOfMemoryError) {\n- barrier = 0x42;\n- length = field;\n- }\n- return length;\n- }\n-}\n","filename":"test\/hotspot\/jtreg\/compiler\/allocation\/TestFailedAllocationBadGraph.java","additions":0,"deletions":80,"binary":false,"changes":80,"status":"deleted"}]}
0 commit comments