--- old/src/share/vm/opto/doCall.cpp 2017-05-29 18:07:44.932024988 +0200 +++ new/src/share/vm/opto/doCall.cpp 2017-05-29 18:07:44.857025069 +0200 @@ -38,6 +38,7 @@ #include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" +#include "opto/valuetypenode.hpp" #include "prims/nativeLookup.hpp" #include "runtime/sharedRuntime.hpp" @@ -657,6 +658,21 @@ push(cast_obj); } } + } else if (rt == T_VALUETYPE) { + assert(ct == T_VALUETYPE, "rt=%s, ct=%s", type2name(rt), type2name(ct)); + if (rtype == C->env()->___Value_klass()) { + const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass()); + Node* retnode = pop(); + Node* cast = _gvn.transform(new CheckCastPPNode(control(), retnode, sig_type)); + Node* vt = ValueTypeNode::make(_gvn, merged_memory(), cast); + push(vt); + } else { + assert(ctype == C->env()->___Value_klass(), "unexpected value type klass"); + Node* retnode = pop(); + assert(retnode->is_ValueType(), "inconsistent"); + retnode = retnode->as_ValueType()->store_to_memory(this); + push(retnode); + } } else { assert(rt == ct, "unexpected mismatch: rt=%s, ct=%s", type2name(rt), type2name(ct)); // push a zero; it's better than getting an oop/int mismatch