diff -r e3b736cf4fa3 src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Oct 18 09:36:35 2013 +0000 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Fri Oct 18 14:45:28 2013 -0700 @@ -183,26 +183,49 @@ address TemplateInterpreterGenerator::ge __ profile_return_type(mdp, rax, tmp); } - Label L_got_cache, L_giant_index; + const Register cache = rbx; + const Register index = rcx; + Label L_normal_index, L_got_cache, L_is_breakpoint, L_giant_index; + if (EnableInvokeDynamic) { + // If the current bytecode is a breakpoint we have to get the original bytecode + // since some bytecodes (e.g. invokedynamic) have bigger indexes. + __ cmpb(Address(r13, 0), Bytecodes::_breakpoint); + __ jcc(Assembler::equal, L_is_breakpoint); + __ cmpb(Address(r13, 0), Bytecodes::_invokedynamic); __ jcc(Assembler::equal, L_giant_index); } - __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u2)); + + __ bind(L_normal_index); + __ get_cache_and_index_at_bcp(cache, index, 1, sizeof(u2)); + + const Register flags = cache; __ bind(L_got_cache); - __ movl(rbx, Address(rbx, rcx, - Address::times_ptr, - in_bytes(ConstantPoolCache::base_offset()) + - 3 * wordSize)); - __ andl(rbx, 0xFF); - __ lea(rsp, Address(rsp, rbx, Address::times_8)); + __ movl(flags, Address(cache, index, Address::times_ptr, + ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset())); + __ andl(flags, ConstantPoolCacheEntry::parameter_size_mask); + __ lea(rsp, Address(rsp, flags, Interpreter::stackElementScale())); __ dispatch_next(state, step); // out of the main line of code... if (EnableInvokeDynamic) { __ bind(L_giant_index); - __ get_cache_and_index_at_bcp(rbx, rcx, 1, sizeof(u4)); + __ get_cache_and_index_at_bcp(cache, index, 1, sizeof(u4)); __ jmp(L_got_cache); + + // Get the original byte code. + __ bind(L_is_breakpoint); + __ push(rax); + __ get_method(c_rarg1); + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::get_original_bytecode_at), c_rarg1, r13); + __ mov(rbx, rax); + __ pop(rax); + + __ cmpl(rbx, Bytecodes::_invokedynamic); + __ jcc(Assembler::equal, L_giant_index); + + __ jmp(L_normal_index); } return entry;