changeset 2945:a5d04cb60a5c

merge
author aph
date Wed, 11 Apr 2012 09:24:03 -0400
parents 0d46eb9c099f (diff) 26f5d8596931 (current diff)
children 5582e72f1897 39068668f2c1
files
diffstat 4 files changed, 228 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/zero/vm/asm_helper.cpp	Fri Mar 16 08:36:04 2012 -0400
+++ b/src/cpu/zero/vm/asm_helper.cpp	Wed Apr 11 09:24:03 2012 -0400
@@ -373,6 +373,11 @@
 	       err_msg(msg, opcode, name));
 }
 
+extern "C" int Helper_target_offset_in_bytes()
+{
+  return java_lang_invoke_CallSite::target_offset_in_bytes();
+}
+
 #endif // STATIC_OFFSETS
 
 #ifdef STATIC_OFFSETS
--- a/src/cpu/zero/vm/bytecodes_arm.def	Fri Mar 16 08:36:04 2012 -0400
+++ b/src/cpu/zero/vm/bytecodes_arm.def	Wed Apr 11 09:24:03 2012 -0400
@@ -219,6 +219,7 @@
 invokespecial        = 0xb7, 3
 invokestatic         = 0xb8, 3
 invokeinterface      = 0xb9, 0
+invokedynamic        = 0xba, 0
 new                  = 0xbb, 3
 newarray             = 0xbc, 2
 anewarray            = 0xbd, 3
@@ -269,6 +270,8 @@
 iload_iload	= 0xe3, 4
 iload_iload_N	= 0xe4, 3
 
+fast_aldc	= 0xe5, 2
+fast_aldc_w	= 0xe6, 3
 @return_register_finalizer = 0xe7, 1
 
 iload_0_iconst_N        = 0xe9, 2
--- a/src/cpu/zero/vm/cppInterpreter_arm.S	Fri Mar 16 08:36:04 2012 -0400
+++ b/src/cpu/zero/vm/cppInterpreter_arm.S	Wed Apr 11 09:24:03 2012 -0400
@@ -802,7 +802,7 @@
         .word   empty_entry                     // empty method (code: _return)
         .word   accessor_entry                  // accessor method (code: _aload_0, _getfield, _(a|i)return)
         .word   normal_entry                    // abstract method (throws an AbstractMethodException)
-        .word   vm_fatal_error                  // java.dyn.MethodHandles::invoke
+        .word   method_handle_entry             // java.lang.invoke.MethodHandles::invoke
         .word   normal_entry                    // implementation of java.lang.Math.sin   (x)
         .word   normal_entry                    // implementation of java.lang.Math.cos   (x)
         .word   normal_entry                    // implementation of java.lang.Math.tan   (x)
@@ -988,6 +988,7 @@
 			.word	.abortentry114, 1
 		FBC	.word	.abortentry117, 0
 			.word	.abortentry118, 0
+			.word	.abortentry119, 1
 	.word	0
 
 #endif
@@ -2746,6 +2747,9 @@
 	Opcode	fast_iload_N_iload_N
 #endif
 	Opcode	undefined
+	// Decache to get better diagnostic info
+	DECACHE_JPC
+	DECACHE_STACK
 	ldr	r2, [dispatch, #Bytecodes_name_Address-XXX]
 	ldrb	r3, [jpc, #0]	@ zero_extendqisi2
 	adrl	r0, bytecode_interpreter_str
@@ -2755,7 +2759,7 @@
 	adr	r2, unimplemented_opcode_msg
 	ldr	r1, =__LINE__
 	str	ip, [arm_sp, #-8]!
-	bl	Helper_report_fatal
+ 	bl	Helper_report_fatal
 	b	breakpoint
 	.ltorg
 unimplemented_opcode_msg:
@@ -3054,6 +3058,147 @@
 	ldr	tmp2, [r3, #INSTANCEKLASS_VTABLE_OFFSET]
 	b	.invokeinterface_invoke
 
+# r2 = [jpc, #1]
+	Opcode	invokedynamic
+	DECACHE_STACK
+	// Fetch index bytes from bytecode
+	ldrb	r0, [jpc, #2]
+	ldrb	r1, [jpc, #3]
+	ldrb	r3, [jpc, #4]
+	orr	r2, r2, r0, lsl #8
+	orr	r2, r2, r1, lsl #16
+	orr	r1, r2, r3, lsl #24
+	// The index is inverted, so we invert it back with MVN
+        mvn     r1, r1
+	// The pool entry is in R0
+        add     r0, constpool, r1, lsl #4
+
+	// Save the pool entry
+	stmfd	arm_sp!, {r0}
+
+	DECACHE_JPC
+	ldr     r1, [r0, #CP_OFFSET+4]  // Pointer to call site
+	// Already resolved?
+	cmp     r1, #0 
+	bleq    resolve_invokedynamic
+
+	// Get the offset from a call site to the corresponding target
+	// method handle
+	bl	Helper_target_offset_in_bytes
+	mov	lr, r0
+
+	// Restore the pool entry
+	ldmfd	arm_sp!, {r0}
+
+	ldr	r0, [r0, #CP_OFFSET+4]	// Call site
+.abortentry119:
+	ldr	r0, [r0, lr]		// Method handle
+	ldr	r1, [istate, #ISTATE_THREAD]
+
+	// Call the target method
+	bl	_ZN14CppInterpreter21process_method_handleEP7oopDescP6Thread
+
+	// Load up the interpreter registers.  Probably not necessary
+	adrl	ip, dispatch_init_adcon
+	ldm	ip, {r0, r1}
+	add	r0, r0, ip
+	add	dispatch, r1, r0
+
+	CACHE_LOCALS
+
+	ldr	ip, [istate, #ISTATE_THREAD]
+	CACHE_JPC
+	ldr	stack, [ip, #THREAD_JAVA_SP]
+	ldr	r2, [istate, #ISTATE_STACK_LIMIT]
+	sub	stack, stack, #4
+
+	// Fix up everything in the thread state to point to the
+	// current frame
+	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
+	// Test for an exception
+	ldr	r3, [ip, #4]
+	DISPATCH_NEXT
+	DISPATCH_NEXT
+	cmp	r3, #0
+	DISPATCH_NEXT
+	bne	invokedynamic_exception_fix
+	DISPATCH_NEXT
+	CACHE_CP
+	DISPATCH_FINISH
+
+resolve_invokedynamic:
+	stmfd	arm_sp!, {lr}
+	ldr	r0, [istate, #ISTATE_THREAD]
+	bl	_ZN18InterpreterRuntime21resolve_invokedynamicEP10JavaThread
+	ldmfd	arm_sp!, {pc}
+
+	// Handler for java.lang.invoke.MethodHandles::invoke
+	ALIGN_CODE
+method_handle_entry:
+ 	b	fast_method_handle_entry	
+	ALIGN_CODE
+fast_method_handle_entry:
+	stmfd	arm_sp!, {regset, lr}
+	bl	_ZN14CppInterpreter19method_handle_entryEP13methodOopDesciP6Thread
+	ldmia	sp!, {regset, pc}
+
+	// Common code for fast_aldc and fast_aldc_w
+# r0 = constpool cache entry
+	.macro	aldc	opc, seq_len
+	// Save the pool entry
+	stmfd	arm_sp!, {r0}
+
+	DECACHE_JPC
+	ldr     r1, [r0, #CP_OFFSET+4]  // Pointer to call site
+	// Already resolved?
+	cmp     r1, #0 
+	ldr	r0, [istate, #ISTATE_THREAD]
+	mov	r1, #\opc
+	bleq    _ZN18InterpreterRuntime11resolve_ldcEP10JavaThreadN9Bytecodes4CodeE
+
+	// Restore the pool entry
+	ldmfd	arm_sp!, {r0}
+
+	ldr     r1, [r0, #CP_OFFSET+4]  // Pointer to MethodHandle
+	PUSH	r1
+
+	// Test for an exception
+	ldr	ip, [istate, #ISTATE_THREAD]
+	ldr	r3, [ip, #4]
+	cmp	r3, #0
+	bne	handle_exception
+	
+	DISPATCH	\seq_len
+	.endm
+
+	// Handler for ldc MethodHandle
+# r2 = [jpc, #1]
+	Opcode fast_aldc
+	DECACHE_STACK
+        add     r0, constpool, r2, lsl #4
+	aldc opc_fast_aldc, 2
+
+	// Handler for ldc_w MethodHandle
+# r2 = [jpc, #1]
+# r1 = [jpc, #2]
+	Opcode fast_aldc_w
+	// Fetch index bytes from bytecode
+	ldrb	r1, [jpc, #2]
+	DECACHE_STACK
+	orr	r1, r2, r1, lsl #8
+        add     r0, constpool, r1, lsl #4
+	aldc opc_fast_aldc_w, 3
+
 #ifdef FAST_BYTECODES
 # r2 = [jpc, #1]
 # r1 = [jpc, #2]
@@ -3507,6 +3652,7 @@
 	.byte	0
 	ALIGN_WORD
 
+invokedynamic_exception_fix:
 invokeinterface_exception_fix:
 	sub	jpc, jpc, #2
 invoke_exception_fix:
@@ -4974,7 +5120,7 @@
 	.word	do_invokespecial	@ 183 0xb7
 	.word	do_invokestatic	@ 184 0xb8
 	.word	do_invokeinterface	@ 185 0xb9
-	.word	do_undefined	@ 186 0xba
+	.word	do_invokedynamic	@ 186 0xba
 	.word	do_new	@ 187 0xbb
 	.word	do_newarray	@ 188 0xbc
 	.word	do_anewarray	@ 189 0xbd
@@ -5017,8 +5163,8 @@
 	.word	do_invokevfinal	@ 226 0xe2
 	.word	do_fast_iload_iload	@ 227 0xe3
 	.word	do_fast_iload_iload_N	@ 228 0xe4
-	.word	do_undefined	@ 229 0xe5
-	.word	do_undefined	@ 230 0xe6
+	.word	do_fast_aldc		@ 229 0xe5
+	.word	do_fast_aldc_w	@ 230 0xe6
 	.word	do_return_register_finalizer	@ 231 0xe7
 	.word	do_undefined	@ 232 0xe8
 	.word	do_iload_0_iconst_N	@ 233 0xe9
--- a/src/cpu/zero/vm/thumb2.cpp	Fri Mar 16 08:36:04 2012 -0400
+++ b/src/cpu/zero/vm/thumb2.cpp	Wed Apr 11 09:24:03 2012 -0400
@@ -239,6 +239,7 @@
 #define opc_invokespecial	0xb7
 #define opc_invokestatic	0xb8
 #define opc_invokeinterface	0xb9
+#define opc_invokedynamic	0xba
 #define opc_new			0xbb
 #define opc_newarray		0xbc
 #define opc_anewarray		0xbd
@@ -258,6 +259,9 @@
 
 #define OPC_LAST_JAVA_OP	0xca
 
+#define opc_fast_aldc		Bytecodes::_fast_aldc
+#define opc_fast_aldc_w		Bytecodes::_fast_aldc_w
+
 #define opc_bgetfield			0xcc
 #define opc_cgetfield			0xcd
 #define opc_igetfield			0xd0
@@ -413,6 +417,7 @@
 #endif // PRODUCT
 
 #define GET_NATIVE_U2(p)	(*(unsigned short *)(p))
+#define GET_NATIVE_U4(p)	(*(unsigned *)(p))
 
 #define GET_JAVA_S1(p)		(((signed char *)(p))[0])
 #define GET_JAVA_S2(p)  	((((signed char *)(p))[0] << 8) + (p)[1])
@@ -1166,7 +1171,7 @@
 	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokespecial
 	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokestatic
 	BCI(3, 0, 0, 1, 0, 0, 0, 0, 0),	// invokeinterface
-	BCI(0, 0, 0, 1, 0, 0, 0, 0, 0),	// xxxunusedxxx
+	BCI(5, 0, 0, 1, 0, 0, 0, 0, 0),	// invokedynamic
 	BCI(3, 0, 1, 0, 0, 0, 0, 0, 0),	// new
 	BCI(2, 1, 1, 0, 0, 0, 0, 0, 0),	// newarray
 	BCI(3, 1, 1, 0, 0, 0, 0, 0, 0),	// anewarray
@@ -1209,8 +1214,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(2, 0, 1, 0, 0, 0, 0, 0, 0),	// fast_aldc
+	BCI(3, 0, 1, 0, 0, 0, 0, 0, 0),	// fast_aldc_w
 	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
@@ -1302,6 +1307,16 @@
 	break;
       }
 
+    case opc_invokedynamic:
+      bci += 5;
+      break;
+    case opc_fast_aldc_w:
+      bci += 3;
+      break;
+    case opc_fast_aldc:
+      bci += 2;
+      break;
+
       case opc_jsr: {
 	int off = GET_JAVA_S2(code_base+bci+1);
 	if (off < 0) bc_stackinfo[bci+off] |= BC_BACK_TARGET;
@@ -1804,6 +1819,21 @@
 	break;
       }
 
+      case opc_invokedynamic: {
+	int site_index = GET_NATIVE_U4(code_base+bci+1);
+	constantPoolOop pool = jinfo->method->constants();
+	int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index();
+	// int pool_index = pool->cache()->entry_at(main_index)->constant_pool_index();
+	Symbol *sig = pool->signature_ref_at(main_index);
+	const jbyte *base = sig->base();
+
+	//tty->print("%d: %s: %s\n", opcode, name->as_C_string(), sig->as_C_string());
+	stackdepth += method_stackchange(base);
+	opcode = code_base[bci];
+	bci += 5;
+	break;
+      }
+
       case opc_invokeresolved:
       case opc_invokespecialresolved:
       case opc_invokestaticresolved:
@@ -5249,10 +5279,17 @@
     stackdepth = stackinfo & ~BC_FLAGS_MASK;
     bc_stackinfo[bci] = (stackinfo & BC_FLAGS_MASK) | (codebuf->idx * 2) | BC_COMPILED;
 
-    if (opcode > OPC_LAST_JAVA_OP && opcode != opc_return_register_finalizer) {
-      if (Bytecodes::is_defined((Bytecodes::Code)opcode))
-	opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
-    }
+    if (opcode > OPC_LAST_JAVA_OP)
+      switch (opcode) {
+      default:
+	if (Bytecodes::is_defined((Bytecodes::Code)opcode))
+	  opcode = (unsigned)Bytecodes::java_code((Bytecodes::Code)opcode);
+	break;
+      case opc_return_register_finalizer:
+      case opc_fast_aldc_w:
+      case opc_fast_aldc:
+	break;
+      }
 
     len = Bytecodes::length_for((Bytecodes::Code)opcode);
     if (len <= 0) {
@@ -6546,6 +6583,31 @@
 	break;
       }
 
+    case opc_invokedynamic:
+      {
+	Thumb2_Exit(jinfo, H_EXIT_TO_INTERPRETER, bci, stackdepth);
+	break;
+      }
+
+    case opc_fast_aldc_w:
+    case opc_fast_aldc:
+      {
+	unsigned index = (opcode == (unsigned)opc_fast_aldc) ?
+				code_base[bci+1] : GET_NATIVE_U2(code_base+bci+1);
+	constantPoolOop constants = jinfo->method->constants();
+	ConstantPoolCacheEntry* cpce = constants->cache()->entry_at(index);
+        if (! cpce->is_f1_null()) {
+	  Thumb2_Spill(jinfo, 1, 0);
+	  int r = JSTACK_REG(jstack);
+	  PUSH(jstack, r);
+	  ldr_imm(jinfo->codebuf, r, Ristate, ISTATE_CONSTANTS, 1, 0);
+	  ldr_imm(jinfo->codebuf, r, r, CP_OFFSET + (index << 4) + 4, 1, 0); // offset to cache->f1()
+	} else {
+	  Thumb2_Exit(jinfo, H_EXIT_TO_INTERPRETER, bci, stackdepth);
+	}
+	break;
+      }
+
       case opc_jsr_w:
       case opc_jsr: {
 	Thumb2_Jsr(jinfo , bci, stackdepth);