# HG changeset patch # User jcm # Date 1475213825 25200 # Node ID a3f113541801aa3b755061d2ec69dc9073763d80 # Parent 94ef14db8a2050619eda10a80b4cdb466e051ebd 8134389: Crash in HotSpot with jvm.dll+0x42b48 ciObjectFactory::create_new_metadata Summary: Always obtain return type from declared_signature for Invoke::declared_type. TypeCast return value to declared_signature return type for inlined lforms. Reviewed-by: kvn, vlivanov diff -r 94ef14db8a20 -r a3f113541801 hotspot/src/share/vm/c1/c1_GraphBuilder.cpp --- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Sep 29 10:00:56 2016 -0700 +++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Thu Sep 29 22:37:05 2016 -0700 @@ -1493,6 +1493,21 @@ // Check to see whether we are inlining. If so, Return // instructions become Gotos to the continuation point. if (continuation() != NULL) { + + int invoke_bci = state()->caller_state()->bci(); + + if (x != NULL && !ignore_return) { + ciMethod* caller = state()->scope()->caller()->method(); + Bytecodes::Code invoke_raw_bc = caller->raw_code_at_bci(invoke_bci); + if (invoke_raw_bc == Bytecodes::_invokehandle || invoke_raw_bc == Bytecodes::_invokedynamic) { + ciType* declared_ret_type = caller->get_declared_signature_at_bci(invoke_bci)->return_type(); + if (declared_ret_type->is_klass() && x->exact_type() == NULL && + x->declared_type() != declared_ret_type && declared_ret_type != compilation()->env()->Object_klass()) { + x = append(new TypeCast(declared_ret_type->as_klass(), x, copy_state_before())); + } + } + } + assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet"); if (compilation()->env()->dtrace_method_probes()) { @@ -1516,7 +1531,6 @@ // State at end of inlined method is the state of the caller // without the method parameters on stack, including the // return value, if any, of the inlined method on operand stack. - int invoke_bci = state()->caller_state()->bci(); set_state(state()->caller_state()->copy_for_parsing()); if (x != NULL) { if (!ignore_return) { diff -r 94ef14db8a20 -r a3f113541801 hotspot/src/share/vm/c1/c1_Instruction.cpp --- a/hotspot/src/share/vm/c1/c1_Instruction.cpp Thu Sep 29 10:00:56 2016 -0700 +++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp Thu Sep 29 22:37:05 2016 -0700 @@ -360,7 +360,8 @@ } ciType* Invoke::declared_type() const { - ciType *t = _target->signature()->return_type(); + ciSignature* declared_signature = state()->scope()->method()->get_declared_signature_at_bci(state()->bci()); + ciType *t = declared_signature->return_type(); assert(t->basic_type() != T_VOID, "need return value of void method?"); return t; } diff -r 94ef14db8a20 -r a3f113541801 hotspot/src/share/vm/ci/ciMethod.hpp --- a/hotspot/src/share/vm/ci/ciMethod.hpp Thu Sep 29 10:00:56 2016 -0700 +++ b/hotspot/src/share/vm/ci/ciMethod.hpp Thu Sep 29 22:37:05 2016 -0700 @@ -256,6 +256,14 @@ return get_method_at_bci(bci, ignored_will_link, &ignored_declared_signature); } + ciSignature* get_declared_signature_at_bci(int bci) { + bool ignored_will_link; + ciSignature* declared_signature; + get_method_at_bci(bci, ignored_will_link, &declared_signature); + assert(declared_signature != NULL, "cannot be null"); + return declared_signature; + } + // Given a certain calling environment, find the monomorphic target // for the call. Return NULL if the call is not monomorphic in // its calling environment. diff -r 94ef14db8a20 -r a3f113541801 hotspot/test/compiler/jsr292/TestArrayReturnType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hotspot/test/compiler/jsr292/TestArrayReturnType.java Thu Sep 29 22:37:05 2016 -0700 @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, 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 + * @bug 8134389 + * + * @run main/othervm -Xbatch compiler.jsr292.TestArrayReturnType + * @run main/othervm -Xbatch -XX:-Inline compiler.jsr292.TestArrayReturnType + * @run main/othervm -Xbatch + * -XX:CompileCommand=exclude,compiler.jsr292.TestArrayReturnType::testArrayReturnType + * compiler.jsr292.TestArrayReturnType + */ + +package compiler.jsr292; + + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +public class TestArrayReturnType { + + static final MethodHandle mh; + static int[] testArray = new int[1]; + static { + try { + mh = MethodHandles.lookup().findStatic(TestArrayReturnType.class, "testArrayReturnType", MethodType.methodType(int[].class)); + } catch (Exception e) { + throw new Error(e); + } + } + + static int[] testArrayReturnType() { + return testArray; + } + + public static void test() throws Throwable { + int a[] = (int[])mh.invokeExact(); + for (int i=0; i