< prev index next >

src/hotspot/cpu/s390/templateTable_s390.cpp

Print this page




2387     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint));
2388     __ pop(state);
2389     __ bind(no_safepoint);
2390   }
2391 
2392   if (state == itos) {
2393     // Narrow result if state is itos but result type is smaller.
2394     // Need to narrow in the return bytecode rather than in generate_return_entry
2395     // since compiled code callers expect the result to already be narrowed.
2396     __ narrow(Z_tos, Z_tmp_1); /* fall through */
2397   }
2398 
2399   __ remove_activation(state, Z_R14);
2400   __ z_br(Z_R14);
2401 }
2402 
2403 // ----------------------------------------------------------------------------
2404 // NOTE: Cpe_offset is already computed as byte offset, so we must not
2405 // shift it afterwards!
2406 void TemplateTable::resolve_cache_and_index(int byte_no,
2407                                             Register cache,
2408                                             Register cpe_offset,
2409                                             size_t index_size) {
2410   BLOCK_COMMENT("resolve_cache_and_index {");
2411   NearLabel      resolved, clinit_barrier_slow;
2412   const Register bytecode_in_cpcache = Z_R1_scratch;
2413   const int      total_f1_offset = in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f1_offset());
2414   assert_different_registers(cache, cpe_offset, bytecode_in_cpcache);
2415 
2416   Bytecodes::Code code = bytecode();
2417   switch (code) {
2418     case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
2419     case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
2420     default:
2421       break;
2422   }
2423 
2424   {
2425     assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2426     __ get_cache_and_index_and_bytecode_at_bcp(cache, cpe_offset, bytecode_in_cpcache, byte_no, 1, index_size);
2427     // Have we resolved this bytecode?
2428     __ compare32_and_branch(bytecode_in_cpcache, (int)code, Assembler::bcondEqual, resolved);
2429   }
2430 
2431   // Resolve first time through.
2432   // Class initialization barrier slow path lands here as well.
2433   __ bind(clinit_barrier_slow);
2434   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2435   __ load_const_optimized(Z_ARG2, (int) code);
2436   __ call_VM(noreg, entry, Z_ARG2);
2437 
2438   // Update registers with resolved info.
2439   __ get_cache_and_index_at_bcp(cache, cpe_offset, 1, index_size);
2440   __ bind(resolved);
2441 
2442   // Class initialization barrier for static methods
2443   if (VM_Version::supports_fast_class_init_checks() && bytecode() == Bytecodes::_invokestatic) {
2444     const Register method = Z_R1_scratch;
2445     const Register klass  = Z_R1_scratch;
2446 
2447     __ load_resolved_method_at_index(byte_no, cache, cpe_offset, method);
2448     __ load_method_holder(klass, method);
2449     __ clinit_barrier(klass, Z_thread, NULL /*L_fast_path*/, &clinit_barrier_slow);
2450   }
2451 
2452   BLOCK_COMMENT("} resolve_cache_and_index");
2453 }
2454 
2455 // The Rcache and index registers must be set before call.
2456 // Index is already a byte offset, don't shift!
2457 void TemplateTable::load_field_cp_cache_entry(Register obj,
2458                                               Register cache,
2459                                               Register index,
2460                                               Register off,
2461                                               Register flags,
2462                                               bool is_static = false) {
2463   assert_different_registers(cache, index, flags, off);
2464   ByteSize cp_base_offset = ConstantPoolCache::base_offset();
2465 
2466   // Field offset
2467   __ mem2reg_opt(off, Address(cache, index, cp_base_offset + ConstantPoolCacheEntry::f2_offset()));
2468   // Flags. Must load 64 bits.
2469   __ mem2reg_opt(flags, Address(cache, index, cp_base_offset + ConstantPoolCacheEntry::flags_offset()));
2470 
2471   // klass overwrite register


3660 
3661   // do the call
3662   __ profile_final_call(Z_tmp_2);
3663   __ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true);
3664   __ jump_from_interpreted(method, Z_tmp_2);
3665 
3666   __ bind(notVFinal);
3667 
3668   // Get receiver klass into klass - also a null check.
3669   __ load_klass(klass, receiver);
3670 
3671   __ lookup_interface_method(klass, interface, noreg, noreg, /*temp*/Z_ARG1,
3672                              no_such_interface, /*return_method=*/false);
3673 
3674   // Profile this call.
3675   __ profile_virtual_call(klass, Z_ARG1/*mdp*/, flags/*scratch*/);
3676 
3677   // Find entry point to call.
3678 
3679   // Get declaring interface class from method
3680   __ load_method_holder(interface, method);


3681 
3682   // Get itable index from method
3683   Register index   = receiver,
3684            method2 = flags;
3685   __ z_lgf(index, Address(method, Method::itable_index_offset()));
3686   __ z_aghi(index, -Method::itable_index_max);
3687   __ z_lcgr(index, index);
3688 
3689   __ lookup_interface_method(klass, interface, index, method2, Z_tmp_2,
3690                              no_such_interface);
3691 
3692   // Check for abstract method error.
3693   // Note: This should be done more efficiently via a throw_abstract_method_error
3694   // interpreter entry point and a conditional jump to it in case of a null
3695   // method.
3696   __ compareU64_and_branch(method2, (intptr_t) 0,
3697                            Assembler::bcondZero, no_such_method);
3698 
3699   __ profile_arguments_type(Z_tmp_1, method2, Z_tmp_2, true);
3700 




2387     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint));
2388     __ pop(state);
2389     __ bind(no_safepoint);
2390   }
2391 
2392   if (state == itos) {
2393     // Narrow result if state is itos but result type is smaller.
2394     // Need to narrow in the return bytecode rather than in generate_return_entry
2395     // since compiled code callers expect the result to already be narrowed.
2396     __ narrow(Z_tos, Z_tmp_1); /* fall through */
2397   }
2398 
2399   __ remove_activation(state, Z_R14);
2400   __ z_br(Z_R14);
2401 }
2402 
2403 // ----------------------------------------------------------------------------
2404 // NOTE: Cpe_offset is already computed as byte offset, so we must not
2405 // shift it afterwards!
2406 void TemplateTable::resolve_cache_and_index(int byte_no,
2407                                             Register Rcache,
2408                                             Register cpe_offset,
2409                                             size_t index_size) {
2410   BLOCK_COMMENT("resolve_cache_and_index {");
2411   NearLabel      resolved;
2412   const Register bytecode_in_cpcache = Z_R1_scratch;
2413   const int      total_f1_offset = in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f1_offset());
2414   assert_different_registers(Rcache, cpe_offset, bytecode_in_cpcache);
2415 
2416   Bytecodes::Code code = bytecode();
2417   switch (code) {
2418     case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
2419     case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
2420     default:
2421       break;
2422   }
2423 
2424   {
2425     assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
2426     __ get_cache_and_index_and_bytecode_at_bcp(Rcache, cpe_offset, bytecode_in_cpcache, byte_no, 1, index_size);
2427     // Have we resolved this bytecode?
2428     __ compare32_and_branch(bytecode_in_cpcache, (int)code, Assembler::bcondEqual, resolved);
2429   }
2430 
2431   // Resolve first time through.


2432   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
2433   __ load_const_optimized(Z_ARG2, (int) code);
2434   __ call_VM(noreg, entry, Z_ARG2);
2435 
2436   // Update registers with resolved info.
2437   __ get_cache_and_index_at_bcp(Rcache, cpe_offset, 1, index_size);
2438   __ bind(resolved);











2439   BLOCK_COMMENT("} resolve_cache_and_index");
2440 }
2441 
2442 // The Rcache and index registers must be set before call.
2443 // Index is already a byte offset, don't shift!
2444 void TemplateTable::load_field_cp_cache_entry(Register obj,
2445                                               Register cache,
2446                                               Register index,
2447                                               Register off,
2448                                               Register flags,
2449                                               bool is_static = false) {
2450   assert_different_registers(cache, index, flags, off);
2451   ByteSize cp_base_offset = ConstantPoolCache::base_offset();
2452 
2453   // Field offset
2454   __ mem2reg_opt(off, Address(cache, index, cp_base_offset + ConstantPoolCacheEntry::f2_offset()));
2455   // Flags. Must load 64 bits.
2456   __ mem2reg_opt(flags, Address(cache, index, cp_base_offset + ConstantPoolCacheEntry::flags_offset()));
2457 
2458   // klass overwrite register


3647 
3648   // do the call
3649   __ profile_final_call(Z_tmp_2);
3650   __ profile_arguments_type(Z_tmp_2, method, Z_ARG5, true);
3651   __ jump_from_interpreted(method, Z_tmp_2);
3652 
3653   __ bind(notVFinal);
3654 
3655   // Get receiver klass into klass - also a null check.
3656   __ load_klass(klass, receiver);
3657 
3658   __ lookup_interface_method(klass, interface, noreg, noreg, /*temp*/Z_ARG1,
3659                              no_such_interface, /*return_method=*/false);
3660 
3661   // Profile this call.
3662   __ profile_virtual_call(klass, Z_ARG1/*mdp*/, flags/*scratch*/);
3663 
3664   // Find entry point to call.
3665 
3666   // Get declaring interface class from method
3667   __ z_lg(interface, Address(method, Method::const_offset()));
3668   __ z_lg(interface, Address(interface, ConstMethod::constants_offset()));
3669   __ z_lg(interface, Address(interface, ConstantPool::pool_holder_offset_in_bytes()));
3670 
3671   // Get itable index from method
3672   Register index   = receiver,
3673            method2 = flags;
3674   __ z_lgf(index, Address(method, Method::itable_index_offset()));
3675   __ z_aghi(index, -Method::itable_index_max);
3676   __ z_lcgr(index, index);
3677 
3678   __ lookup_interface_method(klass, interface, index, method2, Z_tmp_2,
3679                              no_such_interface);
3680 
3681   // Check for abstract method error.
3682   // Note: This should be done more efficiently via a throw_abstract_method_error
3683   // interpreter entry point and a conditional jump to it in case of a null
3684   // method.
3685   __ compareU64_and_branch(method2, (intptr_t) 0,
3686                            Assembler::bcondZero, no_such_method);
3687 
3688   __ profile_arguments_type(Z_tmp_1, method2, Z_tmp_2, true);
3689 


< prev index next >