Argh

Andrew Haley aph at redhat.com
Thu Nov 10 09:00:09 PST 2011


So, I'm trawling through jtreg failures to see which ones really
are VM bugs,and I notice that some java.util.concurrent tests are
failing, and even some really simple ones.  "Ah well," I thought,
"there must be some problem with the memory barrier code."  So, I
read through the source looking for the barriers.

And that was the problem.  There are no barriers.  None, nada,
zilch.  On ARM this is a really big problem: memory barriers are
essential.

I'm testing this patch.

Andrew.


2011-11-10  Andrew Haley  <aph at redhat.com>

        * openjdk-ecj/hotspot/src/cpu/zero/vm/thumb2.cpp (fullBarrier): New.
        (storeBarrier): New.
        (Thumb2_Accessor, Thumb2_codegen): Emit barriers for volatile
        fields.
        * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
        (TEST_VOLATILE, MAYBE_VOLATILE): New macros.
        * arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def (igetfield)
        (bgetfield, cgetfield, sgetfield, lgetfield, iputfield, cputfield)
        (bputfield, lputfield, getstatic, putstatic): Check for volatile
        fields.

diff -r 0e1ae9c38563 arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp
--- a/arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp	Tue Nov 08 06:03:17 2011 -0500
+++ b/arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp	Thu Nov 10 16:46:20 2011 +0000
@@ -489,6 +489,8 @@
   print_def("CONSTANTPOOL_CACHE", offset_of(constantPoolOopDesc, _cache));
   print_def("CONSTANTPOOL_POOL_HOLDER", offset_of(constantPoolOopDesc, _pool_holder));
   print_def("CONSTANTPOOL_BASE", sizeof(constantPoolOopDesc));
+  print_def("CP_CACHE_VOLATILE_FIELD_FLAG_BIT", ConstantPoolCacheEntry::volatileField);
+  print_def("CP_CACHE_FLAGS", offset_of(ConstantPoolCacheEntry, _flags));
   nl();
   print_def("CP_OFFSET", in_bytes(constantPoolCacheOopDesc::base_offset()));
   nl();
diff -r 0e1ae9c38563 arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def
--- a/arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Tue Nov 08 06:03:17 2011 -0500
+++ b/arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Thu Nov 10 16:46:20 2011 +0000
@@ -1573,10 +1573,12 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r3, tmp2
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry78:
 	ldr	tmp2, [tmp1, tmp2]
+	MAYBE_VOLATILE	r3
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	PUSH	tmp2
@@ -1592,10 +1594,12 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r3, tmp2
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry79:
 	ldrsb	tmp2, [tmp1, tmp2]
+	MAYBE_VOLATILE	r3
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	PUSH	tmp2
@@ -1611,10 +1615,12 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r3, tmp2
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry80:
 	ldrh	tmp2, [tmp1, tmp2]
+	MAYBE_VOLATILE	r3
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	PUSH	tmp2
@@ -1630,10 +1636,12 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r3, tmp2
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry81:
 	ldrsh	tmp2, [tmp1, tmp2]
+	MAYBE_VOLATILE	r3
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	PUSH	tmp2
@@ -1649,15 +1657,18 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r3, tmp2
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	add	tmp2, tmp1, tmp2
 	DISPATCH_NEXT
 .abortentry82:
 	ldmia	tmp2, {tmp2, tmp1}
+	MAYBE_VOLATILE	r3
 	DISPATCH_NEXT
 	PUSH	tmp2, tmp1
 	DISPATCH_FINISH
+	.ltorg
 }

 (iputfield) iputfield {
@@ -1669,6 +1680,8 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r2, tmp2
+	MAYBE_VOLATILE	r2	
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -1687,6 +1700,8 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r2, tmp2
+	MAYBE_VOLATILE	r2	
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -1705,6 +1720,8 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r2, tmp2
+	MAYBE_VOLATILE	r2	
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -1721,6 +1738,8 @@
 	add	tmp2, tmp2, r2, lsl #4
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r2, tmp2
+	MAYBE_VOLATILE	r2	
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 .abortentry113:
 	str	r3, [tmp1, tmp2]
@@ -1738,6 +1757,8 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	lr, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	TEST_VOLATILE	r2, tmp2
+	MAYBE_VOLATILE	r2	
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	add	tmp2, lr, tmp2
@@ -1746,6 +1767,7 @@
 .abortentry86:
 	stm	tmp2, {r3, tmp1}
 	DISPATCH_FINISH
+	.ltorg
 }

 #endif // FAST_BYTECODES
@@ -1763,6 +1785,7 @@
 	ldr	r3, [tmp2, #CP_OFFSET+4]
 	ldr	r2, [tmp2, #CP_OFFSET+12]
         ldr     lr, [tmp2, #CP_OFFSET+8]
+	mov	r1, r2			@ R1 saved for MAYBE_VOLATILE
         movs    r2, r2, lsr #29
 	bhi	getstatic_w		@ C = 1, Z = 0 => R2 == 3, 5, 7
 	bcs	getstatic_h		@ C = 1 => R2 = 1
@@ -1784,6 +1807,7 @@
 	blne	resolve_get_put
 	ldr	r3, [tmp2, #CP_OFFSET+4]		@ r3 = object
         ldr     lr, [tmp2, #CP_OFFSET+12]           @ lr = tos_type
+	MAYBE_VOLATILE	lr	
         ldr     r2, [tmp2, #CP_OFFSET+8]            @ r2 = offset
 	movs	lr, lr, lsr #29
 	bhi	putstatic_w		@ C = 1, Z = 0 => R2 == 3, 5, 7
@@ -1792,6 +1816,7 @@
 	tst	lr, #2
 	bne	putstatic_dw
 	b	putstatic_sh
+	.ltorg
 }

 #ifdef NOTICE_SAFEPOINTS
diff -r 0e1ae9c38563 arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
--- a/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Tue Nov 08 06:03:17 2011 -0500
+++ b/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Thu Nov 10 16:46:20 2011 +0000
@@ -585,6 +585,21 @@
 	.fpu softvfp
 #endif // HW_FP

+
+	.macro	TEST_VOLATILE flags, cp_cache
+	ldr	\flags, [\cp_cache, #CP_OFFSET+CP_CACHE_FLAGS]
+	.endm
+
+	.macro	MAYBE_VOLATILE flags
+	tst	\flags, #(1<<CP_CACHE_VOLATILE_FIELD_FLAG_BIT)
+	beq	0f
+	stmfd	sp!, {r2, lr}
+	ldr	r2, =0xffff0fa0
+	blx	r2
+	ldmfd	sp!, {r2, lr}
+0:
+	.endm
+	
 	.eabi_attribute Tag_ABI_FP_denormal, 1
 	.eabi_attribute Tag_ABI_FP_exceptions, 1
 	.eabi_attribute Tag_ABI_FP_number_model, 3
@@ -1942,18 +1957,21 @@
 getstatic_sh:
 	DISPATCH_START	3
 	ldrsh	tmp2, [r3, lr]
+	MAYBE_VOLATILE	r1
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
 getstatic_h:
 	DISPATCH_START	3
 	ldrh	tmp2, [r3, lr]
+	MAYBE_VOLATILE	r1
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
 getstatic_sb:
 	DISPATCH_START	3
 	ldrsb	tmp2, [r3, lr]
+	MAYBE_VOLATILE	r1
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
@@ -1961,12 +1979,14 @@
 	DISPATCH_START	3
 	add	r3, r3, lr
 	ldm	r3, {r2, tmp2}
+	MAYBE_VOLATILE	r1
 	DISPATCH_NEXT
 	PUSH	r2, tmp2
 	DISPATCH_FINISH
 getstatic_w:
 	DISPATCH_START	3
 	ldr	tmp2, [r3, lr]
+	MAYBE_VOLATILE	r1
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
diff -r 0e1ae9c38563 arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
--- a/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Tue Nov 08 06:03:17 2011 -0500
+++ b/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Thu Nov 10 16:46:20 2011 +0000
@@ -2058,7 +2058,9 @@

 #define T_CHKA(size, idx)		(0xca00 | (((size) & 8) << (7-3)) | ((idx) << 3) | ((size) & 7))
 #define T_HBL(handler)			(0xc300 | (handler))
-#define T_ENTER_LEAVE(enter)		(0xf3bf8f0f | ((enter)<<4))
+#define T_MISC_CONTROL(op, option)	(0xf3bf8f00 | ((op)<<4) | option)
+#define T_ENTER_LEAVE(enter)		(T_MISC_CONTROL(enter, 0xf))
+#define T_DMB(option)			(T_MISC_CONTROL(5, option))

 #define T1_ADD_IMM(dst, src, imm3)	(0x1c00 | ((imm3) << 6) | ((src) << 3) | (dst))
 #define T2_ADD_IMM(r, imm8)		(0x3000 | ((r) << 8) | (imm8))
@@ -2878,6 +2880,16 @@
 }
 #endif

+int fullBarrier(CodeBuf *codebuf)
+{
+  return out_16x2(codebuf, T_DMB(0xf));
+}
+
+int storeBarrier(CodeBuf *codebuf)
+{
+  return out_16x2(codebuf, T_DMB(0xe));
+}
+
 int tbh(CodeBuf *codebuf, Reg base, Reg idx)
 {
   out_16x2(codebuf, T_TBH(base, idx));
@@ -4558,6 +4570,10 @@
   else
     ldr_imm(jinfo->codebuf, ARM_R0, ARM_R0, field_offset, 1, 0);
   str_imm(jinfo->codebuf, ARM_R0, ARM_R1, 0, 1, 0);
+
+  if (cache->is_volatile())
+    fullBarrier(jinfo->codebuf);
+
   // deoptimized_frames = 0
   mov_imm(jinfo->codebuf, ARM_R0, 0);
   mov_reg(jinfo->codebuf, ARM_PC, ARM_LR);
@@ -5589,6 +5605,10 @@
 	  mov_imm(jinfo->codebuf, ARM_R1, index);
 	  blx(jinfo->codebuf, handlers[handler]);
 	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+
+	  if (cache->is_volatile())
+	    fullBarrier(jinfo->codebuf);
+
 	  break;
 	}

@@ -5620,6 +5640,10 @@
 	  else
 	    ldr_imm(jinfo->codebuf, r, r_obj, field_offset, 1, 0);
 	}
+
+	if (cache->is_volatile())
+	  fullBarrier(jinfo->codebuf);
+
 	break;
       }

@@ -5652,6 +5676,10 @@
 	  mov_imm(jinfo->codebuf, ARM_R1, index);
 	  blx(jinfo->codebuf, handlers[handler]);
 	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+
+	  if (cache->is_volatile())
+	    fullBarrier(jinfo->codebuf);
+
 	  break;
 	}

@@ -5682,6 +5710,10 @@
 	  else
 	    ldr_imm(jinfo->codebuf, r, r, field_offset, 1, 0);
 	}
+
+	if (cache->is_volatile())
+	  fullBarrier(jinfo->codebuf);
+
 	break;
       }

@@ -5692,6 +5724,10 @@
 	Reg r_obj;

         cache = cp->entry_at(index);
+
+	if (cache->is_volatile())
+	  storeBarrier(jinfo->codebuf);
+
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
 	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
@@ -5710,6 +5746,10 @@
 	  mov_imm(jinfo->codebuf, ARM_R1, index);
 	  blx(jinfo->codebuf, handlers[handler]);
 	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+
+	  if (cache->is_volatile())
+	    fullBarrier(jinfo->codebuf);
+
 	  break;
 	}

@@ -5741,6 +5781,10 @@
 	    }
 	  }
 	}
+
+	if (cache->is_volatile())
+	  fullBarrier(jinfo->codebuf);
+
 	break;
       }

@@ -5750,6 +5794,10 @@
 	int index = GET_NATIVE_U2(code_base+bci+1);

         cache = cp->entry_at(index);
+
+	if (cache->is_volatile())
+	  storeBarrier(jinfo->codebuf);
+
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
 	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
@@ -5808,6 +5856,10 @@
 	    }
 	  }
 	}
+
+	if (cache->is_volatile())
+	  fullBarrier(jinfo->codebuf);
+
 	break;
       }




More information about the distro-pkg-dev mailing list