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