# HG changeset patch # User kvn # Date 1355973675 28800 # Node ID 70896cb93c3593fcb3fef4dcec274bc63bb31892 # Parent f29c91f2f22bcda70d5d6e96e7cd766058a6c852 8004741: Missing compiled exception handle table entry for multidimensional array allocation Summary: Added missing exception path for multidimensional array allocation and use Throwable type instead of OutOfMemoryError for allocation's exception. Reviewed-by: twisti diff -r f29c91f2f22b -r 70896cb93c35 hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Wed Dec 19 15:40:35 2012 -0800 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Dec 19 19:21:15 2012 -0800 @@ -2990,7 +2990,7 @@ set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) ); // create memory projection for i_o set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); - make_slow_call_ex(allocx, env()->OutOfMemoryError_klass(), true); + make_slow_call_ex(allocx, env()->Throwable_klass(), true); // create a memory projection as for the normal control path Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory)); diff -r f29c91f2f22b -r 70896cb93c35 hotspot/src/share/vm/opto/parse3.cpp --- a/hotspot/src/share/vm/opto/parse3.cpp Wed Dec 19 15:40:35 2012 -0800 +++ b/hotspot/src/share/vm/opto/parse3.cpp Wed Dec 19 19:21:15 2012 -0800 @@ -509,6 +509,7 @@ makecon(TypeKlassPtr::make(array_klass)), dims); } + make_slow_call_ex(c, env()->Throwable_klass(), false); Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms)); diff -r f29c91f2f22b -r 70896cb93c35 hotspot/src/share/vm/opto/runtime.cpp --- a/hotspot/src/share/vm/opto/runtime.cpp Wed Dec 19 15:40:35 2012 -0800 +++ b/hotspot/src/share/vm/opto/runtime.cpp Wed Dec 19 19:21:15 2012 -0800 @@ -989,7 +989,7 @@ // since we're notifying the VM on every catch. // Force deoptimization and the rest of the lookup // will be fine. - deoptimize_caller_frame(thread, true); + deoptimize_caller_frame(thread); } // Check the stack guard pages. If enabled, look for handler in this frame; @@ -1143,17 +1143,22 @@ void OptoRuntime::deoptimize_caller_frame(JavaThread *thread, bool doit) { - // Deoptimize frame - if (doit) { - // Called from within the owner thread, so no need for safepoint - RegisterMap reg_map(thread); - frame stub_frame = thread->last_frame(); - assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check"); - frame caller_frame = stub_frame.sender(®_map); + // Deoptimize the caller before continuing, as the compiled + // exception handler table may not be valid. + if (!StressCompiledExceptionHandlers && doit) { + deoptimize_caller_frame(thread); + } +} - // Deoptimize the caller frame. - Deoptimization::deoptimize_frame(thread, caller_frame.id()); - } +void OptoRuntime::deoptimize_caller_frame(JavaThread *thread) { + // Called from within the owner thread, so no need for safepoint + RegisterMap reg_map(thread); + frame stub_frame = thread->last_frame(); + assert(stub_frame.is_runtime_frame() || exception_blob()->contains(stub_frame.pc()), "sanity check"); + frame caller_frame = stub_frame.sender(®_map); + + // Deoptimize the caller frame. + Deoptimization::deoptimize_frame(thread, caller_frame.id()); } diff -r f29c91f2f22b -r 70896cb93c35 hotspot/src/share/vm/opto/runtime.hpp --- a/hotspot/src/share/vm/opto/runtime.hpp Wed Dec 19 15:40:35 2012 -0800 +++ b/hotspot/src/share/vm/opto/runtime.hpp Wed Dec 19 19:21:15 2012 -0800 @@ -174,6 +174,7 @@ static address handle_exception_C (JavaThread* thread); static address handle_exception_C_helper(JavaThread* thread, nmethod*& nm); static address rethrow_C (oopDesc* exception, JavaThread *thread, address return_pc ); + static void deoptimize_caller_frame (JavaThread *thread); static void deoptimize_caller_frame (JavaThread *thread, bool doit); static bool is_deoptimized_caller_frame (JavaThread *thread); diff -r f29c91f2f22b -r 70896cb93c35 hotspot/src/share/vm/runtime/globals.hpp --- a/hotspot/src/share/vm/runtime/globals.hpp Wed Dec 19 15:40:35 2012 -0800 +++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Dec 19 19:21:15 2012 -0800 @@ -922,6 +922,9 @@ develop(bool, PrintExceptionHandlers, false, \ "Print exception handler tables for all nmethods when generated") \ \ + develop(bool, StressCompiledExceptionHandlers, false, \ + "Exercise compiled exception handlers") \ + \ develop(bool, InterceptOSException, false, \ "Starts debugger when an implicit OS (e.g., NULL) " \ "exception happens") \ diff -r f29c91f2f22b -r 70896cb93c35 hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Wed Dec 19 15:40:35 2012 -0800 +++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Dec 19 19:21:15 2012 -0800 @@ -2190,7 +2190,7 @@ // BiasedLocking needs an updated RegisterMap for the revoke monitors pass RegisterMap reg_map(this, UseBiasedLocking); frame compiled_frame = f.sender(®_map); - if (compiled_frame.can_be_deoptimized()) { + if (!StressCompiledExceptionHandlers && compiled_frame.can_be_deoptimized()) { Deoptimization::deoptimize(this, compiled_frame, ®_map); } } diff -r f29c91f2f22b -r 70896cb93c35 hotspot/test/compiler/8004741/Test8004741.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/8004741/Test8004741.java Wed Dec 19 19:21:15 2012 -0800 @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test Test8004741.java + * @bug 8004741 + * @summary Missing compiled exception handle table entry for multidimensional array allocation + * @run main/othervm -Xmx64m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:+StressCompiledExceptionHandlers Test8004741 + * + */ + +import java.util.*; + +public class Test8004741 extends Thread { + + static int[][] test(int a, int b) throws Exception { + int[][] ar = null; + try { + ar = new int[a][b]; + } catch (Error e) { + System.out.println("test got Error"); + passed = true; + throw(e); + } catch (Exception e) { + System.out.println("test got Exception"); + throw(e); + } + return ar; + } + + static boolean passed = false; + + public void run() { + System.out.println("test started"); + try { + while(true) { + test(2,20000); + } + } catch (ThreadDeath e) { + System.out.println("test got ThreadDeath"); + passed = true; + } catch (Error e) { + e.printStackTrace(); + System.out.println("test got Error"); + } catch (Exception e) { + e.printStackTrace(); + System.out.println("test got Exception"); + } + } + + public static void main(String[] args) throws Exception { + for (int n = 0; n < 11000; n++) { + test(2, 20); + } + + // First test exception catch + Test8004741 t = new Test8004741(); + + passed = false; + t.start(); + Thread.sleep(1000); + t.stop(); + + Thread.sleep(5000); + t.join(); + if (passed) { + System.out.println("PASSED"); + } else { + System.out.println("FAILED"); + System.exit(97); + } + } + +};