6910605: C2: NullPointerException/ClassCaseException is thrown when C2 with DeoptimizeALot is used
authorkvn
Mon, 08 Feb 2010 12:20:09 -0800
changeset 4893 fedc27b54caa
parent 4892 e977b527544a
child 4894 8a76fd3d098d
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
hotspot/src/share/vm/code/pcDesc.cpp
hotspot/src/share/vm/opto/graphKit.cpp
hotspot/src/share/vm/opto/parse3.cpp
hotspot/test/compiler/6910605/Test.java
--- a/hotspot/src/share/vm/code/pcDesc.cpp	Sun Feb 07 12:15:06 2010 -0800
+++ b/hotspot/src/share/vm/code/pcDesc.cpp	Mon Feb 08 12:20:09 2010 -0800
@@ -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 @@
     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
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Sun Feb 07 12:15:06 2010 -0800
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Mon Feb 08 12:20:09 2010 -0800
@@ -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 @@
 
 // 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 @@
   // 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
   }
 
--- a/hotspot/src/share/vm/opto/parse3.cpp	Sun Feb 07 12:15:06 2010 -0800
+++ b/hotspot/src/share/vm/opto/parse3.cpp	Mon Feb 08 12:20:09 2010 -0800
@@ -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 @@
 
   // 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;
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6910605/Test.java	Mon Feb 08 12:20:09 2010 -0800
@@ -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;
+        }
+
+}