# HG changeset patch # User bulasevich # Date 1535971378 -10800 # Node ID 4871c2d2e97e18599012d28b7ef0367ad8e9a326 # Parent dca697c71e5d138bfbd0ca864b5062bf3f3afbf1 8209408: Primitive heap access for interpreter BarrierSetAssembler/arm32 Reviewed-by: rkennke diff -r dca697c71e5d -r 4871c2d2e97e src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp --- a/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp Mon Sep 03 13:39:35 2018 +0300 +++ b/src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp Mon Sep 03 13:42:58 2018 +0300 @@ -50,6 +50,43 @@ } break; } + case T_BOOLEAN: __ ldrb (dst, src); break; + case T_BYTE: __ ldrsb (dst, src); break; + case T_CHAR: __ ldrh (dst, src); break; + case T_SHORT: __ ldrsh (dst, src); break; + case T_INT: __ ldr_s32 (dst, src); break; + case T_ADDRESS: __ ldr (dst, src); break; + case T_LONG: +#ifdef AARCH64 + __ ldr (dst, src); break; +#else + assert(dst == noreg, "only to ltos"); + __ add (src.index(), src.index(), src.base()); + __ ldmia (src.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); +#endif // AARCH64 + break; +#ifdef __SOFTFP__ + case T_FLOAT: + assert(dst == noreg, "only to ftos"); + __ ldr (R0_tos, src); + break; + case T_DOUBLE: + assert(dst == noreg, "only to dtos"); + __ add (src.index(), src.index(), src.base()); + __ ldmia (src.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); + break; +#else + case T_FLOAT: + assert(dst == noreg, "only to ftos"); + __ add(src.index(), src.index(), src.base()); + __ ldr_float (S0_tos, src.index()); + break; + case T_DOUBLE: + assert(dst == noreg, "only to dtos"); + __ add (src.index(), src.index(), src.base()); + __ ldr_double (D0_tos, src.index()); + break; +#endif default: Unimplemented(); } @@ -73,7 +110,7 @@ } else #endif // AARCH64 { - __ str(val, obj); + __ str(val, obj); } } else { assert(in_native, "why else?"); @@ -81,6 +118,46 @@ } break; } + case T_BOOLEAN: + __ and_32(val, val, 1); + __ strb(val, obj); + break; + case T_BYTE: __ strb (val, obj); break; + case T_CHAR: __ strh (val, obj); break; + case T_SHORT: __ strh (val, obj); break; + case T_INT: __ str (val, obj); break; + case T_ADDRESS: __ str (val, obj); break; + case T_LONG: +#ifdef AARCH64 + __ str (val, obj); break; +#else // AARCH64 + assert(val == noreg, "only tos"); + __ add (obj.index(), obj.index(), obj.base()); + __ stmia (obj.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); +#endif // AARCH64 + break; +#ifdef __SOFTFP__ + case T_FLOAT: + assert(val == noreg, "only tos"); + __ str (R0_tos, obj); + break; + case T_DOUBLE: + assert(val == noreg, "only tos"); + __ add (obj.index(), obj.index(), obj.base()); + __ stmia (obj.index(), RegisterSet(R0_tos_lo) | RegisterSet(R1_tos_hi)); + break; +#else + case T_FLOAT: + assert(val == noreg, "only tos"); + __ add (obj.index(), obj.index(), obj.base()); + __ str_float (S0_tos, obj.index()); + break; + case T_DOUBLE: + assert(val == noreg, "only tos"); + __ add (obj.index(), obj.index(), obj.base()); + __ str_double (D0_tos, obj.index()); + break; +#endif default: Unimplemented(); } } diff -r dca697c71e5d -r 4871c2d2e97e src/hotspot/cpu/arm/interp_masm_arm.cpp --- a/src/hotspot/cpu/arm/interp_masm_arm.cpp Mon Sep 03 13:39:35 2018 +0300 +++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp Mon Sep 03 13:42:58 2018 +0300 @@ -302,8 +302,9 @@ // Add in the index // convert from field index to resolved_references() index and from // word index to byte offset. Since this is a java object, it can be compressed - add(cache, cache, AsmOperand(index, lsl, LogBytesPerHeapOop)); - load_heap_oop(result, Address(cache, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + logical_shift_left(index, index, LogBytesPerHeapOop); + add(index, index, arrayOopDesc::base_offset_in_bytes(T_OBJECT)); + load_heap_oop(result, Address(cache, index)); } void InterpreterMacroAssembler::load_resolved_klass_at_offset( diff -r dca697c71e5d -r 4871c2d2e97e src/hotspot/cpu/arm/methodHandles_arm.cpp --- a/src/hotspot/cpu/arm/methodHandles_arm.cpp Mon Sep 03 13:39:35 2018 +0300 +++ b/src/hotspot/cpu/arm/methodHandles_arm.cpp Mon Sep 03 13:42:58 2018 +0300 @@ -162,7 +162,7 @@ __ load_heap_oop(Rmethod, Address(tmp, NONZERO(java_lang_invoke_MemberName::method_offset_in_bytes()))); __ verify_oop(Rmethod); - __ ldr(Rmethod, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes()))); + __ access_load_at(T_ADDRESS, IN_HEAP, Address(Rmethod, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset_in_bytes())), Rmethod, noreg, noreg, noreg); if (VerifyMethodHandles && !for_compiler_entry) { // make sure recv is already on stack @@ -381,7 +381,7 @@ verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3); } __ load_heap_oop(Rmethod, member_vmtarget); - __ ldr(Rmethod, vmtarget_method); + __ access_load_at(T_ADDRESS, IN_HEAP, vmtarget_method, Rmethod, noreg, noreg, noreg); break; case vmIntrinsics::_linkToStatic: @@ -389,7 +389,7 @@ verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3); } __ load_heap_oop(Rmethod, member_vmtarget); - __ ldr(Rmethod, vmtarget_method); + __ access_load_at(T_ADDRESS, IN_HEAP, vmtarget_method, Rmethod, noreg, noreg, noreg); break; break; @@ -404,7 +404,7 @@ // pick out the vtable index from the MemberName, and then we can discard it: Register temp2_index = temp2; - __ ldr(temp2_index, member_vmindex); + __ access_load_at(T_ADDRESS, IN_HEAP, member_vmindex, temp2_index, noreg, noreg, noreg); if (VerifyMethodHandles) { Label L_index_ok; @@ -436,7 +436,7 @@ __ verify_klass_ptr(temp3_intf); Register rbx_index = rbx_method; - __ ldr(rbx_index, member_vmindex); + __ access_load_at(T_ADDRESS, IN_HEAP, member_vmindex, rbx_index, noreg, noreg, noreg); if (VerifyMethodHandles) { Label L; __ cmp(rbx_index, 0); diff -r dca697c71e5d -r 4871c2d2e97e src/hotspot/cpu/arm/templateTable_arm.cpp --- a/src/hotspot/cpu/arm/templateTable_arm.cpp Mon Sep 03 13:39:35 2018 +0300 +++ b/src/hotspot/cpu/arm/templateTable_arm.cpp Mon Sep 03 13:42:58 2018 +0300 @@ -161,6 +161,18 @@ return Address(temp, arrayOopDesc::base_offset_in_bytes(elemType)); } +// Returns address of Java array element using temp register as offset from array base +Address TemplateTable::get_array_elem_addr_same_base(BasicType elemType, Register array, Register index, Register temp) { + int logElemSize = exact_log2(type2aelembytes(elemType)); + if (logElemSize == 0) { + __ add(temp, index, arrayOopDesc::base_offset_in_bytes(elemType)); + } else { + __ mov(temp, arrayOopDesc::base_offset_in_bytes(elemType)); + __ add_ptr_scaled_int32(temp, temp, index, logElemSize); + } + return Address(array, temp); +} + //---------------------------------------------------------------------------------------------------- // Condition conversion AsmCondition convNegCond(TemplateTable::Condition cc) { @@ -883,7 +895,8 @@ const Register Rindex = R0_tos; index_check(Rarray, Rindex); - __ ldr_s32(R0_tos, get_array_elem_addr(T_INT, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_INT, Rarray, Rindex, Rtemp); + __ access_load_at(T_INT, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg); } @@ -897,9 +910,8 @@ #ifdef AARCH64 __ ldr(R0_tos, get_array_elem_addr(T_LONG, Rarray, Rindex, Rtemp)); #else - __ add(Rtemp, Rarray, AsmOperand(Rindex, lsl, LogBytesPerLong)); - __ add(Rtemp, Rtemp, arrayOopDesc::base_offset_in_bytes(T_LONG)); - __ ldmia(Rtemp, RegisterSet(R0_tos_lo, R1_tos_hi)); + Address addr = get_array_elem_addr_same_base(T_LONG, Rarray, Rindex, Rtemp); + __ access_load_at(T_LONG, IN_HEAP | IS_ARRAY, addr, noreg /* ltos */, noreg, noreg, noreg); #endif // AARCH64 } @@ -911,12 +923,8 @@ index_check(Rarray, Rindex); - Address addr = get_array_elem_addr(T_FLOAT, Rarray, Rindex, Rtemp); -#ifdef __SOFTFP__ - __ ldr(R0_tos, addr); -#else - __ ldr_float(S0_tos, addr); -#endif // __SOFTFP__ + Address addr = get_array_elem_addr_same_base(T_FLOAT, Rarray, Rindex, Rtemp); + __ access_load_at(T_FLOAT, IN_HEAP | IS_ARRAY, addr, noreg /* ftos */, noreg, noreg, noreg); } @@ -927,13 +935,8 @@ index_check(Rarray, Rindex); -#ifdef __SOFTFP__ - __ add(Rtemp, Rarray, AsmOperand(Rindex, lsl, LogBytesPerLong)); - __ add(Rtemp, Rtemp, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)); - __ ldmia(Rtemp, RegisterSet(R0_tos_lo, R1_tos_hi)); -#else - __ ldr_double(D0_tos, get_array_elem_addr(T_DOUBLE, Rarray, Rindex, Rtemp)); -#endif // __SOFTFP__ + Address addr = get_array_elem_addr_same_base(T_DOUBLE, Rarray, Rindex, Rtemp); + __ access_load_at(T_DOUBLE, IN_HEAP | IS_ARRAY, addr, noreg /* dtos */, noreg, noreg, noreg); } @@ -943,7 +946,7 @@ const Register Rindex = R0_tos; index_check(Rarray, Rindex); - do_oop_load(_masm, R0_tos, get_array_elem_addr(T_OBJECT, Rarray, Rindex, Rtemp), IS_ARRAY); + do_oop_load(_masm, R0_tos, get_array_elem_addr_same_base(T_OBJECT, Rarray, Rindex, Rtemp), IS_ARRAY); } @@ -953,7 +956,8 @@ const Register Rindex = R0_tos; index_check(Rarray, Rindex); - __ ldrsb(R0_tos, get_array_elem_addr(T_BYTE, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_BYTE, Rarray, Rindex, Rtemp); + __ access_load_at(T_BYTE, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg); } @@ -963,7 +967,8 @@ const Register Rindex = R0_tos; index_check(Rarray, Rindex); - __ ldrh(R0_tos, get_array_elem_addr(T_CHAR, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_CHAR, Rarray, Rindex, Rtemp); + __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg); } @@ -983,7 +988,8 @@ // get array element index_check(Rarray, Rindex); - __ ldrh(R0_tos, get_array_elem_addr(T_CHAR, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_CHAR, Rarray, Rindex, Rtemp); + __ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg); } @@ -993,7 +999,8 @@ const Register Rindex = R0_tos; index_check(Rarray, Rindex); - __ ldrsh(R0_tos, get_array_elem_addr(T_SHORT, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_SHORT, Rarray, Rindex, Rtemp); + __ access_load_at(T_SHORT, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg); } @@ -1231,7 +1238,8 @@ __ pop_i(Rindex); index_check(Rarray, Rindex); - __ str_32(R0_tos, get_array_elem_addr(T_INT, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_INT, Rarray, Rindex, Rtemp); + __ access_store_at(T_INT, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg, false); } @@ -1247,9 +1255,8 @@ #ifdef AARCH64 __ str(R0_tos, get_array_elem_addr(T_LONG, Rarray, Rindex, Rtemp)); #else - __ add(Rtemp, Rarray, AsmOperand(Rindex, lsl, LogBytesPerLong)); - __ add(Rtemp, Rtemp, arrayOopDesc::base_offset_in_bytes(T_LONG)); - __ stmia(Rtemp, RegisterSet(R0_tos_lo, R1_tos_hi)); + Address addr = get_array_elem_addr_same_base(T_LONG, Rarray, Rindex, Rtemp); + __ access_store_at(T_LONG, IN_HEAP | IS_ARRAY, addr, noreg /* ltos */, noreg, noreg, noreg, false); #endif // AARCH64 } @@ -1262,13 +1269,8 @@ __ pop_i(Rindex); index_check(Rarray, Rindex); - Address addr = get_array_elem_addr(T_FLOAT, Rarray, Rindex, Rtemp); - -#ifdef __SOFTFP__ - __ str(R0_tos, addr); -#else - __ str_float(S0_tos, addr); -#endif // __SOFTFP__ + Address addr = get_array_elem_addr_same_base(T_FLOAT, Rarray, Rindex, Rtemp); + __ access_store_at(T_FLOAT, IN_HEAP | IS_ARRAY, addr, noreg /* ftos */, noreg, noreg, noreg, false); } @@ -1281,13 +1283,8 @@ __ pop_i(Rindex); index_check(Rarray, Rindex); -#ifdef __SOFTFP__ - __ add(Rtemp, Rarray, AsmOperand(Rindex, lsl, LogBytesPerLong)); - __ add(Rtemp, Rtemp, arrayOopDesc::base_offset_in_bytes(T_DOUBLE)); - __ stmia(Rtemp, RegisterSet(R0_tos_lo, R1_tos_hi)); -#else - __ str_double(D0_tos, get_array_elem_addr(T_DOUBLE, Rarray, Rindex, Rtemp)); -#endif // __SOFTFP__ + Address addr = get_array_elem_addr_same_base(T_DOUBLE, Rarray, Rindex, Rtemp); + __ access_store_at(T_DOUBLE, IN_HEAP | IS_ARRAY, addr, noreg /* dtos */, noreg, noreg, noreg, false); } @@ -1370,7 +1367,8 @@ __ b(L_skip, eq); __ and_32(R0_tos, R0_tos, 1); // if it is a T_BOOLEAN array, mask the stored value to 0/1 __ bind(L_skip); - __ strb(R0_tos, get_array_elem_addr(T_BYTE, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_BYTE, Rarray, Rindex, Rtemp); + __ access_store_at(T_BYTE, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg, false); } @@ -1382,8 +1380,8 @@ __ pop_i(Rindex); index_check(Rarray, Rindex); - - __ strh(R0_tos, get_array_elem_addr(T_CHAR, Rarray, Rindex, Rtemp)); + Address addr = get_array_elem_addr_same_base(T_CHAR, Rarray, Rindex, Rtemp); + __ access_store_at(T_CHAR, IN_HEAP | IS_ARRAY, addr, R0_tos, noreg, noreg, noreg, false); } @@ -3182,7 +3180,7 @@ // modes. // Size of fixed size code block for fast_version - const int log_max_block_size = 2; + const int log_max_block_size = AARCH64_ONLY(2) NOT_AARCH64(3); const int max_block_size = 1 << log_max_block_size; // Decide if fast version is enabled @@ -3249,7 +3247,7 @@ assert(btos == seq++, "btos has unexpected value"); FixedSizeCodeBlock btos_block(_masm, max_block_size, fast_version); __ bind(Lbtos); - __ ldrsb(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_BYTE, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); __ push(btos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -3263,7 +3261,7 @@ assert(ztos == seq++, "btos has unexpected value"); FixedSizeCodeBlock ztos_block(_masm, max_block_size, fast_version); __ bind(Lztos); - __ ldrsb(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_BOOLEAN, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); __ push(ztos); // Rewrite bytecode to be faster (use btos fast getfield) if (!is_static && rc == may_rewrite) { @@ -3277,7 +3275,7 @@ assert(ctos == seq++, "ctos has unexpected value"); FixedSizeCodeBlock ctos_block(_masm, max_block_size, fast_version); __ bind(Lctos); - __ ldrh(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_CHAR, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); __ push(ctos); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_cgetfield, R0_tmp, Rtemp); @@ -3290,7 +3288,7 @@ assert(stos == seq++, "stos has unexpected value"); FixedSizeCodeBlock stos_block(_masm, max_block_size, fast_version); __ bind(Lstos); - __ ldrsh(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_SHORT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); __ push(stos); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_sgetfield, R0_tmp, Rtemp); @@ -3314,8 +3312,7 @@ #ifdef AARCH64 __ ldr(R0_tos, Address(Robj, Roffset)); #else - __ add(Roffset, Robj, Roffset); - __ ldmia(Roffset, RegisterSet(R0_tos_lo, R1_tos_hi)); + __ access_load_at(T_LONG, IN_HEAP, Address(Robj, Roffset), noreg /* ltos */, noreg, noreg, noreg); #endif // AARCH64 __ push(ltos); if (!is_static && rc == may_rewrite) { @@ -3331,7 +3328,7 @@ __ bind(Lftos); // floats and ints are placed on stack in same way, so // we can use push(itos) to transfer value without using VFP - __ ldr_u32(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); __ push(itos); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_fgetfield, R0_tmp, Rtemp); @@ -3349,8 +3346,7 @@ #ifdef AARCH64 __ ldr(R0_tos, Address(Robj, Roffset)); #else - __ add(Rtemp, Robj, Roffset); - __ ldmia(Rtemp, RegisterSet(R0_tos_lo, R1_tos_hi)); + __ access_load_at(T_LONG, IN_HEAP, Address(Robj, Roffset), noreg /* ltos */, noreg, noreg, noreg); #endif // AARCH64 __ push(ltos); if (!is_static && rc == may_rewrite) { @@ -3385,7 +3381,7 @@ // atos case can be merged with itos case (and thus moved out of table switch) on 32-bit ARM, fast version only __ bind(Lint); - __ ldr_s32(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); __ push(itos); // Rewrite bytecode to be faster if (!is_static && rc == may_rewrite) { @@ -3597,7 +3593,7 @@ __ bind(Lbtos); __ pop(btos); if (!is_static) pop_and_check_object(Robj); - __ strb(R0_tos, Address(Robj, Roffset)); + __ access_store_at(T_BYTE, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg, false); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_bputfield, R0_tmp, Rtemp, true, byte_no); } @@ -3611,8 +3607,7 @@ __ bind(Lztos); __ pop(ztos); if (!is_static) pop_and_check_object(Robj); - __ and_32(R0_tos, R0_tos, 1); - __ strb(R0_tos, Address(Robj, Roffset)); + __ access_store_at(T_BOOLEAN, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg, false); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_zputfield, R0_tmp, Rtemp, true, byte_no); } @@ -3626,7 +3621,7 @@ __ bind(Lctos); __ pop(ctos); if (!is_static) pop_and_check_object(Robj); - __ strh(R0_tos, Address(Robj, Roffset)); + __ access_store_at(T_CHAR, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg, false); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_cputfield, R0_tmp, Rtemp, true, byte_no); } @@ -3640,7 +3635,7 @@ __ bind(Lstos); __ pop(stos); if (!is_static) pop_and_check_object(Robj); - __ strh(R0_tos, Address(Robj, Roffset)); + __ access_store_at(T_SHORT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg, false); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_sputfield, R0_tmp, Rtemp, true, byte_no); } @@ -3665,8 +3660,7 @@ #ifdef AARCH64 __ str(R0_tos, Address(Robj, Roffset)); #else - __ add(Roffset, Robj, Roffset); - __ stmia(Roffset, RegisterSet(R0_tos_lo, R1_tos_hi)); + __ access_store_at(T_LONG, IN_HEAP, Address(Robj, Roffset), noreg /* ltos */, noreg, noreg, noreg, false); #endif // AARCH64 if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_lputfield, R0_tmp, Rtemp, true, byte_no); @@ -3683,7 +3677,7 @@ // we can use pop(itos) to transfer value without using VFP __ pop(itos); if (!is_static) pop_and_check_object(Robj); - __ str_32(R0_tos, Address(Robj, Roffset)); + __ access_store_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg, false); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_fputfield, R0_tmp, Rtemp, true, byte_no); } @@ -3702,8 +3696,7 @@ #ifdef AARCH64 __ str(R0_tos, Address(Robj, Roffset)); #else - __ add(Rtemp, Robj, Roffset); - __ stmia(Rtemp, RegisterSet(R0_tos_lo, R1_tos_hi)); + __ access_store_at(T_LONG, IN_HEAP, Address(Robj, Roffset), noreg /* ltos */, noreg, noreg, noreg, false); #endif // AARCH64 if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_dputfield, R0_tmp, Rtemp, true, byte_no); @@ -3732,7 +3725,7 @@ __ bind(Lint); __ pop(itos); if (!is_static) pop_and_check_object(Robj); - __ str_32(R0_tos, Address(Robj, Roffset)); + __ access_store_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg, false); if (!is_static && rc == may_rewrite) { patch_bytecode(Bytecodes::_fast_iputfield, R0_tmp, Rtemp, true, byte_no); } @@ -3867,36 +3860,42 @@ // Get object from stack pop_and_check_object(Robj); + Address addr = Address(Robj, Roffset); // access field switch (bytecode()) { - case Bytecodes::_fast_zputfield: __ and_32(R0_tos, R0_tos, 1); - // fall through - case Bytecodes::_fast_bputfield: __ strb(R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_sputfield: // fall through - case Bytecodes::_fast_cputfield: __ strh(R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_iputfield: __ str_32(R0_tos, Address(Robj, Roffset)); break; + case Bytecodes::_fast_zputfield: + __ access_store_at(T_BOOLEAN, IN_HEAP, addr, R0_tos, noreg, noreg, noreg, false); + break; + case Bytecodes::_fast_bputfield: + __ access_store_at(T_BYTE, IN_HEAP, addr, R0_tos, noreg, noreg, noreg, false); + break; + case Bytecodes::_fast_sputfield: + __ access_store_at(T_SHORT, IN_HEAP, addr, R0_tos, noreg, noreg, noreg, false); + break; + case Bytecodes::_fast_cputfield: + __ access_store_at(T_CHAR, IN_HEAP, addr, R0_tos, noreg, noreg, noreg,false); + break; + case Bytecodes::_fast_iputfield: + __ access_store_at(T_INT, IN_HEAP, addr, R0_tos, noreg, noreg, noreg, false); + break; #ifdef AARCH64 - case Bytecodes::_fast_lputfield: __ str (R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_fputfield: __ str_s(S0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_dputfield: __ str_d(D0_tos, Address(Robj, Roffset)); break; + case Bytecodes::_fast_lputfield: __ str (R0_tos, addr); break; + case Bytecodes::_fast_fputfield: __ str_s(S0_tos, addr); break; + case Bytecodes::_fast_dputfield: __ str_d(D0_tos, addr); break; #else - case Bytecodes::_fast_lputfield: __ add(Robj, Robj, Roffset); - __ stmia(Robj, RegisterSet(R0_tos_lo, R1_tos_hi)); break; - -#ifdef __SOFTFP__ - case Bytecodes::_fast_fputfield: __ str(R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_dputfield: __ add(Robj, Robj, Roffset); - __ stmia(Robj, RegisterSet(R0_tos_lo, R1_tos_hi)); break; -#else - case Bytecodes::_fast_fputfield: __ add(Robj, Robj, Roffset); - __ fsts(S0_tos, Address(Robj)); break; - case Bytecodes::_fast_dputfield: __ add(Robj, Robj, Roffset); - __ fstd(D0_tos, Address(Robj)); break; -#endif // __SOFTFP__ + case Bytecodes::_fast_lputfield: + __ access_store_at(T_LONG, IN_HEAP, addr, noreg, noreg, noreg, noreg, false); + break; + case Bytecodes::_fast_fputfield: + __ access_store_at(T_FLOAT, IN_HEAP, addr, noreg, noreg, noreg, noreg, false); + break; + case Bytecodes::_fast_dputfield: + __ access_store_at(T_DOUBLE, IN_HEAP, addr, noreg, noreg, noreg, noreg, false); + break; #endif // AARCH64 case Bytecodes::_fast_aputfield: - do_oop_store(_masm, Address(Robj, Roffset), R0_tos, Rtemp, R1_tmp, R2_tmp, false); + do_oop_store(_masm, addr, R0_tos, Rtemp, R1_tmp, R2_tmp, false); break; default: @@ -3970,29 +3969,40 @@ __ verify_oop(Robj); __ null_check(Robj, Rtemp); + Address addr = Address(Robj, Roffset); // access field switch (bytecode()) { - case Bytecodes::_fast_bgetfield: __ ldrsb(R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_sgetfield: __ ldrsh(R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_cgetfield: __ ldrh (R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_igetfield: __ ldr_s32(R0_tos, Address(Robj, Roffset)); break; + case Bytecodes::_fast_bgetfield: + __ access_load_at(T_BYTE, IN_HEAP, addr, R0_tos, noreg, noreg, noreg); + break; + case Bytecodes::_fast_sgetfield: + __ access_load_at(T_SHORT, IN_HEAP, addr, R0_tos, noreg, noreg, noreg); + break; + case Bytecodes::_fast_cgetfield: + __ access_load_at(T_CHAR, IN_HEAP, addr, R0_tos, noreg, noreg, noreg); + break; + case Bytecodes::_fast_igetfield: + __ access_load_at(T_INT, IN_HEAP, addr, R0_tos, noreg, noreg, noreg); + break; #ifdef AARCH64 - case Bytecodes::_fast_lgetfield: __ ldr (R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_fgetfield: __ ldr_s(S0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_dgetfield: __ ldr_d(D0_tos, Address(Robj, Roffset)); break; + case Bytecodes::_fast_lgetfield: __ ldr (R0_tos, addr); break; + case Bytecodes::_fast_fgetfield: __ ldr_s(S0_tos, addr); break; + case Bytecodes::_fast_dgetfield: __ ldr_d(D0_tos, addr); break; #else - case Bytecodes::_fast_lgetfield: __ add(Roffset, Robj, Roffset); - __ ldmia(Roffset, RegisterSet(R0_tos_lo, R1_tos_hi)); break; -#ifdef __SOFTFP__ - case Bytecodes::_fast_fgetfield: __ ldr (R0_tos, Address(Robj, Roffset)); break; - case Bytecodes::_fast_dgetfield: __ add(Roffset, Robj, Roffset); - __ ldmia(Roffset, RegisterSet(R0_tos_lo, R1_tos_hi)); break; -#else - case Bytecodes::_fast_fgetfield: __ add(Roffset, Robj, Roffset); __ flds(S0_tos, Address(Roffset)); break; - case Bytecodes::_fast_dgetfield: __ add(Roffset, Robj, Roffset); __ fldd(D0_tos, Address(Roffset)); break; -#endif // __SOFTFP__ + case Bytecodes::_fast_lgetfield: + __ access_load_at(T_LONG, IN_HEAP, addr, noreg, noreg, noreg, noreg); + break; + case Bytecodes::_fast_fgetfield: + __ access_load_at(T_FLOAT, IN_HEAP, addr, noreg, noreg, noreg, noreg); + break; + case Bytecodes::_fast_dgetfield: + __ access_load_at(T_DOUBLE, IN_HEAP, addr, noreg, noreg, noreg, noreg); + break; #endif // AARCH64 - case Bytecodes::_fast_agetfield: do_oop_load(_masm, R0_tos, Address(Robj, Roffset)); __ verify_oop(R0_tos); break; + case Bytecodes::_fast_agetfield: + do_oop_load(_masm, R0_tos, addr); + __ verify_oop(R0_tos); + break; default: ShouldNotReachHere(); } @@ -4070,7 +4080,7 @@ #endif // AARCH64 if (state == itos) { - __ ldr_s32(R0_tos, Address(Robj, Roffset)); + __ access_load_at(T_INT, IN_HEAP, Address(Robj, Roffset), R0_tos, noreg, noreg, noreg); } else if (state == atos) { do_oop_load(_masm, R0_tos, Address(Robj, Roffset)); __ verify_oop(R0_tos); @@ -4081,8 +4091,7 @@ #ifdef __SOFTFP__ __ ldr(R0_tos, Address(Robj, Roffset)); #else - __ add(Roffset, Robj, Roffset); - __ flds(S0_tos, Address(Roffset)); + __ access_load_at(T_FLOAT, IN_HEAP, Address(Robj, Roffset), noreg /* ftos */, noreg, noreg, noreg); #endif // __SOFTFP__ #endif // AARCH64 } else { diff -r dca697c71e5d -r 4871c2d2e97e src/hotspot/cpu/arm/templateTable_arm.hpp --- a/src/hotspot/cpu/arm/templateTable_arm.hpp Mon Sep 03 13:39:35 2018 +0300 +++ b/src/hotspot/cpu/arm/templateTable_arm.hpp Mon Sep 03 13:42:58 2018 +0300 @@ -55,6 +55,7 @@ static void store_category2_local(Register Rlocal_index, Register tmp); static Address get_array_elem_addr(BasicType elemType, Register array, Register index, Register temp); + static Address get_array_elem_addr_same_base(BasicType elemType, Register array, Register index, Register temp); static void jvmti_post_fast_field_mod(TosState state);