Mercurial > hg > openjdk > jdk8u > hotspot
changeset 8507:f5ded236c413 jdk8u144-b31
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, kevinw
author | shshahma |
---|---|
date | Mon, 21 Nov 2016 05:29:59 +0000 |
parents | 53d23b6b25cd |
children | a11aa80cd695 |
files | src/share/vm/c1/c1_GraphBuilder.cpp src/share/vm/c1/c1_Instruction.cpp src/share/vm/ci/ciMethod.hpp |
diffstat | 3 files changed, 27 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/c1/c1_GraphBuilder.cpp Thu Nov 17 16:06:56 2016 +0000 +++ b/src/share/vm/c1/c1_GraphBuilder.cpp Mon Nov 21 05:29:59 2016 +0000 @@ -1485,6 +1485,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) { + 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()) { @@ -1508,7 +1523,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) { state()->push(x->type(), x);
--- a/src/share/vm/c1/c1_Instruction.cpp Thu Nov 17 16:06:56 2016 +0000 +++ b/src/share/vm/c1/c1_Instruction.cpp Mon Nov 21 05:29:59 2016 +0000 @@ -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; }
--- a/src/share/vm/ci/ciMethod.hpp Thu Nov 17 16:06:56 2016 +0000 +++ b/src/share/vm/ci/ciMethod.hpp Mon Nov 21 05:29:59 2016 +0000 @@ -243,11 +243,21 @@ ciField* get_field_at_bci( int bci, bool &will_link); ciMethod* get_method_at_bci(int bci, bool &will_link, ciSignature* *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; + } + ciMethod* get_method_at_bci(int bci) { bool ignored_will_link; ciSignature* ignored_declared_signature; return get_method_at_bci(bci, ignored_will_link, &ignored_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.