ARM: Volatile handlers

Andrew Haley aph at redhat.com
Mon Dec 5 09:38:45 PST 2011


I've rewritten all the volatile code.  The previous version I posted
was buggy and unmaintainable.  I've rewritten it to duplicate every
handler into a volatile and a non-volatile version.  This bloats the
code rather, but it's more efficient and much easier to understand.

Xerxes, please have a look.

Thanks,
Andrew.


2011-12-05  Andrew Haley  <aph at redhat.com>

	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
	(Thumb2_disass): Use class Opcodes to do the disassembly.
	(Thumb2_Enter): Update ISTATE_SELF_LINK.
	(T_DMB): New.
	(fullBarrier): New.
	(storeBarrier): New.
	(Thumb2_Accessor): Add volatile barriers.
	(Thumb2_codegen): Likewise.
	(Thumb2_Initialize): Check UseCompiler.
	(class Opcodes): New.  Load libopcodes.so lazily.
	* arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def: For every
	{get,put}field handler, add a test for volatility and duplicate
	the code path into two parts, volatile and non-volatile.  Add
	barriers to the volatile path.
	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S (dmb)
	(dmb_st): New macros.
	(abort_table): Add entries for volatile versions of all the field
	handlers.
	({put,get}field_volatile_*): Add volatile versions of all handlers.
	(Thumb2_{put,get}field_*_stub): Likewise.
	* arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp
	(print_vm_offsets): Add CP_CACHE_VOLATILE_FIELD_FLAG_BIT and
	CP_CACHE_FLAGS.

diff -r 0a0072170876 arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp
--- a/arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp	Mon Nov 28 20:06:41 2011 +0000
+++ b/arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp	Mon Dec 05 12:33:28 2011 -0500
@@ -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 0a0072170876 arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def
--- a/arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Mon Nov 28 20:06:41 2011 +0000
+++ b/arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Mon Dec 05 12:33:28 2011 -0500
@@ -1573,6 +1573,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r3, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry78:
@@ -1581,6 +1582,17 @@
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+.abortentry78_v:
+	ldr	tmp2, [tmp1, tmp2]
+	dmb
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }

 (bgetfield) bgetfield {
@@ -1592,6 +1604,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r3, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry79:
@@ -1600,6 +1613,17 @@
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+.abortentry79_v:
+	ldrsb	tmp2, [tmp1, tmp2]
+	dmb
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }

 (cgetfield) cgetfield {
@@ -1611,6 +1635,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r3, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry80:
@@ -1619,6 +1644,17 @@
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+.abortentry80_v:
+	ldrh	tmp2, [tmp1, tmp2]
+	dmb
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }

 (sgetfield) sgetfield {
@@ -1630,6 +1666,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r3, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry81:
@@ -1638,6 +1675,17 @@
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+.abortentry81_v:
+	ldrsh	tmp2, [tmp1, tmp2]
+	dmb
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }

 (lgetfield) lgetfield {
@@ -1649,6 +1697,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r3, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	add	tmp2, tmp1, tmp2
@@ -1658,6 +1707,19 @@
 	DISPATCH_NEXT
 	PUSH	tmp2, tmp1
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+	add	tmp2, tmp1, tmp2
+	DISPATCH_NEXT
+	dmb_st
+.abortentry82_v:
+	ldmia	tmp2, {tmp2, tmp1}
+	dmb
+	DISPATCH_NEXT
+	PUSH	tmp2, tmp1
+	DISPATCH_FINISH
 }

 (iputfield) iputfield {
@@ -1669,6 +1731,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -1676,6 +1739,17 @@
 .abortentry83:
 	str	r3, [tmp1, tmp2]
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	dmb_st
+.abortentry83_v:
+	str	r3, [tmp1, tmp2]
+	dmb
+	DISPATCH_FINISH
 }

 (cputfield) cputfield {
@@ -1687,6 +1761,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -1694,6 +1769,17 @@
 .abortentry84:
 	strh	r3, [tmp1, tmp2]
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	dmb_st
+.abortentry84_v:
+	strh	r3, [tmp1, tmp2]
+	dmb
+	DISPATCH_FINISH
 }

 (bputfield) bputfield {
@@ -1705,6 +1791,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	DISPATCH_NEXT
@@ -1712,6 +1799,17 @@
 .abortentry85:
 	strb	r3, [tmp1, tmp2]
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	dmb_st
+.abortentry85_v:
+	strb	r3, [tmp1, tmp2]
+	dmb
+	DISPATCH_FINISH
 }

 (aputfield) aputfield {
@@ -1721,12 +1819,23 @@
 	add	tmp2, tmp2, r2, lsl #4
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 .abortentry113:
 	str	r3, [tmp1, tmp2]
 	mov	r0, tmp1
 	bl	Helper_aputfield
 	DISPATCH 3
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	dmb_st
+.abortentry113_v:
+	str	r3, [tmp1, tmp2]
+	dmb
+	mov	r0, tmp1
+	bl	Helper_aputfield
+	DISPATCH 3
 }

 (lputfield) lputfield {
@@ -1738,6 +1847,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	lr, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 	add	tmp2, lr, tmp2
@@ -1746,6 +1856,18 @@
 .abortentry86:
 	stm	tmp2, {r3, tmp1}
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	ldr	tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+	add	tmp2, lr, tmp2
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	dmb_st
+.abortentry86_v:
+	stm	tmp2, {r3, tmp1}
+	dmb
+	DISPATCH_FINISH
 }

 #endif // FAST_BYTECODES
@@ -1760,6 +1882,7 @@
 	and	r3, r3, #0x00ff0000
 	cmp	r3, #opc_getstatic << 16
 	blne	resolve_get_put
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	r3, [tmp2, #CP_OFFSET+4]
 	ldr	r2, [tmp2, #CP_OFFSET+12]
         ldr     lr, [tmp2, #CP_OFFSET+8]
@@ -1770,6 +1893,18 @@
 	tst	r2, #2
 	bne	getstatic_dw
 	b	getstatic_sh
+3:
+	VOLATILE_VERSION
+	ldr	r3, [tmp2, #CP_OFFSET+4]
+	ldr	r2, [tmp2, #CP_OFFSET+12]
+        ldr     lr, [tmp2, #CP_OFFSET+8]
+        movs    r2, r2, lsr #29
+	bhi	getstatic_volatile_w		@ C = 1, Z = 0 => R2 == 3, 5, 7
+	bcs	getstatic_volatile_h		@ C = 1 => R2 = 1
+	beq	getstatic_volatile_sb		@ Z = 1 => R2 = 0
+	tst	r2, #2
+	bne	getstatic_volatile_dw
+	b	getstatic_volatile_sh
 }

 @ r2 = [jpc, #1]
@@ -1782,6 +1917,7 @@
         and     r3, r3, #0xff000000
         cmp     r3, #opc_putstatic << 24
 	blne	resolve_get_put
+	GO_IF_VOLATILE	r2, tmp2, 3f
 	ldr	r3, [tmp2, #CP_OFFSET+4]		@ r3 = object
         ldr     lr, [tmp2, #CP_OFFSET+12]           @ lr = tos_type
         ldr     r2, [tmp2, #CP_OFFSET+8]            @ r2 = offset
@@ -1792,6 +1928,18 @@
 	tst	lr, #2
 	bne	putstatic_dw
 	b	putstatic_sh
+3:
+	VOLATILE_VERSION
+	ldr	r3, [tmp2, #CP_OFFSET+4]		@ r3 = object
+        ldr     lr, [tmp2, #CP_OFFSET+12]           @ lr = tos_type
+        ldr     r2, [tmp2, #CP_OFFSET+8]            @ r2 = offset
+	movs	lr, lr, lsr #29
+	bhi	putstatic_volatile_w		@ C = 1, Z = 0 => R2 == 3, 5, 7
+	bcs	putstatic_volatile_h		@ C = 1 => R2 = 1
+	beq	putstatic_volatile_sb		@ Z = 1 => R2 = 0
+	tst	lr, #2
+	bne	putstatic_volatile_dw
+	b	putstatic_volatile_sh
 }

 #ifdef NOTICE_SAFEPOINTS
@@ -2216,6 +2364,7 @@
 	DISPATCH_NEXT
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
+	GO_IF_VOLATILE r3, tmp2, 3f
 	DISPATCH_NEXT
         ldr     tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
@@ -2224,6 +2373,16 @@
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+	DISPATCH_NEXT
+        ldr     tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+.abortentry87_v:
+	ldr	tmp2, [tmp1, tmp2]
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }

 @ r2 = [jpc, #1]
@@ -4086,6 +4245,7 @@
 	SW_NPC	cmp	tmp1, #0
 	SW_NPC	beq	null_ptr_exception_jpc_3
 	DISPATCH_NEXT
+	GO_IF_VOLATILE r3, tmp2, 3f
         ldr     tmp2, [tmp2, #CP_OFFSET+8]
 	DISPATCH_NEXT
 .abortentry88:
@@ -4093,6 +4253,15 @@
 	DISPATCH_NEXT
 	PUSH	tmp2
 	DISPATCH_FINISH
+3:
+	VOLATILE_VERSION
+        ldr     tmp2, [tmp2, #CP_OFFSET+8]
+	DISPATCH_NEXT
+.abortentry88_v:
+	ldr	tmp2, [tmp1, tmp2]
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
 }

 @ --- iconst; store -------------------------------------------------
diff -r 0a0072170876 arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
--- a/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Mon Nov 28 20:06:41 2011 +0000
+++ b/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Mon Dec 05 12:33:28 2011 -0500
@@ -585,6 +585,32 @@
 	.fpu softvfp
 #endif // HW_FP

+#ifndef	__ARM_ARCH_7A__
+#	define dmb VOLATILE_BARRIER
+#	define dmb_st VOLATILE_BARRIER
+#else
+#	define	dmb_st .word   0xf57ff05e
+#endif
+
+	.macro	VOLATILE_BARRIER arg
+	stmfd	sp!, {r2, lr}
+	mov	r2, #0xfa0
+	movt    r2, #0xffff
+	blx	r2
+	ldmfd	sp!, {r2, lr}
+	.endm
+	
+	.macro	GO_IF_VOLATILE reg, cp_cache, label
+	ldr	\reg, [\cp_cache, #CP_OFFSET+CP_CACHE_FLAGS]
+	tst	\reg, #(1<<CP_CACHE_VOLATILE_FIELD_FLAG_BIT)
+	bne	\label
+	.set	dispatch_saved, dispatch_state
+	.endm
+
+	.macro VOLATILE_VERSION
+	.set	dispatch_state, dispatch_saved
+	.endm
+	
 	.eabi_attribute Tag_ABI_FP_denormal, 1
 	.eabi_attribute Tag_ABI_FP_exceptions, 1
 	.eabi_attribute Tag_ABI_FP_number_model, 3
@@ -884,17 +910,28 @@
 		FBC	.word	.abortentry77, 1

 	    FBC		.word	.abortentry78, 3
+	    FBC		.word	.abortentry78_v, 3
 	    FBC		.word	.abortentry79, 3
+	    FBC		.word	.abortentry79_v, 3
 	    FBC		.word	.abortentry80, 3
+	    FBC		.word	.abortentry80_v, 3
 	    FBC		.word	.abortentry81, 3
+	    FBC		.word	.abortentry81_v, 3
 	    FBC		.word	.abortentry82, 3
+	    FBC		.word	.abortentry82_v, 3
 	    FBC		.word	.abortentry83, 3
+	    FBC		.word	.abortentry83_v, 3
 	    FBC		.word	.abortentry84, 3
+	    FBC		.word	.abortentry84_v, 3
 	    FBC		.word	.abortentry85, 3
+	    FBC		.word	.abortentry85_v, 3
 	    FBC		.word	.abortentry86, 3
+	    FBC		.word	.abortentry86_v, 3
 	    FBC		.word	.abortentry87, 3
+	    FBC		.word	.abortentry87_v, 3

 	    FBC    	.word	.abortentry88, 3
+	    FBC    	.word	.abortentry88_v, 3
 	    FBC	   	.word	.abortentry89, 5
 	    FBC	     	.word	.abortentry90, 4
 	    FBC	     	.word	.abortentry91, 4
@@ -910,6 +947,7 @@
 		FBC	.word	.abortentry112, 3

 		FBC	.word	.abortentry113, 0
+		FBC	.word	.abortentry113_v, 0
 			.word	.abortentry114, 1
 		FBC	.word	.abortentry117, 0
 			.word	.abortentry118, 0
@@ -2006,6 +2044,87 @@
 	bl	Helper_aputfield
 	DISPATCH 3

+getstatic_volatile_sh:
+	DISPATCH_START	3
+	ldrsh	tmp2, [r3, lr]
+	dmb
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
+getstatic_volatile_h:
+	DISPATCH_START	3
+	ldrh	tmp2, [r3, lr]
+	dmb
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
+getstatic_volatile_sb:
+	DISPATCH_START	3
+	ldrsb	tmp2, [r3, lr]
+	dmb
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
+getstatic_volatile_dw:
+	DISPATCH_START	3
+	add	r3, r3, lr
+	ldm	r3, {r2, tmp2}
+	dmb
+	DISPATCH_NEXT
+	PUSH	r2, tmp2
+	DISPATCH_FINISH
+getstatic_volatile_w:
+	DISPATCH_START	3
+	ldr	tmp2, [r3, lr]
+	dmb
+	DISPATCH_NEXT
+	PUSH	tmp2
+	DISPATCH_FINISH
+
+putstatic_volatile_sh:
+putstatic_volatile_h:
+	DISPATCH_START	3
+	POP	tmp2
+	DISPATCH_NEXT
+	dmb_st
+	strh	tmp2, [r3, r2]
+	dmb
+	DISPATCH_FINISH
+putstatic_volatile_w:
+	cmp	lr, #tos_atos >> 1	@ >> 1 due to lsr #29 above
+	beq	putstatic_volatile_a
+	DISPATCH_START	3
+	POP	tmp2
+	DISPATCH_NEXT
+	dmb_st
+	str	tmp2, [r3, r2]
+	dmb
+	DISPATCH_FINISH
+putstatic_volatile_sb:
+	DISPATCH_START	3
+	POP	tmp2
+	DISPATCH_NEXT
+	dmb_st
+	strb	tmp2, [r3, r2]
+	dmb
+	DISPATCH_FINISH
+putstatic_volatile_dw:
+	DISPATCH_START	3
+	add	r2, r2, r3
+	POP	r3, tmp2
+	DISPATCH_NEXT
+	dmb_st
+	stm	r2, {r3, tmp2}
+	dmb
+	DISPATCH_FINISH
+putstatic_volatile_a:
+	POP	tmp2
+	dmb_st
+	str	tmp2, [r3, r2]
+	mov	r0, r3
+	bl	Helper_aputfield
+	DISPATCH 3
+
 resolve_invokeinterface:
 	mov	r1, #opc_invokeinterface
 	b	resolve_invoke
@@ -5524,6 +5643,8 @@
         mov     r2, Rthread
         blx     r3

+	dmb_st
+	
         ldr     Rthread, [istate, #ISTATE_THREAD]

         ldr     stack, [Rthread, #THREAD_JAVA_SP]
@@ -5569,9 +5690,17 @@
 	cmp	r3, #0
 	beq	field_null_ptr_exception

+	GO_IF_VOLATILE	r2, r2, 3f
+
 	ldr	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	
+	ldr	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getfield_stub_unresolved
@@ -5595,9 +5724,16 @@
 	cmp	r3, #0
 	beq	field_null_ptr_exception

+	GO_IF_VOLATILE	r2, r2, 3f
+
 	ldrsh	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldrsh	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getfield_stub_unresolved
@@ -5621,9 +5757,16 @@
 	cmp	r3, #0
 	beq	field_null_ptr_exception

+	GO_IF_VOLATILE	r2, r2, 3f
+
 	ldrh	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldrh	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getfield_stub_unresolved
@@ -5647,9 +5790,16 @@
 	cmp	r3, #0
 	beq	field_null_ptr_exception

+	GO_IF_VOLATILE	r2, r2, 3f
+
 	ldrsb	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldrsb	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getfield_stub_unresolved
@@ -5673,9 +5823,16 @@
 	cmp	r3, #0
 	beq	field_null_ptr_exception

+	GO_IF_VOLATILE	r2, r2, 3f
+
 	ldrd	r2, r3, [r3, ip]
 	stmdb	stack!, {r2, r3}	@ PUSH r2, r3
 	bx	lr
+3:
+	ldrd	r2, r3, [r3, ip]
+	dmb
+	stmdb	stack!, {r2, r3}	@ PUSH r2, r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getfield_stub_unresolved
@@ -5739,6 +5896,8 @@
 	cmp	r3, #opc_putfield << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
 	cmp	r3, #0
@@ -5746,6 +5905,16 @@

 	str	r2, [r3, ip]
 	bx	lr
+3:	
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	dmb_st
+	str	r2, [r3, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putfield_stub_unresolved
@@ -5762,6 +5931,8 @@
 	cmp	r3, #opc_putfield << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
 	cmp	r3, #0
@@ -5769,6 +5940,16 @@

 	strh	r2, [r3, ip]
 	bx	lr
+3:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	dmb_st
+	strh	r2, [r3, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putfield_stub_unresolved
@@ -5785,6 +5966,8 @@
 	cmp	r3, #opc_putfield << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
 	cmp	r3, #0
@@ -5792,6 +5975,16 @@

 	strb	r2, [r3, ip]
 	bx	lr
+3:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	dmb_st
+	strb	r2, [r3, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putfield_stub_unresolved
@@ -5808,6 +6001,8 @@
 	cmp	r3, #opc_putfield << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
 	cmp	r3, #0
@@ -5817,6 +6012,18 @@
 	ldr	ip, helper_aputfield_adcon
 	mov	r0, r3
 	bx	ip
+3:
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}	@ r2 = value, r3 = obj
+	cmp	r3, #0
+	beq	field_null_ptr_exception
+
+	dmb_st
+	str	r2, [r3, ip]
+	dmb
+	ldr	ip, helper_aputfield_adcon
+	mov	r0, r3
+	bx	ip
 1:
 	mov	ip, lr
 	bl	putfield_stub_unresolved
@@ -5833,6 +6040,8 @@
 	cmp	r3, #opc_putfield << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r1, [r2, #CP_OFFSET+8]
 	ldmia	stack!, {r2, r3, ip}	@ r2,r3 = value, ip = obj
 	cmp	ip, #0
@@ -5840,6 +6049,16 @@

 	strd	r2,r3, [ip, r1]
 	bx	lr
+3:
+	ldr	r1, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3, ip}	@ r2,r3 = value, ip = obj
+	cmp	ip, #0
+	beq	field_null_ptr_exception
+
+	dmb_st
+	strd	r2,r3, [ip, r1]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putfield_stub_unresolved
@@ -5858,12 +6077,22 @@
 	cmp	r3, #opc_getstatic << 16
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]

 	ldr	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldr	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getstatic_stub_unresolved
@@ -5880,12 +6109,22 @@
 	cmp	r3, #opc_getstatic << 16
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]

 	ldrh	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrh	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getstatic_stub_unresolved
@@ -5902,12 +6141,22 @@
 	cmp	r3, #opc_getstatic << 16
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]

 	ldrsh	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrsh	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getstatic_stub_unresolved
@@ -5924,12 +6173,22 @@
 	cmp	r3, #opc_getstatic << 16
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]

 	ldrsb	r3, [r3, ip]
 	str	r3, [stack, #-4]!	@ PUSH r3
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrsb	r3, [r3, ip]
+	dmb
+	str	r3, [stack, #-4]!	@ PUSH r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getstatic_stub_unresolved
@@ -5946,12 +6205,22 @@
 	cmp	r3, #opc_getstatic << 16
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]

 	ldrd	r2, r3, [r3, ip]
 	stmdb	stack!, {r2, r3}	@ PUSH r2, r3
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+
+	ldrd	r2, r3, [r3, ip]
+	dmb
+	stmdb	stack!, {r2, r3}	@ PUSH r2, r3
+	bx	lr
 1:
 	mov	ip, lr
 	bl	getstatic_stub_unresolved
@@ -5970,12 +6239,23 @@
 	cmp	r3, #opc_putstatic << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldr	r2, [stack], #4		@ POP r2

 	str	r2, [r3, ip]
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	dmb_st
+	str	r2, [r3, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putstatic_stub_unresolved
@@ -5994,12 +6274,23 @@
 	cmp	r3, #opc_putstatic << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldr	r2, [stack], #4		@ POP r2

 	strh	r2, [r3, ip]
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	dmb_st
+	strh	r2, [r3, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putstatic_stub_unresolved
@@ -6018,12 +6309,23 @@
 	cmp	r3, #opc_putstatic << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldr	r2, [stack], #4		@ POP r2

 	strb	r2, [r3, ip]
 	bx	lr
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	dmb_st
+	strb	r2, [r3, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putstatic_stub_unresolved
@@ -6042,12 +6344,23 @@
 	cmp	r3, #opc_putstatic << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r1, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldmia	stack!, {r2, r3}

 	strd	r2,r3, [r1, ip]
 	bx	lr
+3:
+	ldr	r1, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldmia	stack!, {r2, r3}
+
+	dmb_st
+	strd	r2,r3, [r1, ip]
+	dmb
+	bx	lr
 1:
 	mov	ip, lr
 	bl	putstatic_stub_unresolved
@@ -6066,6 +6379,8 @@
 	cmp	r3, #opc_putstatic << 24
 	bne	1f
 2:
+	GO_IF_VOLATILE	r3, r2, 3f
+	
 	ldr	r3, [r2, #CP_OFFSET+4]
 	ldr	ip, [r2, #CP_OFFSET+8]
 	ldr	r2, [stack], #4		@ POP r2
@@ -6074,6 +6389,17 @@
 	ldr	ip, helper_aputfield_adcon
 	mov	r0, r3
 	bx	ip
+3:
+	ldr	r3, [r2, #CP_OFFSET+4]
+	ldr	ip, [r2, #CP_OFFSET+8]
+	ldr	r2, [stack], #4		@ POP r2
+
+	dmb_st
+	str	r2, [r3, ip]
+	dmb
+	ldr	ip, helper_aputfield_adcon
+	mov	r0, r3
+	bx	ip
 1:
 	mov	ip, lr
 	bl	putstatic_stub_unresolved
diff -r 0a0072170876 arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
--- a/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Mon Nov 28 20:06:41 2011 +0000
+++ b/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Mon Dec 05 12:33:28 2011 -0500
@@ -27,7 +27,7 @@

 #define T2EE_PRINT_COMPILATION
 #define T2EE_PRINT_STATISTICS
-//#define T2EE_PRINT_DISASS
+#define T2EE_PRINT_DISASS
 #define T2EE_PRINT_REGUSAGE

 #ifdef T2EE_PRINT_COMPILATION
@@ -717,6 +717,43 @@
 static const char *local_types[] = { "int", "long", "float", "double", "ref" };

 #ifdef T2EE_PRINT_DISASS
+
+class Opcodes {
+public:
+  typeof (::print_insn_little_arm) *print_insn_little_arm;
+  typeof (::init_disassemble_info) *init_disassemble_info;
+  typeof (::disassemble_init_for_target) *disassemble_init_for_target;
+
+  // Load libopcodes.so lazily.
+  Opcodes()
+  {
+    void *lib;
+    if (t2ee_print_disass) {
+      if (lib = dlopen("libopcodes.so", RTLD_NOW)) {
+	print_insn_little_arm
+	  = (typeof print_insn_little_arm)dlsym(lib, "print_insn_little_arm");
+	init_disassemble_info
+	  = (typeof init_disassemble_info)dlsym(lib, "init_disassemble_info");
+	disassemble_init_for_target
+	  = (typeof disassemble_init_for_target)dlsym(lib, "disassemble_init_for_target");
+      }
+
+      if (! (print_insn_little_arm
+	     && init_disassemble_info
+	     && disassemble_init_for_target))
+	{
+	  fprintf (stderr, "The environment variable T2EE_PRINT_DISASS is set, but\n"
+		   "libopcodes.so has not been found or is invalid.  If you want to\n"
+		   "see a disassembly, please ensure that a valid copy of\n"
+		   "libopcodes.so is present somewhere in your library load path.\n");
+	  abort();
+	}
+    }
+  }
+};
+
+static Opcodes opcodes;
+
 void Thumb2_disass(Thumb2_Info *jinfo)
 {
   unsigned code_size = jinfo->code_size;
@@ -747,9 +784,9 @@
   }
 #endif

-  init_disassemble_info(&info, stdout, (fprintf_ftype)fprintf);
+  opcodes.init_disassemble_info(&info, stdout, (fprintf_ftype)fprintf);
   info.arch = bfd_arch_arm;
-  disassemble_init_for_target(&info);
+  opcodes.disassemble_init_for_target(&info);
   info.endian = BFD_ENDIAN_LITTLE;
   info.endian_code = BFD_ENDIAN_LITTLE;
   info.buffer = (bfd_byte *)codebuf;
@@ -823,7 +860,7 @@
 	    for (i = 0; i < 4; i++) {
 	      printf("0x%08x:\t", (int)codebuf+idx);
 	      {
-		int len = print_insn_little_arm((bfd_vma)codebuf+idx, &info);
+		int len = opcodes.print_insn_little_arm((bfd_vma)codebuf+idx, &info);
 		if (len == -1) len = 2;
 		idx += len;
 		putchar('\n');
@@ -898,7 +935,7 @@
 	    len = 4;
 	  }
 	} else {
-	  len = print_insn_little_arm((bfd_vma)codebuf+idx, &info);
+	  len = opcodes.print_insn_little_arm((bfd_vma)codebuf+idx, &info);
 	  if (len == -1) len = 2;
 	  idx += len;
 	}
@@ -2058,7 +2095,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 +2917,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 +4607,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);
@@ -4695,6 +4748,8 @@
   str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_THREAD, 1, 0);
   str_imm(jinfo->codebuf, ARM_R0, Ristate, ISTATE_METHOD, 1, 0);

+  str_imm(jinfo->codebuf, Ristate, Ristate, ISTATE_SELF_LINK, 1, 0);
+
   mov_reg(jinfo->codebuf, Rthread, ARM_R2);

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

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

@@ -5692,6 +5755,7 @@
 	Reg r_obj;

         cache = cp->entry_at(index);
+
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
 	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
@@ -5703,16 +5767,20 @@
 	  if (c == 'J' || c == 'D') handler = H_PUTFIELD_DW;
 	  if (c == 'B' || c == 'Z') handler = H_PUTFIELD_B;
 	  if (c == 'C' || c == 'S') handler = H_PUTFIELD_H;
-	  if (c == '[' || c == 'L') handler = H_PUTFIELD_A;
+ 	  if (c == '[' || c == 'L') handler = H_PUTFIELD_A;
 	  Thumb2_Flush(jinfo);
 	  Thumb2_save_locals(jinfo, stackdepth);
 	  mov_imm(jinfo->codebuf, ARM_R0, bci+CONSTMETHOD_CODEOFFSET);
 	  mov_imm(jinfo->codebuf, ARM_R1, index);
 	  blx(jinfo->codebuf, handlers[handler]);
 	  Thumb2_restore_locals(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+
 	  break;
 	}

+	if (cache->is_volatile())
+	  storeBarrier(jinfo->codebuf);
+
 	TosState tos_type = cache->flag_state();
 	int field_offset = cache->f2();

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

@@ -5771,6 +5843,9 @@
 	  break;
 	}

+	if (cache->is_volatile())
+	  storeBarrier(jinfo->codebuf);
+
 	TosState tos_type = cache->flag_state();
 	int field_offset = cache->f2();
 	Reg r_obj;
@@ -5808,6 +5883,10 @@
 	    }
 	  }
 	}
+
+	if (cache->is_volatile())
+	  fullBarrier(jinfo->codebuf);
+
 	break;
       }

@@ -7163,7 +7242,7 @@
   u32 loc_irem, loc_idiv, loc_ldiv;
   int rc;

-  if (!(CPUInfo & ARCH_THUMBEE)) {
+  if (!(CPUInfo & ARCH_THUMBEE) || !UseCompiler) {
     DisableCompiler = 1;
     return;
   }



More information about the distro-pkg-dev mailing list