aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkvn <none@none>2010-02-08 12:20:09 -0800
committerkvn <none@none>2010-02-08 12:20:09 -0800
commit1e6786347c9f006eb82c29e38b90b9da1269efb4 (patch)
treebaa7e5178fda192ae44debffc27bf6b8db89b343
parent8a40fc1963fd34cfc3f44f714735b8b691a8edee (diff)
6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
Summary: Set the reexecute bit for runtime calls _new_array_Java when they used for _multianewarray bytecode. Reviewed-by: never
-rw-r--r--src/share/vm/code/pcDesc.cpp5
-rw-r--r--src/share/vm/opto/graphKit.cpp16
-rw-r--r--src/share/vm/opto/parse3.cpp16
-rw-r--r--test/compiler/6910605/Test.java78
4 files changed, 106 insertions, 9 deletions
diff --git a/src/share/vm/code/pcDesc.cpp b/src/share/vm/code/pcDesc.cpp
index 5b981645a..5d6456bf5 100644
--- a/src/share/vm/code/pcDesc.cpp
+++ b/src/share/vm/code/pcDesc.cpp
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,8 @@ void PcDesc::print(nmethod* code) {
tty->print(" ");
sd->method()->print_short_name(tty);
tty->print(" @%d", sd->bci());
- tty->print(" reexecute=%s", sd->should_reexecute()?"true":"false");
+ if (sd->should_reexecute())
+ tty->print(" reexecute=true");
tty->cr();
}
#endif
diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp
index 57fea6480..6c177904c 100644
--- a/src/share/vm/opto/graphKit.cpp
+++ b/src/share/vm/opto/graphKit.cpp
@@ -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.
*
* 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
// 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();
int cur_bci = jvms->bci();
if (cur_method != NULL && cur_bci != InvocationEntryBci) {
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
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
// deoptimization happens. We set the reexecute state for them here
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
}
diff --git a/src/share/vm/opto/parse3.cpp b/src/share/vm/opto/parse3.cpp
index 40f9940bd..9f0a034bb 100644
--- a/src/share/vm/opto/parse3.cpp
+++ b/src/share/vm/opto/parse3.cpp
@@ -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.
*
* 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,
// or if all non-final dimensions are small constants.
- if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
- Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions, ndimensions);
+ if (ndimensions == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
+ 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);
return;
}
diff --git a/test/compiler/6910605/Test.java b/test/compiler/6910605/Test.java
new file mode 100644
index 000000000..42a26e177
--- /dev/null
+++ b/test/compiler/6910605/Test.java
@@ -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;
+ }
+
+}