Tue, 17 Jun 2014 09:02:30 +0000
8033626: assert(ex_map->jvms()->same_calls_as(_exceptions->jvms())) failed: all collected exceptions must come from the same place
Reviewed-by: kvn, roland
1.1 --- a/src/share/vm/opto/graphKit.cpp Fri Jun 13 15:04:38 2014 -0700 1.2 +++ b/src/share/vm/opto/graphKit.cpp Tue Jun 17 09:02:30 2014 +0000 1.3 @@ -2458,7 +2458,7 @@ 1.4 1.5 //------------------------------make_slow_call_ex------------------------------ 1.6 // Make the exception handler hookups for the slow call 1.7 -void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj) { 1.8 +void GraphKit::make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj, bool deoptimize) { 1.9 if (stopped()) return; 1.10 1.11 // Make a catch node with just two handlers: fall-through and catch-all 1.12 @@ -2472,11 +2472,17 @@ 1.13 set_i_o(i_o); 1.14 1.15 if (excp != top()) { 1.16 - // Create an exception state also. 1.17 - // Use an exact type if the caller has specified a specific exception. 1.18 - const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull); 1.19 - Node* ex_oop = new (C) CreateExNode(ex_type, control(), i_o); 1.20 - add_exception_state(make_exception_state(_gvn.transform(ex_oop))); 1.21 + if (deoptimize) { 1.22 + // Deoptimize if an exception is caught. Don't construct exception state in this case. 1.23 + uncommon_trap(Deoptimization::Reason_unhandled, 1.24 + Deoptimization::Action_none); 1.25 + } else { 1.26 + // Create an exception state also. 1.27 + // Use an exact type if the caller has specified a specific exception. 1.28 + const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull); 1.29 + Node* ex_oop = new (C) CreateExNode(ex_type, control(), i_o); 1.30 + add_exception_state(make_exception_state(_gvn.transform(ex_oop))); 1.31 + } 1.32 } 1.33 } 1.34 1.35 @@ -3290,7 +3296,8 @@ 1.36 1.37 //---------------------------set_output_for_allocation------------------------- 1.38 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, 1.39 - const TypeOopPtr* oop_type) { 1.40 + const TypeOopPtr* oop_type, 1.41 + bool deoptimize_on_exception) { 1.42 int rawidx = Compile::AliasIdxRaw; 1.43 alloc->set_req( TypeFunc::FramePtr, frameptr() ); 1.44 add_safepoint_edges(alloc); 1.45 @@ -3298,7 +3305,7 @@ 1.46 set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) ); 1.47 // create memory projection for i_o 1.48 set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx ); 1.49 - make_slow_call_ex(allocx, env()->Throwable_klass(), true); 1.50 + make_slow_call_ex(allocx, env()->Throwable_klass(), true, deoptimize_on_exception); 1.51 1.52 // create a memory projection as for the normal control path 1.53 Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory)); 1.54 @@ -3376,9 +3383,11 @@ 1.55 // The optional arguments are for specialized use by intrinsics: 1.56 // - If 'extra_slow_test' if not null is an extra condition for the slow-path. 1.57 // - If 'return_size_val', report the the total object size to the caller. 1.58 +// - deoptimize_on_exception controls how Java exceptions are handled (rethrow vs deoptimize) 1.59 Node* GraphKit::new_instance(Node* klass_node, 1.60 Node* extra_slow_test, 1.61 - Node* *return_size_val) { 1.62 + Node* *return_size_val, 1.63 + bool deoptimize_on_exception) { 1.64 // Compute size in doublewords 1.65 // The size is always an integral number of doublewords, represented 1.66 // as a positive bytewise size stored in the klass's layout_helper. 1.67 @@ -3447,7 +3456,7 @@ 1.68 size, klass_node, 1.69 initial_slow_test); 1.70 1.71 - return set_output_for_allocation(alloc, oop_type); 1.72 + return set_output_for_allocation(alloc, oop_type, deoptimize_on_exception); 1.73 } 1.74 1.75 //-------------------------------new_array------------------------------------- 1.76 @@ -3457,7 +3466,8 @@ 1.77 Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) 1.78 Node* length, // number of array elements 1.79 int nargs, // number of arguments to push back for uncommon trap 1.80 - Node* *return_size_val) { 1.81 + Node* *return_size_val, 1.82 + bool deoptimize_on_exception) { 1.83 jint layout_con = Klass::_lh_neutral_value; 1.84 Node* layout_val = get_layout_helper(klass_node, layout_con); 1.85 int layout_is_con = (layout_val == NULL); 1.86 @@ -3600,7 +3610,7 @@ 1.87 ary_type = ary_type->is_aryptr()->cast_to_size(length_type); 1.88 } 1.89 1.90 - Node* javaoop = set_output_for_allocation(alloc, ary_type); 1.91 + Node* javaoop = set_output_for_allocation(alloc, ary_type, deoptimize_on_exception); 1.92 1.93 // Cast length on remaining path to be as narrow as possible 1.94 if (map()->find_edge(length) >= 0) {
2.1 --- a/src/share/vm/opto/graphKit.hpp Fri Jun 13 15:04:38 2014 -0700 2.2 +++ b/src/share/vm/opto/graphKit.hpp Tue Jun 17 09:02:30 2014 +0000 2.3 @@ -802,7 +802,7 @@ 2.4 2.5 // merge in all memory slices from new_mem, along the given path 2.6 void merge_memory(Node* new_mem, Node* region, int new_path); 2.7 - void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj); 2.8 + void make_slow_call_ex(Node* call, ciInstanceKlass* ex_klass, bool separate_io_proj, bool deoptimize = false); 2.9 2.10 // Helper functions to build synchronizations 2.11 int next_monitor(); 2.12 @@ -844,13 +844,16 @@ 2.13 2.14 // implementation of object creation 2.15 Node* set_output_for_allocation(AllocateNode* alloc, 2.16 - const TypeOopPtr* oop_type); 2.17 + const TypeOopPtr* oop_type, 2.18 + bool deoptimize_on_exception=false); 2.19 Node* get_layout_helper(Node* klass_node, jint& constant_value); 2.20 Node* new_instance(Node* klass_node, 2.21 Node* slow_test = NULL, 2.22 - Node* *return_size_val = NULL); 2.23 + Node* *return_size_val = NULL, 2.24 + bool deoptimize_on_exception = false); 2.25 Node* new_array(Node* klass_node, Node* count_val, int nargs, 2.26 - Node* *return_size_val = NULL); 2.27 + Node* *return_size_val = NULL, 2.28 + bool deoptimize_on_exception = false); 2.29 2.30 // java.lang.String helpers 2.31 Node* load_String_offset(Node* ctrl, Node* str);
3.1 --- a/src/share/vm/opto/library_call.cpp Fri Jun 13 15:04:38 2014 -0700 3.2 +++ b/src/share/vm/opto/library_call.cpp Tue Jun 17 09:02:30 2014 +0000 3.3 @@ -4576,7 +4576,10 @@ 3.4 // It's an instance, and it passed the slow-path tests. 3.5 PreserveJVMState pjvms(this); 3.6 Node* obj_size = NULL; 3.7 - Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size); 3.8 + // Need to deoptimize on exception from allocation since Object.clone intrinsic 3.9 + // is reexecuted if deoptimization occurs and there could be problems when merging 3.10 + // exception state between multiple Object.clone versions (reexecute=true vs reexecute=false). 3.11 + Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size, /*deoptimize_on_exception=*/true); 3.12 3.13 copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); 3.14
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/compiler/intrinsics/clone/TestObjectClone.java Tue Jun 17 09:02:30 2014 +0000 4.3 @@ -0,0 +1,80 @@ 4.4 +/* 4.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. 4.11 + * 4.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.15 + * version 2 for more details (a copy is included in the LICENSE file that 4.16 + * accompanied this code). 4.17 + * 4.18 + * You should have received a copy of the GNU General Public License version 4.19 + * 2 along with this work; if not, write to the Free Software Foundation, 4.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.21 + * 4.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.23 + * or visit www.oracle.com if you need additional information or have any 4.24 + * questions. 4.25 + * 4.26 + */ 4.27 + 4.28 +/* 4.29 + * @test 4.30 + * @bug 8033626 4.31 + * @summary assert(ex_map->jvms()->same_calls_as(_exceptions->jvms())) failed: all collected exceptions must come from the same place 4.32 + * @library /testlibrary 4.33 + * @run main/othervm -XX:-TieredCompilation -Xbatch -XX:CompileOnly=TestObjectClone::f TestObjectClone 4.34 + */ 4.35 +import com.oracle.java.testlibrary.Asserts; 4.36 + 4.37 +public class TestObjectClone implements Cloneable { 4.38 + static class A extends TestObjectClone {} 4.39 + static class B extends TestObjectClone { 4.40 + public B clone() { 4.41 + return (B)TestObjectClone.b; 4.42 + } 4.43 + } 4.44 + static class C extends TestObjectClone { 4.45 + public C clone() { 4.46 + return (C)TestObjectClone.c; 4.47 + } 4.48 + } 4.49 + static class D extends TestObjectClone { 4.50 + public D clone() { 4.51 + return (D)TestObjectClone.d; 4.52 + } 4.53 + } 4.54 + static TestObjectClone a = new A(), b = new B(), c = new C(), d = new D(); 4.55 + 4.56 + public static Object f(TestObjectClone o) throws CloneNotSupportedException { 4.57 + // Polymorphic call site: >90% Object::clone / <10% other methods 4.58 + return o.clone(); 4.59 + } 4.60 + 4.61 + public static void main(String[] args) throws Exception { 4.62 + TestObjectClone[] params1 = {a, a, a, a, a, a, a, a, a, a, a, 4.63 + a, a, a, a, a, a, a, a, a, a, a, 4.64 + a, a, a, a, a, a, a, a, a, a, a, 4.65 + b, c, d}; 4.66 + 4.67 + for (int i = 0; i < 15000; i++) { 4.68 + f(params1[i % params1.length]); 4.69 + } 4.70 + 4.71 + Asserts.assertTrue(f(a) != a); 4.72 + Asserts.assertTrue(f(b) == b); 4.73 + Asserts.assertTrue(f(c) == c); 4.74 + Asserts.assertTrue(f(d) == d); 4.75 + 4.76 + try { 4.77 + f(null); 4.78 + throw new AssertionError(""); 4.79 + } catch (NullPointerException e) { /* expected */ } 4.80 + 4.81 + System.out.println("TEST PASSED"); 4.82 + } 4.83 +}