mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
Set the reexecute bit for runtime calls _new_array_Java when they used for _multianewarray bytecode. Reviewed-by: never
This commit is contained in:
parent
2fd8d35905
commit
3f7a94c3f2
4 changed files with 106 additions and 9 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1997-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -52,7 +52,8 @@ void PcDesc::print(nmethod* code) {
|
||||||
tty->print(" ");
|
tty->print(" ");
|
||||||
sd->method()->print_short_name(tty);
|
sd->method()->print_short_name(tty);
|
||||||
tty->print(" @%d", sd->bci());
|
tty->print(" @%d", sd->bci());
|
||||||
tty->print(" reexecute=%s", sd->should_reexecute()?"true":"false");
|
if (sd->should_reexecute())
|
||||||
|
tty->print(" reexecute=true");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2001-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 2001-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -752,12 +752,20 @@ bool GraphKit::dead_locals_are_killed() {
|
||||||
|
|
||||||
// Helper function for enforcing certain bytecodes to reexecute if
|
// Helper function for enforcing certain bytecodes to reexecute if
|
||||||
// deoptimization happens
|
// deoptimization happens
|
||||||
static bool should_reexecute_implied_by_bytecode(JVMState *jvms) {
|
static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarray) {
|
||||||
ciMethod* cur_method = jvms->method();
|
ciMethod* cur_method = jvms->method();
|
||||||
int cur_bci = jvms->bci();
|
int cur_bci = jvms->bci();
|
||||||
if (cur_method != NULL && cur_bci != InvocationEntryBci) {
|
if (cur_method != NULL && cur_bci != InvocationEntryBci) {
|
||||||
Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
|
Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
|
||||||
return Interpreter::bytecode_should_reexecute(code);
|
return Interpreter::bytecode_should_reexecute(code) ||
|
||||||
|
is_anewarray && code == Bytecodes::_multianewarray;
|
||||||
|
// Reexecute _multianewarray bytecode which was replaced with
|
||||||
|
// sequence of [a]newarray. See Parse::do_multianewarray().
|
||||||
|
//
|
||||||
|
// Note: interpreter should not have it set since this optimization
|
||||||
|
// is limited by dimensions and guarded by flag so in some cases
|
||||||
|
// multianewarray() runtime calls will be generated and
|
||||||
|
// the bytecode should not be reexecutes (stack will not be reset).
|
||||||
} else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -808,7 +816,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
|
||||||
// For a known set of bytecodes, the interpreter should reexecute them if
|
// For a known set of bytecodes, the interpreter should reexecute them if
|
||||||
// deoptimization happens. We set the reexecute state for them here
|
// deoptimization happens. We set the reexecute state for them here
|
||||||
if (out_jvms->is_reexecute_undefined() && //don't change if already specified
|
if (out_jvms->is_reexecute_undefined() && //don't change if already specified
|
||||||
should_reexecute_implied_by_bytecode(out_jvms)) {
|
should_reexecute_implied_by_bytecode(out_jvms, call->is_AllocateArray())) {
|
||||||
out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed
|
out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
|
* Copyright 1998-2010 Sun Microsystems, Inc. All Rights Reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -439,8 +439,18 @@ void Parse::do_multianewarray() {
|
||||||
|
|
||||||
// Can use multianewarray instead of [a]newarray if only one dimension,
|
// Can use multianewarray instead of [a]newarray if only one dimension,
|
||||||
// or if all non-final dimensions are small constants.
|
// or if all non-final dimensions are small constants.
|
||||||
if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
|
if (ndimensions == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
|
||||||
Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions, ndimensions);
|
Node* obj = NULL;
|
||||||
|
// Set the original stack and the reexecute bit for the interpreter
|
||||||
|
// to reexecute the multianewarray bytecode if deoptimization happens.
|
||||||
|
// Do it unconditionally even for one dimension multianewarray.
|
||||||
|
// Note: the reexecute bit will be set in GraphKit::add_safepoint_edges()
|
||||||
|
// when AllocateArray node for newarray is created.
|
||||||
|
{ PreserveReexecuteState preexecs(this);
|
||||||
|
_sp += ndimensions;
|
||||||
|
// Pass 0 as nargs since uncommon trap code does not need to restore stack.
|
||||||
|
obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0);
|
||||||
|
} //original reexecute and sp are set back here
|
||||||
push(obj);
|
push(obj);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
78
hotspot/test/compiler/6910605/Test.java
Normal file
78
hotspot/test/compiler/6910605/Test.java
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||||
|
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||||
|
* have any questions.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 6910605
|
||||||
|
* @summary C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
|
||||||
|
*
|
||||||
|
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+DeoptimizeALot -Xbatch Test
|
||||||
|
*
|
||||||
|
* original test: nsk/coverage/runtime/runtime007
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
public static int buf=0;
|
||||||
|
|
||||||
|
public static void main( String argv[] ) {
|
||||||
|
System.exit(run(argv, System.out)+95);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int run(String argv[],PrintStream out) {
|
||||||
|
int ret=0, retx=0, bad=0;
|
||||||
|
|
||||||
|
for( int i=0; (i < 100000) && (bad < 10) ; i++ ) {
|
||||||
|
retx = OptoRuntime_f2i_Type(out);
|
||||||
|
ret += retx;
|
||||||
|
if( retx !=0 ) {
|
||||||
|
out.println("i="+i);
|
||||||
|
bad++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret==0 ? 0 : 2 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int OptoRuntime_f2i_Type(PrintStream out) {
|
||||||
|
int c1=2, c2=3, c3=4, c4=5, c5=6;
|
||||||
|
int j=0, k=0;
|
||||||
|
try {
|
||||||
|
int[][] iii=(int[][])(new int[c1][c2]);
|
||||||
|
|
||||||
|
for( j=0; j<c1; j++ ) {
|
||||||
|
for( k=0; k<c2; k++ ) {
|
||||||
|
iii[j][k]=(int)((float)(j+1)/(float)(k+1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
out.println("Unexpected exception " + e);
|
||||||
|
e.printStackTrace(out);
|
||||||
|
out.println("j="+j+", k="+k);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue