Fri, 03 Apr 2009 13:33:32 -0700
6823453: DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph")
Summary: Use a HaltNode on the fall through path of the AllocateArrayNode to indicate that it is unreachable if the array length is negative.
Reviewed-by: never, jrose
1.1 --- a/src/share/vm/opto/callnode.cpp Thu Apr 02 10:49:41 2009 -0700 1.2 +++ b/src/share/vm/opto/callnode.cpp Fri Apr 03 13:33:32 2009 -0700 1.3 @@ -1043,6 +1043,51 @@ 1.4 //============================================================================= 1.5 uint AllocateArrayNode::size_of() const { return sizeof(*this); } 1.6 1.7 +Node* AllocateArrayNode::Ideal(PhaseGVN *phase, bool can_reshape) { 1.8 + if (remove_dead_region(phase, can_reshape)) return this; 1.9 + 1.10 + const Type* type = phase->type(Ideal_length()); 1.11 + if (type->isa_int() && type->is_int()->_hi < 0) { 1.12 + if (can_reshape) { 1.13 + PhaseIterGVN *igvn = phase->is_IterGVN(); 1.14 + // Unreachable fall through path (negative array length), 1.15 + // the allocation can only throw so disconnect it. 1.16 + Node* proj = proj_out(TypeFunc::Control); 1.17 + Node* catchproj = NULL; 1.18 + if (proj != NULL) { 1.19 + for (DUIterator_Fast imax, i = proj->fast_outs(imax); i < imax; i++) { 1.20 + Node *cn = proj->fast_out(i); 1.21 + if (cn->is_Catch()) { 1.22 + catchproj = cn->as_Multi()->proj_out(CatchProjNode::fall_through_index); 1.23 + break; 1.24 + } 1.25 + } 1.26 + } 1.27 + if (catchproj != NULL && catchproj->outcnt() > 0 && 1.28 + (catchproj->outcnt() > 1 || 1.29 + catchproj->unique_out()->Opcode() != Op_Halt)) { 1.30 + assert(catchproj->is_CatchProj(), "must be a CatchProjNode"); 1.31 + Node* nproj = catchproj->clone(); 1.32 + igvn->register_new_node_with_optimizer(nproj); 1.33 + 1.34 + Node *frame = new (phase->C, 1) ParmNode( phase->C->start(), TypeFunc::FramePtr ); 1.35 + frame = phase->transform(frame); 1.36 + // Halt & Catch Fire 1.37 + Node *halt = new (phase->C, TypeFunc::Parms) HaltNode( nproj, frame ); 1.38 + phase->C->root()->add_req(halt); 1.39 + phase->transform(halt); 1.40 + 1.41 + igvn->replace_node(catchproj, phase->C->top()); 1.42 + return this; 1.43 + } 1.44 + } else { 1.45 + // Can't correct it during regular GVN so register for IGVN 1.46 + phase->C->record_for_igvn(this); 1.47 + } 1.48 + } 1.49 + return NULL; 1.50 +} 1.51 + 1.52 // Retrieve the length from the AllocateArrayNode. Narrow the type with a 1.53 // CastII, if appropriate. If we are not allowed to create new nodes, and 1.54 // a CastII is appropriate, return NULL.
2.1 --- a/src/share/vm/opto/callnode.hpp Thu Apr 02 10:49:41 2009 -0700 2.2 +++ b/src/share/vm/opto/callnode.hpp Fri Apr 03 13:33:32 2009 -0700 2.3 @@ -762,6 +762,7 @@ 2.4 } 2.5 virtual int Opcode() const; 2.6 virtual uint size_of() const; // Size is bigger 2.7 + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); 2.8 2.9 // Dig the length operand out of a array allocation site. 2.10 Node* Ideal_length() {
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/compiler/6823453/Test.java Fri Apr 03 13:33:32 2009 -0700 3.3 @@ -0,0 +1,96 @@ 3.4 +/* 3.5 + * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 3.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 3.24 + * have any questions. 3.25 + * 3.26 + */ 3.27 + 3.28 +/* 3.29 + * @test 3.30 + * @bug 6823453 3.31 + * @summary DeoptimizeALot causes fastdebug server jvm to fail with assert(false,"unscheduable graph") 3.32 + * @run main/othervm -Xcomp -XX:CompileOnly=Test -XX:+DeoptimizeALot Test 3.33 + */ 3.34 + 3.35 +public class Test { 3.36 + 3.37 + static long vara_1 = 1L; 3.38 + 3.39 + static void testa() { 3.40 + short var_2 = (byte) 1.0E10; 3.41 + 3.42 + for ( Object temp = new byte[(byte)1.0E10]; true ; 3.43 + var_2 = "1".equals("0") ? ((byte) vara_1) : 1 ) {} 3.44 + } 3.45 + 3.46 + static void testb() { 3.47 + long var_1 = -1L; 3.48 + 3.49 + short var_2 = (byte) 1.0E10; 3.50 + 3.51 + for ( Object temp = new byte[(byte)1.0E10]; true ; 3.52 + var_2 = "1".equals("0") ? ((byte) var_1) : 1 ) {} 3.53 + } 3.54 + 3.55 + static void testc() { 3.56 + long var_1 = -1L; 3.57 + if (vara_1 > 0) var_1 = 1L; 3.58 + 3.59 + int var_2 = (byte)var_1 - 128; 3.60 + 3.61 + for ( Object temp = new byte[var_2]; true ; 3.62 + var_2 = "1".equals("0") ? 2 : 1 ) {} 3.63 + } 3.64 + 3.65 + static void testd() { 3.66 + long var_1 = 0L; 3.67 + 3.68 + int var_2 = (byte)var_1 + 1; 3.69 + for (int i=0; i<2 ; i++) var_2 = var_2 - 1; 3.70 + 3.71 + for ( Object temp = new byte[var_2]; true ; 3.72 + var_2 = "1".equals("0") ? 2 : 1 ) {} 3.73 + } 3.74 + 3.75 + public static void main(String[] args) throws Exception { 3.76 + int nex = 0; 3.77 + 3.78 + try { 3.79 + testa(); 3.80 + } 3.81 + catch (java.lang.NegativeArraySizeException ex) { nex++; } 3.82 + try { 3.83 + testb(); 3.84 + } 3.85 + catch (java.lang.NegativeArraySizeException ex) { nex++; } 3.86 + try { 3.87 + testc(); 3.88 + } 3.89 + catch (java.lang.NegativeArraySizeException ex) { nex++; } 3.90 + try { 3.91 + testd(); 3.92 + } 3.93 + catch (java.lang.NegativeArraySizeException ex) { nex++; } 3.94 + 3.95 + if (nex != 4) 3.96 + System.exit(97); 3.97 + } 3.98 +} 3.99 +