@@ -2256,14 +2256,82 @@ void TemplateTable::load_field_cp_cache_entry(Register obj,
22562256 }
22572257}
22582258
2259+ // The Rmethod register is input and overwritten to be the adapter method for the
2260+ // indy call. Return address (ra) is set to the return address for the adapter and
2261+ // an appendix may be pushed to the stack. Registers A0-A3 are clobbered.
2262+ void TemplateTable::load_invokedynamic_entry (Register method) {
2263+ // setup registers
2264+ const Register appendix = A0;
2265+ const Register cache = A2;
2266+ const Register index = A3;
2267+ assert_different_registers (method, appendix, cache, index);
2268+
2269+ __ save_bcp ();
2270+
2271+ Label resolved;
2272+
2273+ __ load_resolved_indy_entry (cache, index);
2274+ __ ld_d (method, Address (cache, in_bytes (ResolvedIndyEntry::method_offset ())));
2275+ __ membar (Assembler::Membar_mask_bits (Assembler::LoadLoad | Assembler::LoadStore));
2276+
2277+ // Compare the method to zero
2278+ __ bnez (method, resolved);
2279+
2280+ Bytecodes::Code code = bytecode ();
2281+
2282+ // Call to the interpreter runtime to resolve invokedynamic
2283+ address entry = CAST_FROM_FN_PTR (address, InterpreterRuntime::resolve_from_cache);
2284+ __ li (method, code); // this is essentially Bytecodes::_invokedynamic
2285+ __ call_VM (noreg, entry, method);
2286+ // Update registers with resolved info
2287+ __ load_resolved_indy_entry (cache, index);
2288+ __ ld_d (method, Address (cache, in_bytes (ResolvedIndyEntry::method_offset ())));
2289+ __ membar (Assembler::Membar_mask_bits (Assembler::LoadLoad | Assembler::LoadStore));
2290+
2291+ #ifdef ASSERT
2292+ __ bnez (method, resolved);
2293+ __ stop (" Should be resolved by now" );
2294+ #endif // ASSERT
2295+ __ bind (resolved);
2296+
2297+ Label L_no_push;
2298+ // Check if there is an appendix
2299+ __ ld_bu (index, Address (cache, in_bytes (ResolvedIndyEntry::flags_offset ())));
2300+ __ andi (AT, index, 1UL << ResolvedIndyEntry::has_appendix_shift);
2301+ __ beqz (AT, L_no_push);
2302+
2303+ // Get appendix
2304+ __ ld_hu (index, Address (cache, in_bytes (ResolvedIndyEntry::resolved_references_index_offset ())));
2305+ // Push the appendix as a trailing parameter
2306+ // since the parameter_size includes it.
2307+ __ push (method);
2308+ __ move (method, index);
2309+ __ load_resolved_reference_at_index (appendix, method, A1);
2310+ __ verify_oop (appendix);
2311+ __ pop (method);
2312+ __ push (appendix); // push appendix (MethodType, CallSite, etc.)
2313+ __ bind (L_no_push);
2314+
2315+ // compute return type
2316+ __ ld_bu (index, Address (cache, in_bytes (ResolvedIndyEntry::result_type_offset ())));
2317+ // load return address
2318+ // Return address is loaded into ra and not pushed to the stack like x86
2319+ {
2320+ const address table_addr = (address) Interpreter::invoke_return_entry_table_for (code);
2321+ __ li (AT, table_addr);
2322+ __ alsl_d (AT, index, AT, 3 -1 );
2323+ __ ld_d (RA, AT, 0 );
2324+ }
2325+ }
2326+
22592327// get the method, itable_index and flags of the current invoke
22602328void TemplateTable::load_invoke_cp_cache_entry (int byte_no,
22612329 Register method,
22622330 Register itable_index,
22632331 Register flags,
22642332 bool is_invokevirtual,
22652333 bool is_invokevfinal, /* unused*/
2266- bool is_invokedynamic) {
2334+ bool is_invokedynamic /* unused */ ) {
22672335 // setup registers
22682336 const Register cache = T3;
22692337 const Register index = T1;
@@ -2284,7 +2352,7 @@ void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
22842352 const int index_offset = in_bytes (ConstantPoolCache::base_offset () +
22852353 ConstantPoolCacheEntry::f2_offset ());
22862354
2287- size_t index_size = (is_invokedynamic ? sizeof (u4): sizeof (u2) );
2355+ size_t index_size = sizeof (u2 );
22882356 resolve_cache_and_index (byte_no, cache, index, index_size);
22892357
22902358 __ alsl_d (AT, index, cache, Address::times_ptr - 1 );
@@ -3172,7 +3240,7 @@ void TemplateTable::prepare_invoke(int byte_no,
31723240
31733241 load_invoke_cp_cache_entry (byte_no, method, index, flags, is_invokevirtual, false , is_invokedynamic);
31743242
3175- if (is_invokedynamic || is_invokehandle) {
3243+ if (is_invokehandle) {
31763244 Label L_no_push;
31773245 __ li (AT, (1 << ConstantPoolCacheEntry::has_appendix_shift));
31783246 __ andr (AT, AT, flags);
@@ -3497,32 +3565,32 @@ void TemplateTable::invokehandle(int byte_no) {
34973565 __ jump_from_interpreted (T2_method);
34983566}
34993567
3500- void TemplateTable::invokedynamic (int byte_no) {
3501- transition (vtos, vtos);
3502- assert (byte_no == f1_byte, " use this argument" );
3568+ void TemplateTable::invokedynamic (int byte_no) {
3569+ transition (vtos, vtos);
3570+ assert (byte_no == f1_byte, " use this argument" );
35033571
3504- const Register T2_callsite = T2;
3572+ const Register T2_callsite = T2;
35053573
3506- prepare_invoke (byte_no, Rmethod, T2_callsite );
3574+ load_invokedynamic_entry ( Rmethod);
35073575
3508- // T2: CallSite object (from cpool->resolved_references[f1])
3509- // Rmethod: MH.linkToCallSite method (from f2)
3576+ // T2: CallSite object (from cpool->resolved_references[f1])
3577+ // Rmethod: MH.linkToCallSite method (from f2)
35103578
3511- // Note: T2_callsite is already pushed by prepare_invoke
3512- // %%% should make a type profile for any invokedynamic that takes a ref argument
3513- // profile this call
3514- __ profile_call (T4);
3579+ // Note: T2_callsite is already pushed by prepare_invoke
3580+ // %%% should make a type profile for any invokedynamic that takes a ref argument
3581+ // profile this call
3582+ __ profile_call (T4);
35153583
3516- // T8: tmp, used for mdp
3517- // Rmethod: callee
3518- // T4: tmp
3519- // is_virtual: false
3520- __ profile_arguments_type (T8, Rmethod, T4, false );
3584+ // T8: tmp, used for mdp
3585+ // Rmethod: callee
3586+ // T4: tmp
3587+ // is_virtual: false
3588+ __ profile_arguments_type (T8, Rmethod, T4, false );
35213589
3522- __ verify_oop (T2_callsite);
3590+ __ verify_oop (T2_callsite);
35233591
3524- __ jump_from_interpreted (Rmethod);
3525- }
3592+ __ jump_from_interpreted (Rmethod);
3593+ }
35263594
35273595// -----------------------------------------------------------------------------
35283596// Allocation
0 commit comments