changeset 2717:628e5ee78eca

Update ARM port to HS20 and hard FP. 2011-10-26 Andrew Haley <aph@redhat.com> * patches/arm.patch (CFLAGS): Enable the ARM assembler port. PR icedtea/484: * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S (fast_empty_entry, normal_entry_synchronized, normal_entry): Return 0, #deoptimized_frames. * arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp (Thumb2_Return): Likewise. * arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def (return_unsafe, ireturn_unsafe, lreturn_unsafe) (ireturn,areturn,freturn): Return deoptimized_frames = 0. PR icedtea/323: * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S: Replace all stores to THREAD_LAST_JAVA_SP with stores to THREAD_LAST_JAVA_FP. Add stores to THREAD_LAST_JAVA_SP. * arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp: Likewise. * Makefile.am (ICEDTEA_PATCHES): Add patches/arm-debug.patch. (stamps/ports.stamp): Use cp -l to link the ARM interpreter sources into the target dir rather than copying them. (EXTRA_DIST): Add arm_port. Update to HS20: * arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp: Replace all calls to fatal1() (which no longer exists) with calls to fatal(). (Thumb2_is_zombie, Thumb2_pass2): invoke* and {get,put}* now take native, not Java, byte ordered indexes. (Thumb2_disass, Thumb2_codegen, Thumb2_tablegen): Bytecodes::special_length_at() takes different arguments from the previous version; adjust suitably. * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S: Replace call to report_fatal_vararg(char const*, int, char const*, ...) (which no longer exists) with call to Helper_report_fatal. * arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def (new): Renumber the fast bytecodes iload_0_iconst_N to iload_3_iload_N. * arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp: Likewise. * patches/arm.patch: Likewise. Add *.S to the list of source files. * arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp (All #includes) : Move to new OpenJDK include file format. (Helper_report_fatal): New assember helper. (print_vm_offsets): Add THREAD_LAST_JAVA_FP. Hard FP port: * arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp (Thumb2_Initialize): Add hard FP variants for the stubs that need it. * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S (POPF0, POPF1, POPD0, POPD1,PUSHF0, PUSHD0): New macros. (.eabi_attribute): Use real names. Add declaration for hard FP ABI. (.fast_native_return_double, .fast_native_return_float, .fast_copy_double, .fast_copy_float): New. (fast_native_entry): use SIZEOF_FFI_CIF, not 24. Add logic to handle args in FP registers. (FIND_LOWEST_BIT, FIND_LOWEST_BIT_PAIR, COPY_DOUBLE, COPY_FLOAT): New macros. (.copy_float_table, .copy_double_table): New. * arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def (frem, drem, f2i, f2l, d2i, d2l): Add hardfp args. * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S (REWRITE_PAIRS): New macro. * arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def: Use REWRITE_PAIRS to prevent rewriting pairs of bytecodes in the instruction stream. * arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S (fast_native_entry): Update ISTATE_SELF_LINK to get correct stack traces. * patches/arm-debug.patch: New file.
author aph
date Thu, 27 Oct 2011 13:54:50 +0100
parents 68d8fd484caa
children 16a1f3497b7e 10f799f0520c
files ChangeLog Makefile.am arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp patches/arm-debug.patch patches/arm.patch
diffstat 8 files changed, 961 insertions(+), 157 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Oct 27 13:49:16 2011 +0100
+++ b/ChangeLog	Thu Oct 27 13:54:50 2011 +0100
@@ -1,3 +1,77 @@
+2011-10-26  Andrew Haley  <aph@redhat.com>
+
+	* patches/arm.patch (CFLAGS): Enable the ARM assembler port.
+
+	PR icedtea/484:
+	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
+	(fast_empty_entry, normal_entry_synchronized, normal_entry):
+	Return 0, #deoptimized_frames.
+	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp (Thumb2_Return):
+	Likewise.
+	* arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def
+	(return_unsafe, ireturn_unsafe, lreturn_unsafe)
+	(ireturn,areturn,freturn): Return deoptimized_frames = 0.
+
+	PR icedtea/323:
+	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S: Replace
+	all stores to THREAD_LAST_JAVA_SP with stores to
+	THREAD_LAST_JAVA_FP.  Add stores to THREAD_LAST_JAVA_SP.
+	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp: Likewise.
+
+	* Makefile.am (ICEDTEA_PATCHES): Add patches/arm-debug.patch.
+	(stamps/ports.stamp): Use cp -l to link the ARM interpreter
+	sources into the target dir rather than copying them.
+	(EXTRA_DIST): Add arm_port.
+
+	Update to HS20:
+	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp: Replace all calls
+	to fatal1() (which no longer exists) with calls to fatal().
+	(Thumb2_is_zombie, Thumb2_pass2): invoke* and {get,put}* now take
+	native, not Java, byte ordered indexes.
+	(Thumb2_disass, Thumb2_codegen, Thumb2_tablegen):
+	Bytecodes::special_length_at() takes different arguments from the
+	previous version; adjust suitably.
+	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S: Replace
+	call to report_fatal_vararg(char const*, int, char const*, ...)
+	(which no longer exists) with call to Helper_report_fatal.
+	* arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def (new):
+	Renumber the fast bytecodes iload_0_iconst_N to iload_3_iload_N.
+	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp: Likewise.
+	* patches/arm.patch: Likewise.
+	Add *.S to the list of source files.
+	* arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp (All #includes)
+	: Move to new OpenJDK include file format.
+	(Helper_report_fatal): New assember helper.
+	(print_vm_offsets): Add THREAD_LAST_JAVA_FP.
+
+	Hard FP port:
+	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp (Thumb2_Initialize):
+	Add hard FP variants for the stubs that need it.
+	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
+	(POPF0, POPF1, POPD0, POPD1,PUSHF0, PUSHD0): New macros.
+	(.eabi_attribute): Use real names.  Add declaration for hard
+	FP ABI.
+	(.fast_native_return_double, .fast_native_return_float,
+	.fast_copy_double, .fast_copy_float): New.
+	(fast_native_entry): use SIZEOF_FFI_CIF, not 24.  Add logic to
+	handle args in FP registers.
+	(FIND_LOWEST_BIT, FIND_LOWEST_BIT_PAIR, COPY_DOUBLE, COPY_FLOAT):
+	New macros.
+	(.copy_float_table, .copy_double_table): New. 
+	* arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def
+	(frem, drem, f2i, f2l, d2i, d2l): Add hardfp args.
+
+	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
+	(REWRITE_PAIRS): New macro.
+	* arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def: Use
+	REWRITE_PAIRS to prevent rewriting pairs of bytecodes in the
+	instruction stream.
+
+	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S (fast_native_entry):
+	Update ISTATE_SELF_LINK to get correct stack traces.
+
+	* patches/arm-debug.patch: New file.
+
 2011-10-26  Andrew Haley  <aph@redhat.com>
 
 	Reinstate the ARM assembler port.  Back out this patch:
--- a/Makefile.am	Thu Oct 27 13:49:16 2011 +0100
+++ b/Makefile.am	Thu Oct 27 13:54:50 2011 +0100
@@ -625,7 +625,8 @@
 
 EXTRA_DIST = generated \
 	$(top_srcdir)/patches/* \
-	contrib overlays \
+	contrib arm_port \
+	overlays \
 	jconsole.desktop policytool.desktop \
 	$(JTREG_SRCS) HACKING pulseaudio fsg.sh \
 	hotspot.map \
@@ -1045,7 +1046,7 @@
 	for target in $(abs_top_srcdir)/arm_port/hotspot/tools \
 		      $(abs_top_srcdir)/arm_port/hotspot/src/*cpu/* ; do \
 	  link=$$(dirname $$target | sed 's/^.*arm_port/openjdk/'); \
-	  cp -rv $$target $$link; \
+	  cp -rlv $$target $$link; \
 	done
 endif
 	mkdir -p stamps
@@ -1059,7 +1060,7 @@
 	done
 	rm -f stamps/ports.stamp
 
-+stamps/generated.stamp: stamps/ports.stamp
+stamps/generated.stamp: stamps/ports.stamp
 	if [ ! -e $(GENERATED_BUILD_DIR) ]; then \
 	  cp -a $(abs_top_srcdir)/generated $(GENERATED_BUILD_DIR) && \
 	  chmod -R ug+rwX $(GENERATED_BUILD_DIR) ; \
--- a/arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp	Thu Oct 27 13:49:16 2011 +0100
+++ b/arm_port/hotspot/src/cpu/zero/vm/asm_helper.cpp	Thu Oct 27 13:54:50 2011 +0100
@@ -20,9 +20,27 @@
 #define ARCH_VFP	(1<<17)
 #define ARCH_CLZ	(1<<18)
 
-#ifndef STATIC_OFFSETS
+#include "precompiled.hpp"
+#include "asm/assembler.hpp"
+#include "interp_masm_zero.hpp"
+#include "interpreter/bytecodeInterpreter.hpp"
+#include "interpreter/bytecodeInterpreter.inline.hpp"
+#include "interpreter/interpreter.hpp"
+#include "interpreter/interpreterRuntime.hpp"
+#include "oops/methodDataOop.hpp"
+#include "oops/methodOop.hpp"
+#include "oops/oop.inline.hpp"
+#include "prims/jvmtiExport.hpp"
+#include "prims/jvmtiThreadState.hpp"
+#include "runtime/deoptimization.hpp"
+#include "runtime/frame.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "runtime/stubRoutines.hpp"
+#include "runtime/synchronizer.hpp"
+#include "runtime/vframeArray.hpp"
+#include "utilities/debug.hpp"
 
-#include "incls/_bytecodeInterpreter.cpp.incl"
+#ifndef STATIC_OFFSETS
 
 #include <linux/auxvec.h>
 #include <asm/hwcap.h>
@@ -345,12 +363,17 @@
     return 0;
 }
 
+extern "C" void Helper_report_fatal(char *filename, int line,
+				    char *msg, int opcode, char *name)
+{
+  report_fatal(filename, line,
+	       err_msg(msg, opcode, name));
+}
+
 #endif // STATIC_OFFSETS
 
 #ifdef STATIC_OFFSETS
 
-#include "incls/_precompiled.incl"
-
 class VMStructs {
 public:
 	static void print_vm_offsets(void);
@@ -410,7 +433,10 @@
   print_def("THREAD_HANDLE_AREA", offset_of(JavaThread, _handle_area));
   print_def("THREAD_STACK_BASE", offset_of(JavaThread, _stack_base));
   print_def("THREAD_STACK_SIZE", offset_of(JavaThread, _stack_size));
-  print_def("THREAD_LAST_JAVA_SP", offset_of(JavaThread, _anchor) + offset_of(JavaFrameAnchor, _last_Java_sp));
+  print_def("THREAD_LAST_JAVA_SP", offset_of(JavaThread, _anchor)
+	    + offset_of(JavaFrameAnchor, _last_Java_sp));
+  print_def("THREAD_LAST_JAVA_FP", offset_of(JavaThread, _anchor)
+	    + offset_of(JavaFrameAnchor, _last_Java_fp));
   print_def("THREAD_JNI_ENVIRONMENT", offset_of(JavaThread, _jni_environment));
   print_def("THREAD_VM_RESULT", offset_of(JavaThread, _vm_result));
   print_def("THREAD_STATE", offset_of(JavaThread, _thread_state));
@@ -470,6 +496,7 @@
   print_def("BASE_OFFSET_LONG", arrayOopDesc::base_offset_in_bytes(T_LONG));
   nl();
   print_def("SIZEOF_HANDLEMARK", sizeof(HandleMark));
+  print_def("SIZEOF_FFI_CIF", sizeof(ffi_cif));
 }
 
 int main(void)
--- a/arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Thu Oct 27 13:49:16 2011 +0100
+++ b/arm_port/hotspot/src/cpu/zero/vm/bytecodes_arm.def	Thu Oct 27 13:54:50 2011 +0100
@@ -265,35 +265,35 @@
 iload_iload	= 0xe3, 4
 iload_iload_N	= 0xe4, 3
 
-@return_register_finalizer = 0xe5, 1
-
-iload_0_iconst_N        = 0xe7, 2
-iload_1_iconst_N        = 0xe8, 2
-iload_2_iconst_N        = 0xe9, 2
-iload_3_iconst_N        = 0xea, 2
-iload_iconst_N          = 0xeb, 3
-iadd_istore_N		= 0xec, 2
-isub_istore_N		= 0xed, 2
-iand_istore_N		= 0xee, 2
-ior_istore_N		= 0xef, 2
-ixor_istore_N		= 0xf0, 2
-iadd_u4store		= 0xf1, 3
-isub_u4store		= 0xf2, 3
-iand_u4store		= 0xf3, 3
-ior_u4store		= 0xf4, 3
-ixor_u4store		= 0xf5, 3
-iload_0_iload		= 0xf6, 3
-iload_1_iload		= 0xf7, 3
-iload_2_iload		= 0xf8, 3
-iload_3_iload		= 0xf9, 3
-iload_0_iload_N		= 0xfa, 2
-iload_1_iload_N		= 0xfb, 2
-iload_2_iload_N		= 0xfc, 2
-iload_3_iload_N		= 0xfd, 2
-
-#endif // FAST_BYTECODES
-
-return_register_finalizer = 0xe5, 1
+@return_register_finalizer = 0xe7, 1
+
+iload_0_iconst_N        = 0xe9, 2
+iload_1_iconst_N        = 0xea, 2
+iload_2_iconst_N        = 0xeb, 2
+iload_3_iconst_N        = 0xec, 2
+iload_iconst_N          = 0xed, 3
+iadd_istore_N           = 0xee, 2
+isub_istore_N           = 0xef, 2
+iand_istore_N           = 0xf0, 2
+ior_istore_N            = 0xf1, 2
+ixor_istore_N           = 0xf2, 2
+iadd_u4store            = 0xf3, 3
+isub_u4store            = 0xf4, 3
+iand_u4store            = 0xf5, 3
+ior_u4store             = 0xf6, 3
+ixor_u4store            = 0xf7, 3
+iload_0_iload           = 0xf8, 3
+iload_1_iload           = 0xf9, 3
+iload_2_iload           = 0xfa, 3
+iload_3_iload           = 0xfb, 3
+iload_0_iload_N         = 0xfc, 2
+iload_1_iload_N         = 0xfd, 2
+iload_2_iload_N         = 0xfe, 2
+iload_3_iload_N         = 0xff, 2
+
+#endif
+
+return_register_finalizer = 0xe7, 1
 
 (nop) {
 	DISPATCH	\seq_len
@@ -965,24 +965,18 @@
 }
 
 (frem) frem {
-@ It must be possible to do better than this
-	POP	r0
-        bl      __aeabi_f2d
-	PUSH	r0, r1
-	GET_STACK	2, r0
-        bl      __aeabi_f2d
-	POP	r2, r3
-        bl      fmod
-        bl      __aeabi_d2f
-	PUT_STACK	0, r0
+	POPF1
+	POPF0
+        bl      fmodf
+	PUSHF0
 	DISPATCH	\seq_len
 }
 
 (drem) drem {
-	POP	r2, r3
-	POP	r0, r1
+	POPD1
+        POPD0
         bl      fmod
-	PUSH	r0, r1
+	PUSHD0
 	DISPATCH	\seq_len
 }
 
@@ -1241,14 +1235,14 @@
 }
 
 (f2i) f2i {
-	POP	r0
+	POPF0
         bl      _ZN13SharedRuntime3f2iEf
 	PUSH	r0
 	DISPATCH	\seq_len
 }
 
 (f2l) f2l {
-	POP	r0
+	POPF0
         bl      _ZN13SharedRuntime3f2lEf
 	PUSH	r0, r1
 	DISPATCH	\seq_len
@@ -1262,14 +1256,14 @@
 }
 
 (d2i) d2i {
-	POP	r0, r1
+	POPD0
         bl      _ZN13SharedRuntime3d2iEd
 	PUSH	r0
 	DISPATCH	\seq_len
 }
 
 (d2l) d2l {
-	POP	r0, r1
+	POPD0
         bl      _ZN13SharedRuntime3d2lEd
 	PUSH	r0, r1
 	DISPATCH	\seq_len
@@ -1825,6 +1819,7 @@
 
 	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	bl	return_check_monitors
@@ -1855,6 +1850,7 @@
 
 	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	bl	return_check_monitors
@@ -1886,6 +1882,7 @@
 
 	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	bl	return_check_monitors
@@ -2608,7 +2605,7 @@
 1:
 	ldrb	lr, [jpc, #-1]
 	add	lr, lr, #opc_iaccess_0-opc_aload_0
-	strb	lr, [jpc, #-1]
+	REWRITE_PAIRS	strb	lr, [jpc, #-1]
 	b	2b
 }
 
@@ -2617,7 +2614,7 @@
 (iload_0,iload_1,iload_2,iload_3)
 {
 	add	r0, r0, #opc_iload_0_iload_N-opc_iload_0
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_fast_iload_N_iload_N
 }
 
@@ -2659,7 +2656,7 @@
 (iload)
 {
 	add	r0, r0, #opc_iload_0_iload-opc_iload_0
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_fast_iload_N_iload
 }
 
@@ -2684,7 +2681,7 @@
 1:
 	ldrb	lr, [jpc, #-1]
 	add	lr, lr, #opc_iaccess_0-opc_aload_0
-	strb	lr, [jpc, #-1]
+	REWRITE_PAIRS	strb	lr, [jpc, #-1]
 	b	2b
 }
 
@@ -2710,7 +2707,7 @@
 (iload_0,iload_1,iload_2,iload_3)
 {
 	mov	r0, #opc_iload_iload_N
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_fast_iload_iload_N
 }
 
@@ -2731,7 +2728,7 @@
 
 (iload)(iload) {
 	mov	r0, #opc_iload_iload
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_fast_iload_iload
 }
 
@@ -2882,7 +2879,7 @@
 (iconst_m1,iconst_0,iconst_1,iconst_2,iconst_3,iconst_4,iconst_5)
 {
         add     r0, r0, #opc_iload_0_iconst_N-opc_iload_0
-        strb    r0, [jpc]
+        REWRITE_PAIRS	strb    r0, [jpc]
 	b	do_iload_0_iconst_N
 }
 
@@ -2903,7 +2900,8 @@
         DISPATCH_FINISH
 1:
         mov     tmp1, #opc_iload_iconst_N
-        strb    tmp1, [jpc, #-\seq_len]!
+        REWRITE_PAIRS	strb    tmp1, [jpc, #-\seq_len]
+	add	jpc, #-\seq_len
 	b	do_iload_iconst_N
 }
 
@@ -3859,6 +3857,7 @@
 
 	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
@@ -3888,6 +3887,7 @@
 
 	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
@@ -4069,7 +4069,7 @@
 (igetfield)
 {
 	add	r0, r0, #opc_iaccess_0-opc_aload_0
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	DISPATCH_BYTECODE
 }
 
@@ -4284,6 +4284,7 @@
 
 	str	stack, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 1:
 	PUSH	r1
@@ -4702,14 +4703,14 @@
 
 (iadd)(istore) {
 	mov	r0, #opc_iadd_u4store
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_iadd_u4store
 }
 
 (iadd)
 (istore_0,istore_1,istore_2,istore_3) {
 	mov	r0, #opc_iadd_istore_N
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_iadd_istore_N
 }
 
@@ -4824,14 +4825,14 @@
 
 (isub)(istore) {
 	mov	r0, #opc_isub_u4store
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_isub_u4store
 }
 
 (isub)
 (istore_0,istore_1,istore_2,istore_3) {
 	mov	r0, #opc_isub_istore_N
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_isub_istore_N
 }
 
@@ -4946,14 +4947,14 @@
 
 (iand)(istore) {
 	mov	r0, #opc_iand_u4store
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_iand_u4store
 }
 
 (iand)
 (istore_0,istore_1,istore_2,istore_3) {
 	mov	r0, #opc_iand_istore_N
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_iand_istore_N
 }
 
@@ -5068,14 +5069,14 @@
 
 (ior)(istore) {
 	mov	r0, #opc_ior_u4store
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_ior_u4store
 }
 
 (ior)
 (istore_0,istore_1,istore_2,istore_3) {
 	mov	r0, #opc_ior_istore_N
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_ior_istore_N
 }
 
@@ -5191,14 +5192,14 @@
 
 (ixor)(istore) {
 	mov	r0, #opc_ixor_u4store
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_ixor_u4store
 }
 
 (ixor)
 (istore_0,istore_1,istore_2,istore_3) {
 	mov	r0, #opc_ixor_istore_N
-	strb	r0, [jpc]
+	REWRITE_PAIRS	strb	r0, [jpc]
 	b	do_ixor_istore_N
 }
 
--- a/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Thu Oct 27 13:49:16 2011 +0100
+++ b/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Thu Oct 27 13:54:50 2011 +0100
@@ -267,6 +267,19 @@
 #endif
         .endm
 
+@------------------------------------------------
+@ Rewrite pairs of bytecodes
+@
+@ The fast bytecodes that replace pairs of codes improve performance,
+@ but they cause races between threads and incorrect operation in some
+@ other cases too.  REWRITE_PAIRS disables rewriting bytecode pairs.
+@	
+@ Usage:
+@	REWRITE_PAIRS	<instruction>
+@------------------------------------------------
+	.macro	REWRITE_PAIRS	p1, p2, p3, p4
+        .endm
+
 	.macro	Opcode	label
 	ALIGN_OPCODE
 do_\label:
@@ -314,6 +327,63 @@
   .endif
 	.endm
 
+	.macro POPF0
+#ifdef __ARM_PCS_VFP
+	flds s0, [stack, #4]
+	add stack, #4
+#else
+	POP r0
+#endif
+	.endm
+	
+	.macro POPF1
+#ifdef __ARM_PCS_VFP
+	flds s1, [stack, #4]
+	add stack, #4
+#else
+	POP r0
+#endif
+	.endm
+	
+	.macro POPD0
+#ifdef __ARM_PCS_VFP
+	flds s0, [stack, #4]
+	flds s1, [stack, #8]
+	add stack, #8
+#else
+	POP r0, r1
+#endif
+	.endm
+	
+	.macro POPD1
+#ifdef __ARM_PCS_VFP
+	flds s2, [stack, #4]
+	flds s3, [stack, #8]
+	add stack, #8
+#else
+	POP r2, r3
+#endif
+	.endm
+	
+	.macro PUSHF0
+#ifdef __ARM_PCS_VFP
+	add stack, #-4
+	fsts s0, [stack, #4]
+#else
+	PUSH r0
+#endif
+	.endm
+	
+	.macro PUSHD0
+#ifdef __ARM_PCS_VFP
+	add stack, #-8
+	fsts s0, [stack, #4]
+	fsts s1, [stack, #8]
+#else
+	POP r0, r1
+#endif
+	.endm
+	
 	.macro	CACHE_JPC
 	ldr	jpc, [istate, #ISTATE_BCP]
 	.endm
@@ -496,19 +566,29 @@
 #else
 	.arch armv7-a
 #endif
+
 #ifdef HW_FP
+
+#ifdef __ARM_PCS_VFP
+ 	.fpu vfpv3-d16
+	.eabi_attribute Tag_ABI_HardFP_use, 3
+	.eabi_attribute Tag_ABI_VFP_args, 1
+#else // __ARM_PCS_VFP
 	.fpu vfp
-#else
+#endif // __ARM_PCS_VFP
+
+#else // HW_FP
 	.fpu softvfp
-#endif
-	.eabi_attribute 20, 1
-	.eabi_attribute 21, 1
-	.eabi_attribute 23, 3
-	.eabi_attribute 24, 1
-	.eabi_attribute 25, 1
-	.eabi_attribute 26, 2
-	.eabi_attribute 30, 2
-	.eabi_attribute 18, 4
+#endif // HW_FP
+
+	.eabi_attribute Tag_ABI_FP_denormal, 1
+	.eabi_attribute Tag_ABI_FP_exceptions, 1
+	.eabi_attribute Tag_ABI_FP_number_model, 3
+	.eabi_attribute Tag_ABI_align8_needed, 1
+	.eabi_attribute Tag_ABI_align8_preserved, 1
+	.eabi_attribute Tag_ABI_enum_size, 2
+	.eabi_attribute Tag_ABI_optimization_goals, 2
+	.eabi_attribute Tag_ABI_PCS_wchar_t, 4
 
 	.text
 
@@ -623,6 +703,10 @@
 	mov	r3, r0
 	mov	r0, #0
 #ifdef PRODUCT
+	// These entry points can not be used when PRODUCT is
+	// undefined because the BytecodeInterpreter class is virtual
+	// so it has an extra word (the vtable pointer) at its
+	// beginning.
 	adrl	ip, dispatch_init_adcon
 	ldm	ip, {r1, r2}
 	add	r1, r1, ip
@@ -641,8 +725,8 @@
 	cmp	r3, #14
 	adrcc	ip, asm_method_table
 	ldrcc	r0, [ip, r3, lsl #2]
+#endif // PRODUCT
 1:
-#endif // PRODUCT
 	bx	lr
 asm_method_table:
 	.word	normal_entry
@@ -688,6 +772,7 @@
 	ldr	r1, [r2, #THREAD_JAVA_SP]
 	add	r1, r1, r3, lsl #2
 	str	r1, [r2, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
 	bx	lr
 .L1359:
 	.word	_GLOBAL_OFFSET_TABLE_-(.LPIC19+8)
@@ -829,7 +914,8 @@
 	ALIGN_CODE
 native_entry:
 	stmfd	arm_sp!, {regset, lr}
-	bl	fast_native_entry
+	bl	fast_native_entry	
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmia	sp!, {regset, pc}
 
 	ALIGN_CODE
@@ -872,6 +958,7 @@
 	str	r7, [r9, #ISTATE_LOCALS]
 	str	r10, [r9, #ISTATE_CONSTANTS]
 	str	r11, [r9, #ISTATE_METHOD]
+	str     r9, [r9, #ISTATE_SELF_LINK]
 
 @	stmia	r9, {r2, r5, r7, r10, r11}
 	ldr	r1, [r2, #THREAD_STACK_SIZE]
@@ -886,12 +973,18 @@
 	blt	.fast_native_entry_throw_stack_overflow
 	cmp	r5, #0
 	bne	.fast_native_entry_got_handleraddr
+	str	r5, [r9, #THREAD_LAST_JAVA_SP] @ r5 is zero at this point
+	str	r0, [r9, #THREAD_LAST_JAVA_FP]
+	ldr	r0, [r9, #THREAD_JAVA_SP]
 	str	r0, [r9, #THREAD_LAST_JAVA_SP]
 	mov	r0, r9
 	mov	r1, r11
 	bl	_ZN18InterpreterRuntime19prepare_native_callEP10JavaThreadP13methodOopDesc
 	ldr	r11, [r9, #THREAD_TOP_ZERO_FRAME]
 	ldr	r1, [r9, #THREAD_PENDING_EXC]
+	str	r5, [r9, #THREAD_LAST_JAVA_SP]  @ r5 is zero at this point
+	str	r5, [r9, #THREAD_LAST_JAVA_FP]
+	ldr	r5, [r9, #THREAD_JAVA_SP]
 	str	r5, [r9, #THREAD_LAST_JAVA_SP]
 	ldr	r11, [r11, #-72 + ISTATE_METHOD]
 	cmp	r1, #0
@@ -902,8 +995,13 @@
 	cmp	r5, r2
 	bne	.fast_native_entry_get_handler
 	ldr	r3, [r9, #THREAD_TOP_ZERO_FRAME]
+	stmfd	sp!, {r2}
 	mov	r2, #0
+        str     r2, [r9, #THREAD_LAST_JAVA_SP]
+	ldmfd	sp!, {r2}
 	mov	r0, r9
+	str	r3, [r9, #THREAD_LAST_JAVA_FP]
+	ldr	r3, [r9, #THREAD_JAVA_SP]
 	str	r3, [r9, #THREAD_LAST_JAVA_SP]
 	mov	r3, r2
 	mov	r1, r11
@@ -914,6 +1012,7 @@
 	ldr	r11, [r11, #-72 + ISTATE_METHOD]
 	cmp	r1, #0
 	str	r3, [r9, #THREAD_LAST_JAVA_SP]
+	str	r3, [r9, #THREAD_LAST_JAVA_FP]
 	mov	r5, r0
 	bne	.fast_native_entry_exception
 .fast_native_entry_get_handler:
@@ -928,7 +1027,7 @@
 	sub	arm_sp, arm_sp, #16
 
 	bic	lr, lr, #1
-	add	r1, r5, #24
+	add	r1, r5, #SIZEOF_FFI_CIF
 
 	sub	arm_sp, arm_sp, lr, lsl #2
 	add	r2, r9, #THREAD_JNI_ENVIRONMENT
@@ -936,6 +1035,10 @@
 	mov	lr, arm_sp
 	str	r2, [lr], #4
 
+#ifdef __ARM_PCS_VFP
+	mov	r10, #0xff	@ bitmap for floating-point register set
+	orr	r10, #0xff00
+#endif	
 	ldr	r2, [r11, #METHOD_ACCESSFLAGS]
 	add	r1, r1, #4
 	tst	r2, #JVM_ACC_STATIC
@@ -948,7 +1051,6 @@
 	add	r1, r1, #4
 	str	r2, [r3]
 
-
 .do_fast_copy_args:
 	cmp	ip, #0
 	blt	.fast_no_args
@@ -956,9 +1058,12 @@
 .fast_copy_args:
 	ldr	r0, [r1], #4
 	ldrh	r3, [r0, #6]
+	cmp	r3, #FFI_TYPE_DOUBLE
+	beq	.fast_copy_double
+	cmp	r3, #FFI_TYPE_FLOAT
+	beq	.fast_copy_float
 	ldr	r2, [r7], #-4
-	cmp	r3, #FFI_TYPE_DOUBLE
-	cmpne	r3, #FFI_TYPE_SINT64
+	cmp	r3, #FFI_TYPE_SINT64
 	beq	.fast_copy_long
 
 	cmp	r3, #FFI_TYPE_POINTER
@@ -969,6 +1074,69 @@
 	bge	.fast_copy_args
 	b	.fast_no_args
 
+#ifdef __ARM_PCS_VFP
+	// FIXME: These macros are very inefficient
+	.macro	FIND_LOWEST_BIT	rd, rs
+	mov	\rd, #0
+0:	tst	\rs, #1
+	lsr	\rs, #1
+	addeq	\rd, #1
+	beq	0b
+	lsl	\rs, \rd
+	lsl	\rs, #1
+	.endm
+	
+	.macro	FIND_LOWEST_BIT_PAIR rd, rs
+	stmfd	sp!, {r1}
+	stmfd	sp!, {\rs}
+	mov	\rd, #0
+0:	tst	\rs, #1
+	lsr	\rs, #2
+	addeq	\rd, #2
+	beq	0b
+	ldmfd	sp!, {\rs}
+	mov	r1, #3
+	lsl	r1, \rd
+	bic	\rs, r1
+	ldmfd	sp!, {r1}
+	.endm
+	
+.fast_copy_double:
+	orrs	r10, r10
+	ldreq	r2, [r7], #-4	
+	beq	vm_fatal_error
+	FIND_LOWEST_BIT_PAIR r0, r10
+	adrl	r2, .copy_double_table
+	add	pc, r2, r0, asl#5
+
+.fast_copy_float:
+	orrs	r10, r10
+	ldreq	r2, [r7], #-4	
+	beq	vm_fatal_error
+	FIND_LOWEST_BIT r0, r10
+	adr	r2, .copy_float_table
+	add	pc, r2, r0, asl#6
+#else
+
+.fast_copy_double:
+	ldr	r2, [r7], #-4
+	tst	lr, #4
+	ldr	r3, [r7], #-4
+	addne	lr, lr, #4
+	str	r2, [lr, #4]
+	subs	ip, ip, #2
+	str	r3, [lr], #8
+	bge	.fast_copy_args
+	b	.fast_no_args
+	
+.fast_copy_float:
+	ldr	r2, [r7], #-4
+	subs	ip, ip, #1
+	str	r2, [lr], #4
+	bge	.fast_copy_args
+
+#endif
+
 .fast_copy_long:
 	tst	lr, #4
 	ldr	r3, [r7], #-4
@@ -990,9 +1158,15 @@
 	ldr	r0, [r9, #THREAD_TOP_ZERO_FRAME]
 	mov	r2, #_thread_in_native
 
-	str	r0, [r9, #THREAD_LAST_JAVA_SP]
+	mov	ip, #0
+	str	ip, [r9, #THREAD_LAST_JAVA_SP]
+
+	str	r0, [r9, #THREAD_LAST_JAVA_FP]
 	str	r2, [r9, #THREAD_STATE]
 
+	ldr	r2, [r9, #THREAD_JAVA_SP]
+	str	r2, [r9, #THREAD_LAST_JAVA_SP]
+
 	ldr	ip, [r11, #METHOD_NATIVEHANDLER]
 	ldrh	r11, [r11, #METHOD_SIZEOFPARAMETERS]
 
@@ -1017,8 +1191,9 @@
 
 	str	r3, [r9, #THREAD_STATE]
 	str	r2, [r9, #THREAD_LAST_JAVA_SP]
-
-	add	r2, r5, #24
+	str	r2, [r9, #THREAD_LAST_JAVA_FP]
+
+	add	r2, r5, #SIZEOF_FFI_CIF
 	ldr	r3, [r5, #4]
 
 	ldr	r5, [r9, #THREAD_TOP_ZERO_FRAME]
@@ -1039,8 +1214,13 @@
 .return_type_table:
 	.word	.fast_native_return_void	@ FFI_TYPE_VOID	== 0
 	.word	0
+#ifdef __ARM_PCS_VFP
+	.word	.fast_native_return_float	@ FFI_TYPE_FLOAT == 2
+	.word	.fast_native_return_double	@ FFI_TYPE_DOUBLE == 3
+#else
 	.word	.fast_native_return_w		@ FFI_TYPE_FLOAT == 2
 	.word	.fast_native_return_dw		@ FFI_TYPE_DOUBLE == 3
+#endif
 	.word	0
 	.word	.fast_native_return_bool	@ FFI_TYPE_BOOL == 5
 	.word	.fast_native_return_byte	@ FFI_TYPE_SINT8 == 6
@@ -1053,6 +1233,25 @@
 	.word	0
 	.word	.fast_native_return_obj		@ FFI_TYPE_POINTER == 14
 
+#ifdef __ARM_PCS_VFP
+.fast_native_return_double:
+	fsts	s0, [r5, #-8]
+	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
+	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
+	fsts	s1, [r5, #-4]
+	add	r5, #-8
+	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
+	ldmfd	arm_sp!, {fast_regset, pc}
+.fast_native_return_float:
+	fsts	s0, [r5, #-4]
+	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
+	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
+	add	r5, #-4
+	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
+	ldmfd	arm_sp!, {fast_regset, pc}
+#endif
 .fast_native_return_dw:
 	str	r0, [r5, #-8]!
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
@@ -1067,6 +1266,7 @@
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r0, [r5, #-4]!
 	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_char:
 	mov	r0, r0, lsl #16
@@ -1075,6 +1275,7 @@
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r0, [r5, #-4]!
 	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_bool:
 	ands	r0, r0, #255
@@ -1083,6 +1284,7 @@
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r0, [r5, #-4]!
 	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_obj:
 	cmp	r0, #0
@@ -1091,6 +1293,7 @@
 	str	lr, [r9, #THREAD_TOP_ZERO_FRAME]
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 .fast_native_return_short:
 	mov	r0, r0, lsl #16
@@ -1102,14 +1305,16 @@
 	str	tmp1, [ip, #JNIHANDLEBLOCK_TOP]
 .fast_native_exit:
 	str	r5, [r9, #THREAD_JAVA_SP]
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 
 .fast_native_entry_throw_stack_overflow:
-	str	r0, [r9, #THREAD_LAST_JAVA_SP]
+	str	r0, [r9, #THREAD_LAST_JAVA_FP]
 	mov	r0, r9
 	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
 	mov	r3, #0
 	ldr	r1, [r9, #THREAD_PENDING_EXC]
+	str	r3, [r9, #THREAD_LAST_JAVA_FP]
 	str	r3, [r9, #THREAD_LAST_JAVA_SP]
 .fast_native_entry_exception:
 	ldr	r5, [r9, #THREAD_TOP_ZERO_FRAME]
@@ -1127,6 +1332,84 @@
 	ldmia	arm_sp!, {r0, r1}
 	b	.fast_native_entry_do_return
 
+
+	
+#ifdef __ARM_PCS_VFP
+
+	.macro	COPY_FLOAT rs, rd, rcount
+	.align	6
+	flds	\rd, [\rs]
+	add	\rs, #-4
+	subs	\rcount, #1
+	bge	.fast_copy_args
+	b	.fast_no_args
+	.endm
+
+	.align	6
+.copy_float_table:
+	COPY_FLOAT r7, s0, ip
+	COPY_FLOAT r7, s1, ip
+	COPY_FLOAT r7, s2, ip
+	COPY_FLOAT r7, s3, ip
+	COPY_FLOAT r7, s4, ip
+	COPY_FLOAT r7, s5, ip
+	COPY_FLOAT r7, s6, ip
+	COPY_FLOAT r7, s7, ip
+	COPY_FLOAT r7, s8, ip
+	COPY_FLOAT r7, s9, ip
+	COPY_FLOAT r7, s10, ip
+	COPY_FLOAT r7, s11, ip
+	COPY_FLOAT r7, s12, ip
+	COPY_FLOAT r7, s13, ip
+	COPY_FLOAT r7, s14, ip
+	COPY_FLOAT r7, s15, ip
+	COPY_FLOAT r7, s16, ip
+	COPY_FLOAT r7, s17, ip
+	COPY_FLOAT r7, s18, ip
+	COPY_FLOAT r7, s19, ip
+	COPY_FLOAT r7, s20, ip
+	COPY_FLOAT r7, s21, ip
+	COPY_FLOAT r7, s22, ip
+	COPY_FLOAT r7, s23, ip
+	COPY_FLOAT r7, s24, ip
+	COPY_FLOAT r7, s25, ip
+	COPY_FLOAT r7, s26, ip
+	COPY_FLOAT r7, s27, ip
+	COPY_FLOAT r7, s28, ip
+	COPY_FLOAT r7, s29, ip
+	COPY_FLOAT r7, s30, ip
+	COPY_FLOAT r7, s31, ip
+
+	.macro	COPY_DOUBLE rs, rdlo, rdhi, rcount
+	.align	6
+	flds	\rdhi, [\rs]
+	flds	\rdlo, [\rs, #-4]
+	add	\rs, #-8
+	subs	\rcount, #2
+	bge	.fast_copy_args
+	b	.fast_no_args
+	.endm
+
+	.align	6
+.copy_double_table:
+	COPY_DOUBLE r7, s0, s1, ip
+	COPY_DOUBLE r7, s2, s3, ip
+	COPY_DOUBLE r7, s4, s5, ip
+	COPY_DOUBLE r7, s6, s7, ip
+	COPY_DOUBLE r7, s8, s9, ip
+	COPY_DOUBLE r7, s10, s11, ip
+	COPY_DOUBLE r7, s12, s13, ip
+	COPY_DOUBLE r7, s14, s15, ip
+	COPY_DOUBLE r7, s16, s17, ip
+	COPY_DOUBLE r7, s18, s19, ip
+	COPY_DOUBLE r7, s20, s21, ip
+	COPY_DOUBLE r7, s22, s23, ip
+	COPY_DOUBLE r7, s24, s25, ip
+	COPY_DOUBLE r7, s26, s27, ip
+	COPY_DOUBLE r7, s28, s29, ip
+	COPY_DOUBLE r7, s30, s31, ip
+#endif
+
 #include "bytecodes_arm.s"
 
 	Opcode	idiv
@@ -1337,6 +1620,7 @@
 	mov	lr, pc
 	ldr	pc, [tmp1]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 
 #endif // THUMB2EE
@@ -1757,7 +2041,8 @@
 	DISPATCH 3
 
 bytecode_interpreter_str:
-	.ascii  "[Bytecode Interpreter]\000"
+	.ascii  __FILE__
+	.byte 0
 	ALIGN_WORD
 
 	Opcode	newarray
@@ -1955,8 +2240,13 @@
 	str	r3, [istate, #ISTATE_STACK_LIMIT]
 	str	r0, [r1, #4]
 	ldr	r1, [istate, #ISTATE_THREAD]
+
+	str	r0, [r1, #THREAD_LAST_JAVA_SP]  @ set SP to zero before setting FP
 	ldr	r3, [r1, #THREAD_TOP_ZERO_FRAME]
+	str	r3, [r1, #THREAD_LAST_JAVA_FP]
+	ldr	r3, [r1, #THREAD_JAVA_SP]	
 	str	r3, [r1, #THREAD_LAST_JAVA_SP]
+
 	CACHE_STACK
 	ldr	sl, [istate, #ISTATE_STACK_BASE]
 	ldr	r3, [stack, #4]
@@ -2268,10 +2558,11 @@
 	adrcs	ip, unknown_bytecode
 	ldrcc	ip, [r2, r3, asl #2]
 	adr	r2, unimplemented_opcode_msg
-	mov	r1, #99
+	ldr	r1, =__LINE__
 	str	ip, [arm_sp, #-8]!
-	bl	_Z19report_fatal_varargPKciS0_z
+	bl	Helper_report_fatal
 	b	breakpoint
+	.ltorg
 unimplemented_opcode_msg:
 	.ascii  "\011*** Unimplemented opcode: %d = %s\012\000"
 unknown_bytecode:
@@ -2300,6 +2591,7 @@
 normal_entry_synchronized:
 	stmfd	arm_sp!, {regset, lr}
 	bl	fast_normal_entry_synchronized
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {regset, pc}
 
 	ALIGN_CODE
@@ -2347,15 +2639,23 @@
 	bl	build_frame
 	mov	tmp_vvv, r0
 	ldr	r3, [tmp1, #THREAD_TOP_ZERO_FRAME]
-	sub	r0, r0, #72
+	sub	r0, r0, #72	@ This mysterious constant is actually the offset of
+				@ the next frame field.  Why is "ISTATE_NEXT_FRAME"
+				@ not used here?
 	mov	istate, r0
 	str	r3, [tmp_vvv, #0]
 	adrl	ip, dispatch_init_adcon
+	ldr	r1, [tmp1, #THREAD_JAVA_SP]
+	str	r1, [tmp1, #THREAD_LAST_JAVA_SP]
 	ldm	ip, {r0, r1}
 	add	r0, r0, ip
 	str	tmp_vvv, [tmp1, #THREAD_TOP_ZERO_FRAME]
 @	CACHE_JPC
-	str	tmp_vvv, [tmp1, #THREAD_LAST_JAVA_SP]
+	mov	r2, #0  @ set SP to zero before setting FP
+	str	r2, [tmp1, #THREAD_LAST_JAVA_SP]
+	str	tmp_vvv, [tmp1, #THREAD_LAST_JAVA_FP]
+	ldr	r3, [tmp1, #THREAD_JAVA_SP]
+	str	r3, [tmp1, #THREAD_LAST_JAVA_SP]
 	add	dispatch, r1, r0
 	ldr	r0, [istate, #ISTATE_METHOD]
 	ldr	r3, [r0, #METHOD_ACCESSFLAGS]
@@ -2500,6 +2800,7 @@
 	ldr	ip, [tmp2, #METHOD_FROM_INTERPRETED]
 	mov	r1, #0
 	str	ip, [istate, #36]
+	str	r1, [tmp1, #THREAD_LAST_JAVA_FP]
 	str	r1, [tmp1, #THREAD_LAST_JAVA_SP]
 
 	add	stack, stack, #4
@@ -2528,9 +2829,15 @@
 	ldr	r2, [istate, #ISTATE_STACK_LIMIT]
 	sub	stack, stack, #4
 
+	ldr	r1, [ip, #THREAD_JAVA_SP]
+	stmfd	arm_sp!, {r1}
+	mov	r1, #0
+	str	r1, [ip, #THREAD_LAST_JAVA_SP]
 	ldr	r1, [ip, #THREAD_TOP_ZERO_FRAME]
 	add	r2, r2, #4
 	str	r2, [ip, #THREAD_JAVA_SP]
+	str	r1, [ip, #THREAD_LAST_JAVA_FP]
+	ldmfd	arm_sp!, {r1}
 	str	r1, [ip, #THREAD_LAST_JAVA_SP]
 	DISPATCH_START	5
 	ldr	r3, [ip, #4]
@@ -2679,8 +2986,11 @@
 
 	ldr	r1, [ip, #THREAD_TOP_ZERO_FRAME]
 	add	r2, r2, #4
+	mov	r3, #0
+	str	r3, [ip, #THREAD_LAST_JAVA_SP]
 	str	r2, [ip, #THREAD_JAVA_SP]
-	str	r1, [ip, #THREAD_LAST_JAVA_SP]
+	str	r1, [ip, #THREAD_LAST_JAVA_FP]
+	str	r2, [ip, #THREAD_LAST_JAVA_SP]
 	DISPATCH_START	3
 	ldr	r3, [ip, #4]
 	DISPATCH_NEXT
@@ -2717,6 +3027,7 @@
 	ldr	tmp1, [istate, #ISTATE_THREAD]
 	str	r3, [istate, #36]
 	str	r1, [tmp1, #THREAD_LAST_JAVA_SP]
+	str	r1, [tmp1, #THREAD_LAST_JAVA_FP]
 
 	add	stack, stack, #4
 	str	stack, [tmp1, #THREAD_JAVA_SP]
@@ -2780,6 +3091,7 @@
 
 	bl	fast_normal_entry
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {regset, pc}
 
 	ALIGN_CODE
@@ -2810,7 +3122,7 @@
 
         subs    r5, r7, #2
         tst     r7, #1
-        strne   r1, [stack, #-4]!
+        strne   r1, [stack, #-4]!  // stack->push(0);
         bcc     3f
 1:
         str     r1, [stack, #-4]
@@ -2820,14 +3132,13 @@
 3:
 	ldr	r3, [tmp1, #THREAD_TOP_ZERO_FRAME]
 	mov	lr, #0
-        sub     istate, stack, #FRAME_SIZE
+        sub     istate, stack, #FRAME_SIZE     // stack->push(INTERPRETER_FRAME);
         sub     r2, istate, r2, lsl #2
         str     lr, [istate, #ISTATE_MSG]
 	str	r2, [tmp1, #THREAD_JAVA_SP]
         sub     r5, r2, #4                      @ stack limit = istate - stackwords - 4
 	str	r3, [istate, #ISTATE_NEXT_FRAME]
 	str	ip, [istate, #ISTATE_FRAME_TYPE]
-@	str	istate, [istate, #ISTATE_SELF_LINK]
 	str	istate, [istate, #ISTATE_MONITOR_BASE]
 	str	r5, [istate, #ISTATE_STACK_LIMIT]
 	str	istate, [istate, #ISTATE_STACK_BASE]
@@ -2842,6 +3153,10 @@
         ldr     constpool, [constpool, #CONSTANTPOOL_CACHE]
         str     ip, [tmp1, #THREAD_TOP_ZERO_FRAME]
   USEC	ldr	r3, [r10, #METHOD_INVOCATIONCOUNTER]
+	mov	r1, #0
+        str     r1, [tmp1, #THREAD_LAST_JAVA_SP]
+        str     ip, [tmp1, #THREAD_LAST_JAVA_FP]
+	ldr	ip, [tmp1, #THREAD_JAVA_SP]
         str     ip, [tmp1, #THREAD_LAST_JAVA_SP]
 	DISPATCH_NEXT
   USEC	ldr	lr, [dispatch, #InterpreterInvocationLimit_Address-XXX]
@@ -2857,6 +3172,7 @@
 	DISPATCH_NEXT
 	DISPATCH_NEXT
 	str	r10, [istate, #ISTATE_METHOD]
+ 	str	istate, [istate, #ISTATE_SELF_LINK]
 @	mov	lr, #0
 @        str     lr, [istate, #ISTATE_PREV_LINK]
 @	str	lr, [istate, #ISTATE_CALLEE]
@@ -2919,6 +3235,7 @@
 
 	ldr	r2, [tmp_xxx, #THREAD_TOP_ZERO_FRAME]
 	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_SP]
+	str	r3, [tmp_xxx, #THREAD_LAST_JAVA_FP]
 	ldr	r0, [istate, #ISTATE_METHOD]
 	ldr	r3, [r2, #0]
 	ldrh	r0, [r0, #40]
@@ -2939,19 +3256,28 @@
 
 	str	r1, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 
 @ ----------------------------------------------------------------------------------------
 stack_overflow_no_frame:
 	mov	r0, tmp1
+	mov	ip, #0
+	str	ip, [r0, #THREAD_LAST_JAVA_SP]
 	ldr	ip, [r0, #THREAD_TOP_ZERO_FRAME]
+	str	ip, [r0, #THREAD_LAST_JAVA_FP]
+	ldr	ip, [r0, #THREAD_JAVA_SP]
 	str	ip, [r0, #THREAD_LAST_JAVA_SP]
 	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
 	ldmfd	arm_sp!, {regset, pc}
 
 stack_overflow_before_frame:
 	mov	r0, tmp1
+	mov	ip, #0
+	str	ip, [r0, #THREAD_LAST_JAVA_SP]
 	ldr	ip, [r0, #THREAD_TOP_ZERO_FRAME]
+	str	ip, [r0, #THREAD_LAST_JAVA_FP]
+	ldr	ip, [r0, #THREAD_JAVA_SP]
 	str	ip, [r0, #THREAD_LAST_JAVA_SP]
 	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
 	ldmfd	arm_sp!, {fast_regset, pc}
@@ -3049,6 +3375,7 @@
 
 	str	r1, [tmp_xxx, #THREAD_JAVA_SP]
 
+	mov	r0, #0	@ deoptimized_frames = 0
 	ldmfd	arm_sp!, {fast_regset, pc}
 
 return_check_monitors:
@@ -3129,6 +3456,7 @@
   USEC	bcs	normal_entry
 
 	ldr	r1, [r0, #METHOD_CONSTMETHOD]
+
 	ldrb	r3, [r1, #CONSTMETHOD_CODEOFFSET+2]
 	ldrb	r1, [r1, #CONSTMETHOD_CODEOFFSET+3]
 	ldr	ip, [r0, #METHOD_CONSTANTS]
@@ -3153,6 +3481,7 @@
 
 	ldr	r0, [r3, r1]
 	str	r0, [ip, #0]
+	mov	r0, #0
 	bx	lr
 
 .fast_accessor_non_w:
@@ -4893,6 +5222,7 @@
 	mov	r1, #0
 	str	ip, [istate, #36]
 	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_FP]
 
 	add	stack, stack, #4
 	str	stack, [Rthread, #THREAD_JAVA_SP]
@@ -4914,8 +5244,11 @@
 
 	ldr	r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
 	add	r2, r2, #4
+	mov	r0, #0
+	str	r0, [Rthread, #THREAD_LAST_JAVA_SP]
 	str	r2, [Rthread, #THREAD_JAVA_SP]
-	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_FP]
+	str	r2, [Rthread, #THREAD_LAST_JAVA_SP]
 	ldr	r3, [Rthread, #4]
 	cmp	r3, #0
 	bne	istub_exception
@@ -5011,6 +5344,7 @@
 	mov	r1, #0
         ldr     ip, [tmp2, #METHOD_FROM_INTERPRETED]
         str     r1, [Rthread, #THREAD_LAST_JAVA_SP]
+        str     r1, [Rthread, #THREAD_LAST_JAVA_FP]
         str     ip, [istate, #36]
 
         add     stack, stack, #4
@@ -5031,10 +5365,13 @@
 	ldr	stack, [Rthread, #THREAD_JAVA_SP]
 	ldr	r2, [istate, #ISTATE_STACK_LIMIT]
 
+	mov	r0, #0
+	str	r0, [Rthread, #THREAD_LAST_JAVA_SP]
 	ldr	r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
 	add	r2, r2, #4
 	str	r2, [Rthread, #THREAD_JAVA_SP]
-	str	r1, [Rthread, #THREAD_LAST_JAVA_SP]
+	str	r1, [Rthread, #THREAD_LAST_JAVA_FP]
+	str	r2, [Rthread, #THREAD_LAST_JAVA_SP]
 	ldr	r3, [Rthread, #4]
 	cmp	r3, #0
 	bne	istub_exception
@@ -5099,11 +5436,15 @@
 
         ldr     r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
         add     r2, r2, #4
+	mov	r3, #0
+	str	r3, [Rthread, #THREAD_LAST_JAVA_SP]	
+        str     r1, [Rthread, #THREAD_LAST_JAVA_FP]
         str     r2, [Rthread, #THREAD_JAVA_SP]
-        str     r1, [Rthread, #THREAD_LAST_JAVA_SP]
+        str     r2, [Rthread, #THREAD_LAST_JAVA_SP]
         ldr     r3, [Rthread, #4]
         cmp     r3, #0
         bne     istub_exception
+	mov	r0, #0
         ldmia   sp!, {ip, pc}
 
 isstub_resolve:
@@ -5172,7 +5513,8 @@
         ldr     r1, [Rthread, #THREAD_TOP_ZERO_FRAME]
         add     r2, r2, #4
         str     r2, [Rthread, #THREAD_JAVA_SP]
-        str     r1, [Rthread, #THREAD_LAST_JAVA_SP]
+        str     r2, [Rthread, #THREAD_LAST_JAVA_SP]
+        str     r1, [Rthread, #THREAD_LAST_JAVA_FP]
         ldr     r3, [Rthread, #4]
         cmp     r3, #0
         bne     istub_exception
@@ -6263,9 +6605,14 @@
 
 Thumb2_Stack_Overflow:
 	mov	r0, r2
+	mov	r2, #0
+	str	r2, [r0, #THREAD_LAST_JAVA_SP]
 	ldr	ip, [r0, #THREAD_TOP_ZERO_FRAME]
-	str	ip, [r0, #THREAD_LAST_JAVA_SP]
+	ldr	r2, [r0, #THREAD_JAVA_SP]
+	str	ip, [r0, #THREAD_LAST_JAVA_FP]
+	str	r2, [r0, #THREAD_LAST_JAVA_SP]
 	bl	_ZN18InterpreterRuntime24throw_StackOverflowErrorEP10JavaThread
+	mov	r0, #0
 	ldmfd	arm_sp!, {fast_regset, pc}
 
 	.global	Thumb2_Exit_To_Interpreter
--- a/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Thu Oct 27 13:49:16 2011 +0100
+++ b/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Thu Oct 27 13:54:50 2011 +0100
@@ -51,7 +51,8 @@
 
 #include <sys/mman.h>
 
-#include "incls/_precompiled.incl"
+#include "precompiled.hpp"
+#include "interpreter/bytecodes.hpp"
 
 #ifdef T2EE_PRINT_DISASS
 #include "dis-asm.h"
@@ -282,32 +283,33 @@
 #define opc_invokestaticresolved	0xe1
 #define opc_invokevfinal		0xe2
 #define opc_iload_iload			0xe3
-#define opc_iload_iload_N		0xe4
-#define opc_return_register_finalizer	0xe5
-#define opc_dmac			0xe6
-#define opc_iload_0_iconst_N		0xe7
-#define opc_iload_1_iconst_N		0xe8
-#define opc_iload_2_iconst_N		0xe9
-#define opc_iload_3_iconst_N		0xea
-#define opc_iload_iconst_N		0xeb
-#define opc_iadd_istore_N		0xec
-#define opc_isub_istore_N		0xed
-#define opc_iand_istore_N		0xee
-#define opc_ior_istore_N		0xef
-#define opc_ixor_istore_N		0xf0
-#define opc_iadd_u4store		0xf1
-#define opc_isub_u4store		0xf2
-#define opc_iand_u4store		0xf3
-#define opc_ior_u4store			0xf4
-#define opc_ixor_u4store		0xf5
-#define opc_iload_0_iload		0xf6
-#define opc_iload_1_iload		0xf7
-#define opc_iload_2_iload		0xf8
-#define opc_iload_3_iload		0xf9
-#define opc_iload_0_iload_N		0xfa
-#define opc_iload_1_iload_N		0xfb
-#define opc_iload_2_iload_N		0xfc
-#define opc_iload_3_iload_N		0xfd
+
+#define opc_return_register_finalizer   0xe7
+#define opc_dmac                        0xe8
+#define opc_iload_0_iconst_N            0xe9
+#define opc_iload_1_iconst_N            0xea
+#define opc_iload_2_iconst_N            0xeb
+#define opc_iload_3_iconst_N            0xec
+#define opc_iload_iconst_N              0xed
+#define opc_iadd_istore_N               0xee
+#define opc_isub_istore_N               0xef
+#define opc_iand_istore_N               0xf0
+#define opc_ior_istore_N                0xf1
+#define opc_ixor_istore_N               0xf2
+#define opc_iadd_u4store                0xf3
+#define opc_isub_u4store                0xf4
+#define opc_iand_u4store                0xf5
+#define opc_ior_u4store                 0xf6
+#define opc_ixor_u4store                0xf7
+#define opc_iload_0_iload               0xf8
+#define opc_iload_1_iload               0xf9
+#define opc_iload_2_iload               0xfa
+#define opc_iload_3_iload               0xfb
+#define opc_iload_0_iload_N             0xfc
+#define opc_iload_1_iload_N             0xfd
+#define opc_iload_2_iload_N             0xfe
+#define opc_iload_3_iload_N             0xff
+
 
 #define H_IREM				0
 #define H_IDIV				1
@@ -776,7 +778,12 @@
 	    opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
 	}
 	len = Bytecodes::length_for((Bytecodes::Code)opcode);
-	if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+	if (len <= 0) {
+	  Bytecodes::Code code = Bytecodes::code_at(NULL, (address)(code_base+bci));
+	  len = (Bytecodes::special_length_at
+		 (code,
+		  (address)(code_base+bci), (address)(code_base+code_size)));
+	}
 	switch (opcode) {
 	  case opc_tableswitch: {
 	    int nbci = (bci & ~3) + 4;
@@ -1150,6 +1157,8 @@
 	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokevfinal
 	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_INT),	// iload_iload
 	BCI(2, 0, 1, 0, 1, 0, 0, 0, BCI_TYPE_INT),	// iload_iload_N
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// impdep1
+	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// impdep2
 	BCI(1, 0, 0, 1, 0, 0, 0, 0, 0),	// return_register_finalizer
 	BCI(1, 4, 2, 0, 0, 0, 0, 0, 0),	// dmac
 	BCI(1, 0, 1, 0, 1, 1, 0, 0, BCI_TYPE_INT),	// iload_0_iconst_N
@@ -1175,8 +1184,6 @@
 	BCI(1, 0, 1, 0, 1, 1, 0, 1, BCI_TYPE_INT),	// iload_1_iload_N
 	BCI(1, 0, 1, 0, 1, 1, 0, 2, BCI_TYPE_INT),	// iload_2_iload_N
 	BCI(1, 0, 1, 0, 1, 1, 0, 3, BCI_TYPE_INT),	// iload_3_iload_N
-	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// impdep1
-	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// impdep2
 };
 
 void Thumb2_pass1(Thumb2_Info *jinfo, unsigned bci)
@@ -1369,7 +1376,7 @@
 
       default:
 	opcode = code_base[bci];
-	fatal1("Undefined opcode %d\n", opcode);
+	fatal(err_msg("Undefined opcode %d\n", opcode));
 	break;
     }
   }
@@ -1492,7 +1499,7 @@
 
 	default:
 	  opcode = code_base[bci];
-	  fatal1("Undefined opcode %d\n", opcode);
+	  fatal("Undefined opcode %d\n", opcode);
 	  break;
       }
     }
@@ -1725,7 +1732,7 @@
       case opc_putstatic:
       case opc_getfield:
       case opc_putfield: {
-	int index = GET_JAVA_U2(code_base+bci+1);
+	int index = GET_NATIVE_U2(code_base+bci+1);
 	constantPoolOop pool = jinfo->method->constants();
 	symbolOop sig = pool->signature_ref_at(index);
 	jbyte *base = sig->base();
@@ -1753,7 +1760,7 @@
       case opc_invokevirtual:
       case opc_invokespecial:
       case opc_invokestatic: {
-	int index = GET_JAVA_U2(code_base+bci+1);
+	int index = GET_NATIVE_U2(code_base+bci+1);
 	constantPoolOop pool = jinfo->method->constants();
 	//symbolOop name = pool->name_ref_at(index);
 	symbolOop sig = pool->signature_ref_at(index);
@@ -1791,13 +1798,13 @@
 	  else if (opcode == opc_lstore || opcode == opc_dstore)
 	    stackdepth -= 2;
 	  else if (opcode != opc_ret)
-	    fatal1("Undefined wide opcode %d\n", opcode);
+	    fatal(err_msg("Undefined wide opcode %d\n", opcode));
 	}
 	break;
 
       default:
 	opcode = code_base[bci];
-	fatal1("Undefined opcode %d\n", opcode);
+	fatal(err_msg("Undefined opcode %d\n", opcode));
 	break;
     }
   }
@@ -4365,6 +4372,7 @@
 
   mov_imm(jinfo->codebuf, ARM_LR, 0);
   str_imm(jinfo->codebuf, ARM_LR, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+  str_imm(jinfo->codebuf, ARM_LR, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
   ldr_imm(jinfo->codebuf, Rstack, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
   ldr_imm(jinfo->codebuf, ARM_LR, Rstack, 0, 1, 0);
 
@@ -4383,6 +4391,12 @@
   str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
   Thumb2_Debug(jinfo, H_DEBUG_METHODEXIT);
 //  enter_leave(jinfo->codebuf, 0);
+
+  // deoptimized_frames = 0
+  // FIXME: This should be done in the slow entry, but only three
+  // words are allocated there for the instructions.
+  mov_imm(jinfo->codebuf, ARM_R0, 0);
+
   ldm(jinfo->codebuf, C_REGSET + (1<<ARM_PC), ARM_SP, POP_FD, 1);
 }
 
@@ -4655,8 +4669,13 @@
 
   str_imm(jinfo->codebuf, Ristate, Ristate, ISTATE_MONITOR_BASE, 1, 0);
 
+  mov_imm(jinfo->codebuf, ARM_R1, 0);   // set last SP to zero before
+                                        // setting FP
+  str_imm(jinfo->codebuf, ARM_R1, ARM_R2, THREAD_LAST_JAVA_SP, 1, 0);
   add_imm(jinfo->codebuf, ARM_R3, Ristate, ISTATE_NEXT_FRAME);
   str_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_TOP_ZERO_FRAME, 1, 0);
+  str_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_LAST_JAVA_FP, 1, 0);
+  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_JAVA_SP, 1, 0);
   str_imm(jinfo->codebuf, ARM_R3, ARM_R2, THREAD_LAST_JAVA_SP, 1, 0);
 
   ldr_imm(jinfo->codebuf, ARM_R3, ARM_IP, CONSTANTPOOL_CACHE, 1, 0);
@@ -4793,7 +4812,12 @@
     }
 
     len = Bytecodes::length_for((Bytecodes::Code)opcode);
-    if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+    if (len <= 0) {
+      Bytecodes::Code code = Bytecodes::code_at(NULL, (address)(code_base+bci));
+      len = (Bytecodes::special_length_at
+	     (code,
+	      (address)(code_base+bci), (address)(code_base+code_size)));
+    }
 
     if (IS_DEAD(stackinfo) || IS_ZOMBIE(stackinfo)) {
       unsigned zlen = 0;
@@ -4820,7 +4844,12 @@
 	}
 
 	len = Bytecodes::length_for((Bytecodes::Code)opcode);
-	if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+	if (len <= 0) {
+	  Bytecodes::Code code = Bytecodes::code_at(NULL, (address)(code_base+bci));
+	  len = (Bytecodes::special_length_at
+		 (code,
+		  (address)(code_base+bci), (address)(code_base+code_size)));
+	}
 
       } while (1);
 #ifdef T2EE_PRINT_DISASS
@@ -4853,7 +4882,12 @@
 	}
 
 	len = Bytecodes::length_for((Bytecodes::Code)opcode);
-	if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+	if (len <= 0) {
+	  Bytecodes::Code code = Bytecodes::code_at(NULL, (address)(code_base+bci));
+	  len = (Bytecodes::special_length_at
+		 (code,
+		  (address)(code_base+bci), (address)(code_base+code_size)));
+	}
 
       } while (1);
 #ifdef T2EE_PRINT_DISASS
@@ -5524,7 +5558,7 @@
 
         cache = cp->entry_at(index);
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-	  int java_index = GET_JAVA_U2(code_base+bci+1);
+ 	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
 	  symbolOop sig = pool->signature_ref_at(java_index);
 	  jbyte *base = sig->base();
@@ -5587,7 +5621,7 @@
 
         cache = cp->entry_at(index);
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
 	  symbolOop sig = pool->signature_ref_at(java_index);
 	  jbyte *base = sig->base();
@@ -5645,7 +5679,7 @@
 
         cache = cp->entry_at(index);
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
 	  symbolOop sig = pool->signature_ref_at(java_index);
 	  jbyte *base = sig->base();
@@ -5703,7 +5737,7 @@
 
         cache = cp->entry_at(index);
         if (!cache->is_resolved((Bytecodes::Code)opcode)) {
-	  int java_index = GET_JAVA_U2(code_base+bci+1);
+	  int java_index = GET_NATIVE_U2(code_base+bci+1);
 	  constantPoolOop pool = jinfo->method->constants();
 	  symbolOop sig = pool->signature_ref_at(java_index);
 	  jbyte *base = sig->base();
@@ -5833,6 +5867,7 @@
 	if (opcode == opc_invokespecial)
 	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R3, 0, 1, 0); // Null pointer check - cbz better?
 	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
 	ldr_imm(jinfo->codebuf, ARM_R1, ARM_R0, METHOD_FROM_INTERPRETED, 1, 0);
   str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_BCP, 1, 0);
 	str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
@@ -5854,11 +5889,15 @@
 	ldr_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_STACK_LIMIT, 1, 0);
 	JASSERT(!(bc_stackinfo[bci+len] & BC_COMPILED), "code already compiled for this bytecode?");
 	Thumb2_invoke_restore(jinfo, bc_stackinfo[bci+len] & ~BC_FLAGS_MASK);
+	mov_imm(jinfo->codebuf, ARM_R0, 0);   // set last SP to zero
+					      // before setting FP
+	str_imm(jinfo->codebuf, ARM_R0, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
 	ldr_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_TOP_ZERO_FRAME, 1, 0);
 	add_imm(jinfo->codebuf, ARM_R2, ARM_R2, 4);
 	ldr_imm(jinfo->codebuf, ARM_R3, Rthread, THREAD_PENDING_EXC, 1, 0);
 	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_JAVA_SP, 1, 0);
-	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
 	cmp_imm(jinfo->codebuf, ARM_R3, 0);
 	it(jinfo->codebuf, COND_NE, IT_MASK_T);
 	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION_NO_REGS]);
@@ -5949,6 +5988,7 @@
   ldr_imm(jinfo->codebuf, ARM_R2, ARM_R2, METHOD_CONSTMETHOD, 1, 0);
 	  ldr_imm(jinfo->codebuf, ARM_R3, ARM_R3, 0, 1, 0); // Null pointer check - cbz better?
 	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
 	  ldr_imm(jinfo->codebuf, ARM_R1, ARM_R0, METHOD_FROM_INTERPRETED, 1, 0);
   add_imm(jinfo->codebuf, ARM_R2, ARM_R2, bci+CONSTMETHOD_CODEOFFSET);
 	  str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
@@ -5975,7 +6015,8 @@
 	  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, 4);
 	  ldr_imm(jinfo->codebuf, ARM_R3, Rthread, THREAD_PENDING_EXC, 1, 0);
 	  str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_JAVA_SP, 1, 0);
-	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
 	cmp_imm(jinfo->codebuf, ARM_R3, 0);
 	it(jinfo->codebuf, COND_NE, IT_MASK_T);
 	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION_NO_REGS]);
@@ -5989,6 +6030,7 @@
 	  ldr_imm(jinfo->codebuf, ARM_R0, ARM_R3, INSTANCEKLASS_VTABLE_OFFSET + cache->f2() * 4, 1, 0);
   add_imm(jinfo->codebuf, ARM_R2, ARM_R2, bci+CONSTMETHOD_CODEOFFSET);
 	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
 	  ldr_imm(jinfo->codebuf, ARM_R1, ARM_R0, METHOD_FROM_INTERPRETED, 1, 0);
   str_imm(jinfo->codebuf, ARM_R2, Ristate, ISTATE_BCP, 1, 0);
 	  str_imm(jinfo->codebuf, Rstack, Rthread, THREAD_JAVA_SP, 1, 0);
@@ -6014,7 +6056,8 @@
 	  add_imm(jinfo->codebuf, ARM_R2, ARM_R2, 4);
 	  ldr_imm(jinfo->codebuf, ARM_R3, Rthread, THREAD_PENDING_EXC, 1, 0);
 	  str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_JAVA_SP, 1, 0);
-	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R1, Rthread, THREAD_LAST_JAVA_FP, 1, 0);
+	  str_imm(jinfo->codebuf, ARM_R2, Rthread, THREAD_LAST_JAVA_SP, 1, 0);
 	cmp_imm(jinfo->codebuf, ARM_R3, 0);
 	it(jinfo->codebuf, COND_NE, IT_MASK_T);
 	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION_NO_REGS]);
@@ -6478,7 +6521,7 @@
 	    Thumb2_Store(jinfo, local, stackdepth);
 	  else if (opcode == opc_lstore || opcode == opc_dstore)
 	    Thumb2_StoreX2(jinfo, local, stackdepth);
-	  else fatal1("Undefined wide opcode %d\n", opcode);
+	  else fatal(err_msg("Undefined wide opcode %d\n", opcode));
 	}
 	break;
       }
@@ -6611,7 +6654,12 @@
       continue;
     } else {
       int len = Bytecodes::length_for((Bytecodes::Code)opcode);
-      if (len <= 0) len = Bytecodes::special_length_at((address)(code_base+bci), (address)(code_base+code_size));
+      if (len <= 0) {
+	Bytecodes::Code code = Bytecodes::code_at(NULL, (address)(code_base+bci));
+	len = (Bytecodes::special_length_at
+	       (code,
+		(address)(code_base+bci), (address)(code_base+code_size)));
+      }
       bci += len;
     }
   }
@@ -7141,6 +7189,9 @@
 #if 1
   memcpy(cb->hp, Thumb2_stubs, STUBS_SIZE);
 
+  // fprintf(stderr, "Thumb2_stubs offset: 0x%x\n",
+  // 	  (char*)(cb->hp) - (char*)Thumb2_stubs);
+
   handlers[H_IDIV] = (unsigned)(cb->hp + IDIV_STUB);
   handlers[H_IREM] = (unsigned)(cb->hp + IREM_STUB);
   handlers[H_INVOKEINTERFACE] = (unsigned)(cb->hp + INVOKEINTERFACE_STUB);
@@ -7201,12 +7252,30 @@
   mov_reg(&codebuf, ARM_PC, ARM_R3);
 
   handlers[H_DREM] = out_pos(&codebuf);
+  stm(&codebuf, (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
   mov_imm(&codebuf, ARM_IP, (u32)fmod);
-  mov_reg(&codebuf, ARM_PC, ARM_IP);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_d_toVFP(&codebuf, VFP_D0, ARM_R0, ARM_R1);
+  vmov_reg_d_toVFP(&codebuf, VFP_D1, ARM_R2, ARM_R3);
+#endif
+  blx_reg(&codebuf, ARM_IP);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_d_toARM(&codebuf, ARM_R0, ARM_R1, VFP_D0);
+#endif
+  ldm(&codebuf, (1<<ARM_PC), ARM_SP, POP_FD, 1);
 
   handlers[H_FREM] = out_pos(&codebuf);
+  stm(&codebuf, (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
   mov_imm(&codebuf, ARM_R3, (u32)fmodf);
-  mov_reg(&codebuf, ARM_PC, ARM_R3);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_s_toVFP(&codebuf, VFP_S0, ARM_R0);
+  vmov_reg_s_toVFP(&codebuf, VFP_S1, ARM_R1);
+#endif
+  blx_reg(&codebuf, ARM_R3);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_s_toARM(&codebuf, ARM_R0, VFP_S0);
+#endif
+  ldm(&codebuf, (1<<ARM_PC), ARM_SP, POP_FD, 1);
 
   handlers[H_I2F] = out_pos(&codebuf);
   mov_imm(&codebuf, ARM_IP, (u32)__aeabi_i2f);
@@ -7226,10 +7295,16 @@
 
   handlers[H_F2I] = out_pos(&codebuf);
   mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3f2iEf);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_s_toVFP(&codebuf, VFP_S0, ARM_R0);
+#endif
   mov_reg(&codebuf, ARM_PC, ARM_IP);
 
   handlers[H_F2L] = out_pos(&codebuf);
   mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3f2lEf);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_s_toVFP(&codebuf, VFP_S0, ARM_R0);
+#endif
   mov_reg(&codebuf, ARM_PC, ARM_IP);
 
   handlers[H_F2D] = out_pos(&codebuf);
@@ -7238,10 +7313,16 @@
 
   handlers[H_D2I] = out_pos(&codebuf);
   mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3d2iEd);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_d_toVFP(&codebuf, VFP_S0, ARM_R0, ARM_R1);
+#endif
   mov_reg(&codebuf, ARM_PC, ARM_IP);
 
   handlers[H_D2L] = out_pos(&codebuf);
   mov_imm(&codebuf, ARM_IP, (u32)_ZN13SharedRuntime3d2lEd);
+#ifdef __ARM_PCS_VFP
+  vmov_reg_d_toVFP(&codebuf, VFP_S0, ARM_R0, ARM_R1);
+#endif
   mov_reg(&codebuf, ARM_PC, ARM_IP);
 
   handlers[H_D2F] = out_pos(&codebuf);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/arm-debug.patch	Thu Oct 27 13:54:50 2011 +0100
@@ -0,0 +1,41 @@
+--- openjdk/hotspot/src/share/vm/utilities/vmError.cpp	2011-09-16 19:04:00.000000000 +0100
++++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp	2011-09-19 11:40:10.000000000 +0100
+@@ -238,6 +238,18 @@
+   return buf;
+ }
+ 
++extern "C" void ps() {
++  fdStream out(defaultStream::output_fd());
++  JavaThread* thread = JavaThread::active();
++  char *buf = new char[1024*1024];
++  VMError err(thread, "", 0, "", "");
++
++  err.print_stack_trace(&out, thread, buf, 1024*1024, true);
++
++  delete[] buf;
++}
++
++
+ void VMError::print_stack_trace(outputStream* st, JavaThread* jt,
+                                 char* buf, int buflen, bool verbose) {
+ #ifdef ZERO
+--- openjdk/hotspot/src/share/vm/utilities/vmError.hpp	2011-07-05 14:31:05.000000000 -0400
++++ openjdk/hotspot/src/share/vm/utilities/vmError.hpp	2011-09-19 13:38:35.000000000 -0400
+@@ -30,6 +30,8 @@
+ 
+ class VM_ReportJavaOutOfMemory;
+ 
++extern "C" void ps();
++
+ class VMError : public StackObj {
+   friend class VM_ReportJavaOutOfMemory;
+ 
+@@ -89,6 +91,8 @@
+   const char* detail_msg() const { return _detail_msg; }
+   bool should_report_bug(unsigned int id) { return id != oom_error; }
+ 
++  friend void ps();
++
+ public:
+   // Constructor for crashes
+   VMError(Thread* thread, unsigned int sig, address pc, void* siginfo,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/arm.patch	Thu Oct 27 13:54:50 2011 +0100
@@ -0,0 +1,232 @@
+diff -Nru openjdk.orig/hotspot/make/linux/makefiles/zeroshark.make openjdk/hotspot/make/linux/makefiles/zeroshark.make
+--- openjdk.orig/hotspot/make/linux/makefiles/zeroshark.make	2010-05-28 11:09:25.000000000 +0100
++++ openjdk/hotspot/make/linux/makefiles/zeroshark.make	2010-06-17 17:28:03.000000000 +0100
+@@ -25,6 +25,41 @@
+ 
+ # Setup common to Zero (non-Shark) and Shark versions of VM
+ 
++ifeq ($(ZERO_LIBARCH),arm)
++
++Obj_Files += asm_helper.o
++Obj_Files += cppInterpreter_arm.o
++Obj_Files += thumb2.o
++
++CFLAGS += -DHOTSPOT_ASM
++
++%.o: %.S
++	@echo Assembling $<
++	$(QUIETLY) $(REMOVE_TARGET)
++	$(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
++
++cppInterpreter_arm.o:	offsets_arm.s bytecodes_arm.s
++thumb2.o:		offsets_arm.s
++
++offsets_arm.s:	mkoffsets
++	@echo Generating assembler offsets
++	./mkoffsets > $@
++
++bytecodes_arm.s: bytecodes_arm.def mkbc
++	@echo Generatine ARM assembler bytecode sequences
++	$(CC_COMPILE) -E -x c++ - < $< | ./mkbc - $@ $(COMPILE_DONE)
++
++mkbc:	$(GAMMADIR)/tools/mkbc.c
++	@echo Compiling mkbc tool
++	$(CC_COMPILE) -o $@ $< $(COMPILE_DONE)
++
++mkoffsets:	asm_helper.cpp
++	@echo Compiling offset generator
++	$(QUIETLY) $(REMOVE_TARGET)
++	$(CC_COMPILE) -DSTATIC_OFFSETS -o $@ $< $(COMPILE_DONE)
++
++endif
++
+ # The copied fdlibm routines in sharedRuntimeTrig.o must not be optimized
+ OPT_CFLAGS/sharedRuntimeTrig.o = $(OPT_CFLAGS/NOOPT)
+ # The copied fdlibm routines in sharedRuntimeTrans.o must not be optimized
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp openjdk/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp	2010-05-28 11:10:30.000000000 +0100
++++ openjdk/hotspot/src/cpu/zero/vm/bytecodes_zero.cpp	2010-06-17 17:29:30.000000000 +0100
+@@ -1,6 +1,7 @@
+ /*
+  * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+  * Copyright 2007 Red Hat, Inc.
++ * Copyright 2009 Edward Nevill
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -27,5 +28,54 @@
+ #include "incls/_bytecodes_zero.cpp.incl"
+ 
+ void Bytecodes::pd_initialize() {
+-  // No zero specific initialization
++#ifdef HOTSPOT_ASM
++  // Because iaccess_N can trap, we must say aload_N can trap, otherwise
++  // we get an assertion failure
++  def(_aload_1, "aload_1", "b", NULL, T_OBJECT ,  1, true);
++  def(_aload_2, "aload_2", "b", NULL, T_OBJECT ,  1, true);
++  def(_aload_3, "aload_3", "b", NULL, T_OBJECT ,  1, true);
++
++  def(_iaccess_0, "_iaccess_0", "b_jj", NULL, T_INT,  1, true, _aload_0);
++  def(_iaccess_1, "_iaccess_1", "b_jj", NULL, T_INT,  1, true, _aload_1);
++  def(_iaccess_2, "_iaccess_2", "b_jj", NULL, T_INT,  1, true, _aload_2);
++  def(_iaccess_3, "_iaccess_3", "b_jj", NULL, T_INT,  1, true, _aload_3);
++
++  def(_invokeresolved,   "invokeresolved",   "bjj", NULL, T_ILLEGAL, -1, true, _invokevirtual);
++  def(_invokespecialresolved, "invokespecialresolved", "bjj", NULL, T_ILLEGAL, -1, true, _invokespecial);
++  def(_invokestaticresolved,  "invokestaticresolved",  "bjj", NULL, T_ILLEGAL,  0, true, _invokestatic);
++
++  def(_dmac,            "dmac",      "b_",  NULL, T_DOUBLE, -16, false, _dmul);
++
++  def(_iload_iload,      "iload_iload",      "bi_i",NULL, T_INT, 2, false, _iload);
++  def(_iload_iload_N,    "iload_iload_N",    "bi_", NULL, T_INT, 2, false, _iload);
++
++  def(_iload_0_iconst_N, "iload_0_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_0);
++  def(_iload_1_iconst_N, "iload_1_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_1);
++  def(_iload_2_iconst_N, "iload_2_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_2);
++  def(_iload_3_iconst_N, "iload_3_iconst_N", "b_",  NULL, T_INT, 2, false, _iload_3);
++  def(_iload_iconst_N,   "iload_iconst_N",   "bi_", NULL, T_INT, 2, false, _iload);
++
++  def(_iadd_istore_N,    "iadd_istore_N",    "b_",  NULL, T_VOID, -2, false, _iadd);
++  def(_isub_istore_N,    "isub_istore_N",    "b_",  NULL, T_VOID, -2, false, _isub);
++  def(_iand_istore_N,    "iand_istore_N",    "b_",  NULL, T_VOID, -2, false, _iand);
++  def(_ior_istore_N,     "ior_istore_N",     "b_",  NULL, T_VOID, -2, false, _ior);
++  def(_ixor_istore_N,    "ixor_istore_N",    "b_",  NULL, T_VOID, -2, false, _ixor);
++
++  def(_iadd_u4store,     "iadd_u4store",     "b_i", NULL, T_VOID, -2, false, _iadd);
++  def(_isub_u4store,     "isub_u4store",     "b_i", NULL, T_VOID, -2, false, _isub);
++  def(_iand_u4store,     "iand_u4store",     "b_i", NULL, T_VOID, -2, false, _iand);
++  def(_ior_u4store,      "ior_u4store",      "b_i", NULL, T_VOID, -2, false, _ior);
++  def(_ixor_u4store,     "ixor_u4store",     "b_i", NULL, T_VOID, -2, false, _ixor);
++
++  def(_iload_0_iload,    "iload_0_iload",    "b_i", NULL, T_INT, 2, false, _iload_0);
++  def(_iload_1_iload,    "iload_1_iload",    "b_i", NULL, T_INT, 2, false, _iload_1);
++  def(_iload_2_iload,    "iload_2_iload",    "b_i", NULL, T_INT, 2, false, _iload_2);
++  def(_iload_3_iload,    "iload_3_iload",    "b_i", NULL, T_INT, 2, false, _iload_3);
++
++  def(_iload_0_iload_N,  "iload_0_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_0);
++  def(_iload_1_iload_N,  "iload_1_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_1);
++  def(_iload_2_iload_N,  "iload_2_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_2);
++  def(_iload_3_iload_N,  "iload_3_iload_N",  "b_",  NULL, T_INT, 2, false, _iload_3);
++
++#endif // HOTSPOT_ASM
+ }
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp openjdk/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	2010-06-16 14:11:07.000000000 +0100
++++ openjdk/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	2010-06-17 17:30:02.000000000 +0100
+@@ -724,10 +724,21 @@
+   return generate_entry((address) CppInterpreter::normal_entry);
+ }
+ 
++#ifdef HOTSPOT_ASM
++extern "C" address asm_generate_method_entry(
++  AbstractInterpreter::MethodKind kind);
++#endif // HOTSPOT_ASM
++
+ address AbstractInterpreterGenerator::generate_method_entry(
+     AbstractInterpreter::MethodKind kind) {
+   address entry_point = NULL;
+ 
++#ifdef HOTSPOT_ASM
++    address asm_entry = asm_generate_method_entry(kind);
++    if (asm_entry)
++      return ((InterpreterGenerator*) this)->generate_entry(asm_entry);
++#endif // HOTSPOT_ASM
++
+   switch (kind) {
+   case Interpreter::zerolocals:
+   case Interpreter::zerolocals_synchronized:
+diff -Nru openjdk.orig/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp openjdk/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
+--- openjdk.orig/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	2010-05-28 11:11:05.000000000 +0100
++++ openjdk/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	2010-06-17 17:27:35.000000000 +0100
+@@ -82,6 +82,10 @@
+   ShouldNotCallThis();
+ }
+ 
++#ifdef HOTSPOT_ASM
++extern "C" int asm_check_null_ptr(ucontext_t *uc);
++#endif // HOTSPOT_ASM
++
+ extern "C" int
+ JVM_handle_linux_signal(int sig,
+                         siginfo_t* info,
+@@ -89,6 +93,12 @@
+                         int abort_if_unrecognized) {
+   ucontext_t* uc = (ucontext_t*) ucVoid;
+ 
++#ifdef HOTSPOT_ASM
++  if (sig == SIGSEGV) {
++        if (asm_check_null_ptr(uc)) return 1;
++  }
++#endif // HOTSPOT_ASM
++
+   Thread* t = ThreadLocalStorage::get_thread_slow();
+ 
+   SignalHandlerMark shm(t);
+diff -Nru openjdk.orig/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp openjdk/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp
+--- openjdk.orig/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp	2011-01-25 22:57:24.000000000 +0000
++++ openjdk/hotspot/src/cpu/zero/vm/bytecodes_zero.hpp	2011-01-28 01:46:18.769782690 +0000
+@@ -1,6 +1,7 @@
+ /*
+  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+  * Copyright 2009 Red Hat, Inc.
++ * Copyright 2009 Edward Nevill
+  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+  *
+  * This code is free software; you can redistribute it and/or modify it
+@@ -26,6 +27,44 @@
+ #ifndef CPU_ZERO_VM_BYTECODES_ZERO_HPP
+ #define CPU_ZERO_VM_BYTECODES_ZERO_HPP
+ 
+-// This file is intentionally empty
++#ifdef HOTSPOT_ASM
++#define _iaccess_0      ((Bytecodes::Code)0xdb)
++#define _iaccess_1      ((Bytecodes::Code)0xdc)
++#define _iaccess_2      ((Bytecodes::Code)0xdd)
++#define _iaccess_3      ((Bytecodes::Code)0xde)
++
++#define _invokeresolved         ((Bytecodes::Code)0xdf)
++#define _invokespecialresolved  ((Bytecodes::Code)0xe0)
++#define _invokestaticresolved   ((Bytecodes::Code)0xe1)
++
++#define _iload_iload    ((Bytecodes::Code)0xe3)
++#define _iload_iload_N  ((Bytecodes::Code)0xe4)
++
++#define _dmac           ((Bytecodes::Code)0xe8)
++
++      _iload_0_iconst_N   , // 233 0xe9
++      _iload_1_iconst_N   , // 234 0xea
++      _iload_2_iconst_N   , // 235 0xeb
++      _iload_3_iconst_N   , // 236 0xec
++      _iload_iconst_N     , // 237 0xed
++      _iadd_istore_N      , // 238 0xee
++      _isub_istore_N      , // 239 0xef
++      _iand_istore_N      , // 240 0xf0
++      _ior_istore_N       , // 241 0xf1
++      _ixor_istore_N      , // 242 0xf2
++      _iadd_u4store       , // 243 0xf3
++      _isub_u4store       , // 244 0xf4
++      _iand_u4store       , // 245 0xf5
++      _ior_u4store        , // 246 0xf6
++      _ixor_u4store       , // 247 0xf7
++      _iload_0_iload      , // 248 0xf8
++      _iload_1_iload      , // 249 0xf9
++      _iload_2_iload      , // 250 0xfa
++      _iload_3_iload      , // 251 0xfb
++      _iload_0_iload_N    , // 252 0xfc
++      _iload_1_iload_N    , // 253 0xfd
++      _iload_2_iload_N    , // 254 0xfe
++      _iload_3_iload_N    , // 255 0xff
++#endif // HOTSPOT_ASM
+ 
+ #endif // CPU_ZERO_VM_BYTECODES_ZERO_HPP
+--- openjdk/hotspot/make/linux/makefiles/vm.make	2011-09-16 14:22:51.000000000 +0100
++++ openjdk/hotspot/make/linux/makefiles/vm.make	2011-09-16 16:04:50.000000000 +0100
+@@ -183,7 +183,7 @@
+ # Locate all source files in the given directory, excluding files in Src_Files_EXCLUDE.
+ define findsrc
+ 	$(notdir $(shell find $(1)/. ! -name . -prune \
+-		-a \( -name \*.c -o -name \*.cpp -o -name \*.s \) \
++		-a \( -name \*.c -o -name \*.cpp -o -name \*.s -o -name \*.S \) \
+ 		-a ! \( -name DUMMY $(addprefix -o -name ,$(Src_Files_EXCLUDE)) \)))
+ endef
+