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