RTC Thumb2 JIT methods containing exc handlers

ed at camswl.com ed at camswl.com
Thu Jan 28 09:15:20 PST 2010


Hi folks,

The following patch allows the Thumb2 JIT to JIT methods containing exception
handlers which were previously not compiled.

OK to commit?

Regards,
Ed.

--- CUT HERE --------------------------------------------------------------------
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S new/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	2010-01-28 17:01:20.000000000 +0000
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/cppInterpreter_arm.S	2010-01-28 17:06:02.000000000 +0000
@@ -6151,17 +6151,24 @@
 dc_18:
 	.word     0x38e38e39
 
+#define TBIT 1
+
 	.global	Thumb2_DivZero_Handler
 Thumb2_DivZero_Handler:
+#ifdef THUMB2EE
 	adrl	r0, idiv_clz_ret
 	cmp	r0, lr
 	addne	r0, r0, #irem_clz_ret - idiv_clz_ret
 	cmpne	r0, lr
 	beq	divide_by_zero_exception
-	ldr	r0, [istate, #ISTATE_METHOD]
-        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	bic	r0, lr, #TBIT
+	ldr	r1, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r1, #METHOD_CONSTMETHOD]
 	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	Thumb2_lr_to_bci
+	add	jpc, jpc, r0
 	bl	load_dispatch
+#endif // THUMB2EE
 	b	divide_by_zero_exception
 
 #ifdef THUMB2EE
@@ -6171,16 +6178,23 @@
 	.global	Thumb2_NullPtr_Handler
 	.global Thumb2_Stack_Overflow
 Thumb2_ArrayBounds_Handler:
-	ldr	r0, [istate, #ISTATE_METHOD]
-        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	bic	r0, lr, #TBIT
+	ldr	r1, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r1, #METHOD_CONSTMETHOD]
 	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	Thumb2_lr_to_bci
+	add	jpc, jpc, r0
 	bl	load_dispatch
 	mov	r0, #VMSYMBOLS_ArrayIndexOutOfBounds
 	b	raise_exception
+Thumb2_NullPtr_Handler:
 Thumb2_Handle_Exception:
-	ldr	r0, [istate, #ISTATE_METHOD]
-        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
+	bic	r0, lr, #TBIT
+	ldr	r1, [istate, #ISTATE_METHOD]
+        ldr     jpc, [r1, #METHOD_CONSTMETHOD]
 	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
+	bl	Thumb2_lr_to_bci
+	add	jpc, jpc, r0
 	bl	load_dispatch
 	b	handle_exception
 Thumb2_Stack_Overflow:
@@ -6198,13 +6212,6 @@
 	CACHE_LOCALS
 	DISPATCH	0
 
-Thumb2_NullPtr_Handler:
-	ldr	r0, [istate, #ISTATE_METHOD]
-        ldr     jpc, [r0, #METHOD_CONSTMETHOD]
-	add	jpc, jpc, #CONSTMETHOD_CODEOFFSET
-	bl	load_dispatch
-	b	null_ptr_exception
-
 	.global	Thumb2_Clear_Cache
 Thumb2_Clear_Cache:
 	stmdb	sp!, {r7}
diff -ruNE old/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp new/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp
--- old/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp	2010-01-28 17:01:20.000000000 +0000
+++ new/icedtea6/ports/hotspot/src/cpu/zero/vm/thumb2.cpp	2010-01-28 17:09:00.000000000 +0000
@@ -546,17 +546,18 @@
     // 		bl	fast_entry
     // 		pop	{r4, r5, r6, r7, r9, r10, r11, pc}
     unsigned slow_entry[3];
-    // osr_tablep:				@ pointer to the osr table
-    // 		.word	osr_table
-    unsigned *osr_table;
+    unsigned *osr_table;			// pointer to the osr table
+    unsigned *exception_table;
     Compiled_Method *next;
     // OSR Entry point:
     // 	R0 = entry point within compiled method
-    // 	R1 = locals
+    // 	R1 = locals - 4000 * 4
     // 	R2 = thread
+    // 	R3 = locals - 31 * 4
     // osr_entry:
     // 		@ Load each local into it register allocated register
-    // 		ldr	<reg>, [R1, #-<local> * 4]
+    // 		ldr	<reg>, [R1, #(4000-<local>) * 4]
+    //    or	ldr	<reg>, [R3, #(31-<local>) * 4]
     // 		...
     // 		mov	Rthread, R2
     // 		bx	R0
@@ -4484,6 +4485,7 @@
   out_32(jinfo->codebuf, 0);
 
   out_32(jinfo->codebuf, 0);	// pointer to osr table
+  out_32(jinfo->codebuf, 0);	// Space for exception_table pointer
   out_32(jinfo->codebuf, 0);	// next compiled method
 
   // OSR entry point
@@ -4524,7 +4526,8 @@
   bl(jinfo->codebuf, out_pos(jinfo->codebuf) + CODE_ALIGN - 4);
   ldm(jinfo->codebuf, I_REGSET + (1<<ARM_PC), ARM_SP, POP_FD, 1);
 
-  out_32(jinfo->codebuf, 0);	// Space for osr_table point
+  out_32(jinfo->codebuf, 0);	// Space for osr_table pointer
+  out_32(jinfo->codebuf, 0);	// Space for exception_table pointer
   out_32(jinfo->codebuf, 0);	// Pointer to next method
 
   // OSR entry point == Slow entry + 16 - caller save
@@ -4577,7 +4580,7 @@
 
     for (i = 0; i < extra_locals; i++) {
       unsigned linfo = locals_info[parms+i];
-      if (linfo & (1<< LOCAL_REF))
+      if (linfo & (1<< LOCAL_REF) || ((linfo >> LOCAL_INT) & 0x1f) == 0)
 	str_imm(jinfo->codebuf, ARM_R1, Rstack, (extra_locals-1 - i) * 4, 1, 0);
     }
   }
@@ -4777,6 +4780,8 @@
 	if (stackinfo & BC_BRANCH_TARGET) break;
 	if (!(IS_DEAD(stackinfo) || IS_ZOMBIE(stackinfo))) break;
 
+	bc_stackinfo[bci] = (stackinfo & BC_FLAGS_MASK) | (codebuf->idx * 2);
+
 	if (opcode > OPC_LAST_JAVA_OP) {
 	  if (Bytecodes::is_defined((Bytecodes::Code)opcode))
 	    opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
@@ -6461,17 +6466,75 @@
   }
 }
 
-void Thumb2_tablegen(Thumb2_Info *jinfo)
+#define BEG_BCI_OFFSET		0
+#define END_BCI_OFFSET		1
+#define HANDLER_BCI_OFFSET	2
+#define KLASS_INDEX_OFFSET	3
+#define ENTRY_SIZE		4
+
+extern "C" int Thumb2_lr_to_bci(unsigned lr, methodOop method)
+{
+  Compiled_Method *cmethod = compiled_method_list;
+  typeArrayOop table = method->exception_table();
+  constantPoolOop pool = method->constants();
+  int length = table->length();
+
+  while (cmethod) {
+    unsigned *exception_table = cmethod->exception_table;
+    if (exception_table) {
+      unsigned code_base = (unsigned)cmethod;
+      if (code_base <= lr && lr <= (unsigned)exception_table) {
+	for (int i = 0; i < length; i += ENTRY_SIZE) {
+	  unsigned offsets = *exception_table++;
+	  unsigned exc_beg = code_base + ((offsets >> 16) << 1);
+	  unsigned exc_end = code_base + ((offsets & 0xffff) << 1);
+
+	  if (exc_beg <= lr && lr <= exc_end) {
+	    return table->int_at(i + BEG_BCI_OFFSET);
+	  }
+	}
+      }
+    }
+    cmethod = cmethod->next;
+  }
+  return 0;
+}
+
+void Thumb2_generate_exception_table(Compiled_Method *cmethod, Thumb2_Info *jinfo)
+{
+  methodOop method = jinfo->method;
+  typeArrayOop table = method->exception_table();
+  constantPoolOop pool = method->constants();
+  int length = table->length();
+  unsigned *bc_stackinfo = jinfo->bc_stackinfo;
+
+  cmethod->exception_table = (unsigned *)out_pos(jinfo->codebuf);
+  for (int i = 0; i < length; i += ENTRY_SIZE) {
+    int beg_bci = table->int_at(i + BEG_BCI_OFFSET);
+    int end_bci = table->int_at(i + END_BCI_OFFSET);
+    unsigned stackinfo;
+    unsigned beg_offset, end_offset;
+
+    stackinfo = bc_stackinfo[beg_bci];
+    beg_offset = (stackinfo & ~BC_FLAGS_MASK) >> 1;
+    stackinfo = bc_stackinfo[end_bci];
+    end_offset = (stackinfo & ~BC_FLAGS_MASK) >> 1;
+    JASSERT(beg_offset != 0 && end_offset >= beg_offset && end_offset < 65536, "oops");
+    out_32(jinfo->codebuf, (beg_offset << 16) | (end_offset));
+  }
+}
+
+void Thumb2_tablegen(Compiled_Method *cmethod, Thumb2_Info *jinfo)
 {
   unsigned code_size = jinfo->code_size;
   jubyte *code_base = jinfo->code_base;
   unsigned *bc_stackinfo = jinfo->bc_stackinfo;
   unsigned bci;
-  unsigned *count_pos = (unsigned *)out_pos(jinfo->codebuf);
   unsigned count = 0;
   unsigned i;
   CodeBuf *codebuf = jinfo->codebuf;
 
+  cmethod->osr_table = (unsigned *)out_pos(jinfo->codebuf);
   out_32(codebuf, 0);
   bc_stackinfo[0] |= BC_BACK_TARGET;
   for (bci = 0; bci < code_size;) {
@@ -6501,7 +6564,9 @@
       bci += len;
     }
   }
-  *count_pos = count;
+  *cmethod->osr_table = count;
+  if (jinfo->method->has_exception_handler())
+    Thumb2_generate_exception_table(cmethod, jinfo);
 }
 
 extern "C" void Thumb2_Clear_Cache(char *base, char *limit);
@@ -6705,8 +6770,7 @@
   //
   if (code_size > THUMB2_MAX_BYTECODE_SIZE ||
 		(method->max_locals() + method->max_stack()) >= 1000 ||
-		method->has_monitor_bytecodes() ||
-		method->has_exception_handler()) {
+		method->has_monitor_bytecodes()) {
         method->set_not_compilable();
 	return 0;
   }
@@ -6748,8 +6812,11 @@
 
 #ifdef T2EE_PRINT_COMPILATION
   if (t2ee_print_compilation) {
-    tty->print("Compiling (%d) ", compiled_methods);
-    tty->print_cr("%s", method->name_and_sig_as_C_string());
+    tty->print_cr("%d %c%c %s",
+	compiled_methods,
+	method->is_synchronized() ? 'S' : ' ',
+	method->has_exception_handler() ? 'E' : ' ',
+	method->name_and_sig_as_C_string());
   }
 #endif
 
@@ -6846,13 +6913,8 @@
 
   out_32(&codebuf_str, slow_entry);
 
-  if (!compiled_accessor) {
-    unsigned osr_entry_table = out_pos(jinfo_str.codebuf);
-
-    Thumb2_tablegen(&jinfo_str);
-
-    cmethod->osr_table = (unsigned *)osr_entry_table;
-  }
+  if (!compiled_accessor)
+    Thumb2_tablegen(cmethod, &jinfo_str);
 
   cb->hp += codebuf_str.idx * 2;
 
@@ -6968,6 +7030,7 @@
   Thumb2_CodeBuf *cb = thumb2_codebuf;
   if (!(CPUInfo & ARCH_THUMBEE)) return 0;
   if (IS_COMPILED(pc, cb)) {
+    regs[ARM_LR] = pc;
     regs[ARM_PC] = (unsigned)Thumb2_NullPtr_Handler;
     regs[ARM_CPSR] &= ~CPSR_THUMB_BIT;
     return 1;



More information about the distro-pkg-dev mailing list