ARM: Enable safepoints for JIT-compiled code

Andrew Haley aph at redhat.com
Tue Jan 10 06:31:43 PST 2012


I've found the bug that broke safepoints.  It turns out that safepoints
do not convert a PC address to a bytecode index, so you have to set the
bytecode pointer explicitly whenever at a safepoint.  I'm intend to apply
this to trunk and branch, given RM approval.

Andrew.


2012-01-09  Andrew Haley  <aph at redhat.com>

	* arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp (Thumb2_disass):
	Flush the output streams.
	(Thumb2_Safepoint): Add the bci as a new argument.  Pass it to
	the safepoint handler.
	(Thumb2_Branch): Pass the bci to Thumb2_Safepoint().
	(Thumb2_Goto): Likewise.
	(Thumb2_Return):  Add the bci as a new argument.  Pass it to
	Thumb2_Safepoint().
	Add braces for clarity.
	move call to Thumb2_Safepoint() to point before retval is popped.
	(Thumb2_codegen): Pass the bci to Thumb2_Return().
	(Thumb2_Initialize): Disassemble the codebuf we just created.

	* arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
	(method_entry_freq_count_overflow): Make sure self_link is set
	when re-entering JIT-compiled code.

comparing with ssh://icedtea.classpath.org/hg/icedtea6
searching for changes
changeset:   2769:57ae0e361acf
tag:         tip
user:        aph
date:        Mon Jan 09 13:34:27 2012 -0500
summary:     ARM: Enable safepoints for JIT-compiled code.

diff -r 4d6b4215b78f -r 57ae0e361acf arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
--- a/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Thu Dec 22 11:54:40 2011 -0500
+++ b/arm_port/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	Mon Jan 09 13:34:27 2012 -0500
@@ -3371,6 +3371,7 @@
 #ifdef THUMB2EE
 #define THUMB2_MAXLOCALS 1000
 call_thumb2:
+	str	istate, [istate, #ISTATE_SELF_LINK]
 	mov	ip, r1
 	sub	r1, locals, #THUMB2_MAXLOCALS * 4
 	ldr	r2, [istate, #ISTATE_THREAD]
diff -r 4d6b4215b78f -r 57ae0e361acf arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp
--- a/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Thu Dec 22 11:54:40 2011 -0500
+++ b/arm_port/hotspot/src/cpu/zero/vm/thumb2.cpp	Mon Jan 09 13:34:27 2012 -0500
@@ -791,6 +791,9 @@
   }
 #endif

+  fflush(stdout);
+  fflush(stderr);
+
   opcodes.init_disassemble_info(&info, stdout, (fprintf_ftype)fprintf);
   info.arch = bfd_arch_arm;
   opcodes.disassemble_init_for_target(&info);
@@ -950,6 +953,7 @@
       }
     }
   }
+  fflush(stdout);
 }
 #endif

@@ -4342,9 +4346,8 @@

 // Insert code to poll the SafepointSynchronize state and call
 // Helper_SafePoint.
-void Thumb2_Safepoint(Thumb2_Info *jinfo, int stackdepth)
-{
-#if 0  // Causes maysterious segfaults
+void Thumb2_Safepoint(Thumb2_Info *jinfo, int stackdepth, int bci)
+{
   Thumb2_Flush(jinfo);
   int r_tmp = Thumb2_Tmp(jinfo, 0);
   mov_imm(jinfo->codebuf, r_tmp, (u32)SafepointSynchronize::address_of_state());
@@ -4353,11 +4356,11 @@
   {
     unsigned loc = forward_16(jinfo->codebuf);
   Thumb2_save_locals(jinfo, stackdepth);
+    mov_imm(jinfo->codebuf, ARM_R1, bci+CONSTMETHOD_CODEOFFSET);
     bl(jinfo->codebuf, handlers[H_SAFEPOINT]);
   Thumb2_restore_locals(jinfo, stackdepth);
     bcc_patch(jinfo->codebuf, COND_NE, loc);
   }
-#endif
 }

 int Thumb2_Branch(Thumb2_Info *jinfo, unsigned bci, unsigned cond, int stackdepth)
@@ -4369,7 +4372,7 @@

     if (jinfo->bc_stackinfo[dest_taken] & BC_COMPILED) {
       loc = forward_16(jinfo->codebuf);
-      Thumb2_Safepoint(jinfo, stackdepth);
+      Thumb2_Safepoint(jinfo, stackdepth, bci);
       branch_uncond(jinfo->codebuf, jinfo->bc_stackinfo[dest_taken] & ~BC_FLAGS_MASK);
       bcc_patch(jinfo->codebuf, NEG_COND(cond), loc);
       return dest_not_taken;
@@ -4388,7 +4391,7 @@
     unsigned loc;

     if (jinfo->bc_stackinfo[dest_taken] & BC_COMPILED) {
-      Thumb2_Safepoint(jinfo, stackdepth);
+      Thumb2_Safepoint(jinfo, stackdepth, bci);
       branch_uncond(jinfo->codebuf, jinfo->bc_stackinfo[dest_taken] & ~BC_FLAGS_MASK);
       return dest_not_taken;
     }
@@ -4399,7 +4402,7 @@
     return -1;
 }

-void Thumb2_Return(Thumb2_Info *jinfo, unsigned opcode)
+void Thumb2_Return(Thumb2_Info *jinfo, unsigned opcode, int bci)
 {
   Reg r_lo, r;
   Thumb2_Stack *jstack = jinfo->jstack;
@@ -4467,6 +4470,8 @@
     cbz_patch(jinfo->codebuf, ARM_R3, loc_success2);
   }

+  Thumb2_Safepoint(jinfo, 0, bci);
+
   if (opcode != opc_return) {
     if (opcode == opc_lreturn || opcode == opc_dreturn) {
       Thumb2_Fill(jinfo, 2);
@@ -4490,8 +4495,9 @@
     if (opcode == opc_lreturn || opcode == opc_dreturn) {
       str_imm(jinfo->codebuf, r, Rstack, jinfo->method->max_locals() * sizeof(int), 1, 0);
       str_imm(jinfo->codebuf, r_lo, Rstack, jinfo->method->max_locals() * sizeof(int)-4, 1, 1);
-    } else
+    } else {
       str_imm(jinfo->codebuf, r, Rstack, jinfo->method->max_locals() * sizeof(int), 1, 1);
+    }
   }

 //  sub_imm(jinfo->codebuf, Ristate, ARM_LR, ISTATE_NEXT_FRAME);
@@ -4500,8 +4506,6 @@
   Thumb2_Debug(jinfo, H_DEBUG_METHODEXIT);
 //  enter_leave(jinfo->codebuf, 0);

-  Thumb2_Safepoint(jinfo, 0);
-
   // deoptimized_frames = 0
   // FIXME: This should be done in the slow entry, but only three
   // words are allocated there for the instructions.
@@ -6354,7 +6358,7 @@
       case opc_ireturn:
       case opc_freturn:
       case opc_areturn:
-	Thumb2_Return(jinfo, opcode);
+	Thumb2_Return(jinfo, opcode, bci);
 	if (!jinfo->compiled_return) jinfo->compiled_return = bci;
 	break;

@@ -6389,7 +6393,7 @@
 	it(jinfo->codebuf, COND_NE, IT_MASK_T);
 	bl(jinfo->codebuf, handlers[H_HANDLE_EXCEPTION]);
 	bcc_patch(jinfo->codebuf, COND_EQ, loc_eq);
-	Thumb2_Return(jinfo, opc_return);
+	Thumb2_Return(jinfo, opc_return, bci);
 	break;
       }

@@ -7742,11 +7746,20 @@
 // H_SAFEPOINT
   handlers[H_SAFEPOINT] = out_pos(&codebuf);
   stm(&codebuf, (1<<ARM_LR), ARM_SP, PUSH_FD, 1);
+
+  // Set up BytecodeInterpreter->_bcp for the GC
+  // bci+CONSTMETHOD_CODEOFFSET is passed in ARM_R1
+  ldr_imm(&codebuf, ARM_R0, Ristate, ISTATE_METHOD, 1, 0);
+  ldr_imm(&codebuf, ARM_R0, ARM_R0, METHOD_CONSTMETHOD, 1, 0);
+  add_reg(&codebuf, ARM_R0, ARM_R0, ARM_R1);
+  str_imm(&codebuf, ARM_R0, Ristate, ISTATE_BCP, 1, 0);
+
   mov_imm(&codebuf, ARM_IP, (u32)Helper_SafePoint);
   mov_reg(&codebuf, ARM_R0, Rthread);
   blx_reg(&codebuf, ARM_IP);
   ldm(&codebuf, (1<<ARM_LR), ARM_SP, POP_FD, 1);
   cmp_imm(&codebuf, ARM_R0, 0);
+
   // The sequence here is delicate.  We need to seet things up so that
   // it looks as though Thumb2_Handle_Exception_NoRegs was called
   // directly from a compiled method.
@@ -7759,6 +7772,29 @@
   cb->hp += codebuf.idx * 2;

   thumb2_codebuf = cb;
+
+#if 0 // Disassemble the codebuf we just created.  For debugging
+  Opcodes opcodes;
+  if (t2ee_print_disass) {
+    struct disassemble_info info;
+    info.arch = bfd_arch_arm;
+    opcodes.disassemble_init_for_target(&info);
+    opcodes.init_disassemble_info(&info, stdout, (fprintf_ftype)fprintf);
+    info.endian = BFD_ENDIAN_LITTLE;
+    info.endian_code = BFD_ENDIAN_LITTLE;
+    info.buffer = (bfd_byte *)codebuf.codebuf;
+    info.buffer_vma = (bfd_vma)codebuf.codebuf;
+    info.buffer_length = codebuf.idx * sizeof(short);
+    info.disassembler_options = (char *)"force-thumb";
+    int len;
+    for (unsigned int i = 0; i < codebuf.idx * sizeof(short); i += len) {
+      printf("0x%08x:\t", ((int)codebuf.codebuf)+i);
+      len = opcodes.print_insn_little_arm(((bfd_vma)codebuf.codebuf)+i, &info);
+      if (len == -1) len = 2;
+      putchar('\n');
+    }
+  }
+#endif
 }

 #endif // THUMB2EE




More information about the distro-pkg-dev mailing list