changeset 52388:4871c2d2e97e

8209408: Primitive heap access for interpreter BarrierSetAssembler/arm32 Reviewed-by: rkennke
author bulasevich
date Mon, 03 Sep 2018 13:42:58 +0300
parents dca697c71e5d
children b0c81cfd4dc9
files src/hotspot/cpu/arm/gc/shared/barrierSetAssembler_arm.cpp src/hotspot/cpu/arm/interp_masm_arm.cpp src/hotspot/cpu/arm/methodHandles_arm.cpp src/hotspot/cpu/arm/templateTable_arm.cpp src/hotspot/cpu/arm/templateTable_arm.hpp
diffstat 5 files changed, 205 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- 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();
   }
 }
--- 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(
--- 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);
--- 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 {
--- 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);