src/cpu/x86/vm/templateTable_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File valhalla Cdiff src/cpu/x86/vm/templateTable_x86.cpp

src/cpu/x86/vm/templateTable_x86.cpp

Print this page

        

*** 3614,3624 **** const bool is_invokedirect = code == Bytecodes::_invokedirect; const bool is_invokespecial = code == Bytecodes::_invokespecial; const bool load_receiver = (recv != noreg); const bool save_flags = (flags != noreg); assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), ""); ! assert(save_flags == (is_invokeinterface || is_invokevirtual), "need flags for vfinal"); assert(flags == noreg || flags == rdx, ""); assert(recv == noreg || recv == rcx, ""); // setup registers & access constant pool cache if (recv == noreg) recv = rcx; --- 3614,3624 ---- const bool is_invokedirect = code == Bytecodes::_invokedirect; const bool is_invokespecial = code == Bytecodes::_invokespecial; const bool load_receiver = (recv != noreg); const bool save_flags = (flags != noreg); assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), ""); ! assert(save_flags == (is_invokeinterface || is_invokevirtual || is_invokedirect), "need flags for vfinal"); assert(flags == noreg || flags == rdx, ""); assert(recv == noreg || recv == rcx, ""); // setup registers & access constant pool cache if (recv == noreg) recv = rcx;
*** 3749,3773 **** invokevirtual_helper(rbx, rcx, rdx); } /* ! * Dummy implemented basically as invokevirtual (blindly uses resolve_invokevirtual), ! * but assumes it picks out a final call (unsure about interfaces, default ! * methods and where "Value.equals(QValue;)Z" should live at this point in time) */ void TemplateTable::invokedirect(int byte_no) { transition(vtos, vtos); assert(byte_no == f2_byte, "use this argument"); ! prepare_invoke(byte_no, rbx, noreg, rcx); // recv, flags __ verify_oop(rcx); __ null_check(rcx); - __ profile_final_call(rax); __ profile_arguments_type(rax, rbx, rbcp, true); __ jump_from_interpreted(rbx, rax); } void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument"); --- 3749,3785 ---- invokevirtual_helper(rbx, rcx, rdx); } /* ! * The invokedirect bytecode is implemented as an invokevirtual bytecode: ! * The implementation blindly uses resolve_invokevirtual() and assumes ! * that a final call will be picked at the end. (Currently unsure about interfaces, ! * default methods, and about where "Value.equals(QValue;)Z" should live.) */ void TemplateTable::invokedirect(int byte_no) { transition(vtos, vtos); assert(byte_no == f2_byte, "use this argument"); ! prepare_invoke(byte_no, ! rbx, // method (and not vtable index, as the method to be invoked should be final) ! noreg, ! rcx, rdx); // recv, flags ! ! // Check if the method is final ! Label notFinal; ! __ movl(rax, rdx); ! __ andl(rax, (1 << ConstantPoolCacheEntry::is_vfinal_shift)); ! __ jcc(Assembler::zero, notFinal); __ verify_oop(rcx); __ null_check(rcx); __ profile_final_call(rax); __ profile_arguments_type(rax, rbx, rbcp, true); __ jump_from_interpreted(rbx, rax); + + __ bind(notFinal); + __ stop("Interpreter observed a non-final method as a target of an invokedirect instruction"); } void TemplateTable::invokespecial(int byte_no) { transition(vtos, vtos); assert(byte_no == f1_byte, "use this argument");
src/cpu/x86/vm/templateTable_x86.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File