public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* libffi: closures for sparc
@ 2002-07-17  8:09 Jeff Sturm
  2002-07-17  8:57 ` Kresten Krab Thorup
  0 siblings, 1 reply; 5+ messages in thread
From: Jeff Sturm @ 2002-07-17  8:09 UTC (permalink / raw)
  To: gcc-patches; +Cc: java-patches

I've finished enough of the closure API for sparc to enable the libgcj
bytecode interpreter for sparc and sparc64.  Notes on the implementation:

a) Stack-allocated trampolines Just Don't Work on Solaris unless you
arrange for the stack to be executable, somehow.  Gcc relies on a mprotect
hack to get around this.  I've chosen to eschew this hack in libffi since
libgcj doesn't need it.  The only code I'm aware of that breaks is the
libffi testsuite, so the simplest thing to do is fix the testsuite.

b) The mess in java_raw_api.c is mostly caused by treating the `raw'
argument to ffi_java_raw_call as a pointer to ffi_raw, when it is really a
pointer to _Jv_word.  The two unions are not compatible, or even close.
For instance ffi_raw may not have a 32-bit integer member resembling a
`jint'.

This whole file ought to be looked at more closely, since it seems to be
using ffi_raw as something it isn't.  I'd expect ppc64 to have the same
problems as sparc64.

c) I didn't do any testing on FFI_TYPE_STRUCT arguments to closures.
There are currently no such tests, hence no failures.  I have little
interest in adding test cases since they are irrelevant to gcj.  If
someone else contributes test cases for structs I'll take a look.

d) sparc64 closures will fail in circumstances such as fp args and
variadic functions or functions without prototypes.  I could find
no portable way to accomodate these in libffi at this time.

Tested on sparc-sun-solaris2.8 with GNU binutils and Sun as/ld.  I'm
interested in feedback from sparc-linux and powerpc users.

2002-07-17  Jeff Sturm  <jsturm@one-point.com>

	* include/ffi.h.in: Add closure defines for SPARC, SPARC64.
	* src/ffitest.c (main): Use static storage for closure.
	* src/java_raw_api.c (ffi_java_raw_to_ptrarray,
	ffi_java_ptrarray_to_raw): For WORDS_BIGENDIAN, handle
	raw argument as a _Jv_word.
	* src/sparc/ffi.c (ffi_prep_closure, ffi_closure_sparc_inner): New.
	* src/sparc/v8.S (ffi_closure_v8): New.
	* src/sparc/v9.S (ffi_closure_v9): New.

Index: include/ffi.h.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/include/ffi.h.in,v
retrieving revision 1.15
diff -u -p -r1.15 ffi.h.in
--- include/ffi.h.in	29 Apr 2002 04:14:44 -0000	1.15
+++ include/ffi.h.in	17 Jul 2002 04:56:46 -0000
@@ -430,6 +430,18 @@ struct ffi_ia64_trampoline_struct {
 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */
 #define FFI_NATIVE_RAW_API 0

+#elif defined(SPARC64)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(SPARC)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
 #else

 #define FFI_CLOSURES 0
Index: src/ffitest.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/ffitest.c,v
retrieving revision 1.6
diff -u -p -r1.6 ffitest.c
--- src/ffitest.c	24 Feb 2002 17:31:45 -0000	1.6
+++ src/ffitest.c	17 Jul 2002 04:56:46 -0000
@@ -704,7 +704,9 @@ int main(/*@unused@*/ int argc, /*@unuse
 # if FFI_CLOSURES
   /* A simple closure test */
     {
-      ffi_closure cl;
+      /* The closure must not be an automatic variable on
+	 platforms (Solaris) that forbid stack execution by default. */
+      static ffi_closure cl;
       ffi_type * cl_arg_types[3];

       cl_arg_types[0] = &ffi_type_sint;
Index: src/java_raw_api.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/java_raw_api.c,v
retrieving revision 1.2
diff -u -p -r1.2 java_raw_api.c
--- src/java_raw_api.c	8 Apr 2002 23:59:13 -0000	1.2
+++ src/java_raw_api.c	17 Jul 2002 04:56:46 -0000
@@ -81,21 +81,14 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif,
 	{
 	case FFI_TYPE_UINT8:
 	case FFI_TYPE_SINT8:
-	  *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1);
+	  *args = (void*) ((char*)(raw++) + 3);
 	  break;

 	case FFI_TYPE_UINT16:
 	case FFI_TYPE_SINT16:
-	  *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2);
+	  *args = (void*) ((char*)(raw++) + 2);
 	  break;

-#if SIZEOF_ARG >= 4
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	  *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4);
-	  break;
-#endif
-
 #if SIZEOF_ARG == 8
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_SINT64:
@@ -157,31 +150,54 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif,
       switch ((*tp)->type)
 	{
 	case FFI_TYPE_UINT8:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT8*) (*args);
+#else
 	  (raw++)->uint = *(UINT8*) (*args);
+#endif
 	  break;

 	case FFI_TYPE_SINT8:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT8*) (*args);
+#else
 	  (raw++)->sint = *(SINT8*) (*args);
+#endif
 	  break;

 	case FFI_TYPE_UINT16:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT16*) (*args);
+#else
 	  (raw++)->uint = *(UINT16*) (*args);
+#endif
 	  break;

 	case FFI_TYPE_SINT16:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT16*) (*args);
+#else
 	  (raw++)->sint = *(SINT16*) (*args);
+#endif
 	  break;

-#if SIZEOF_ARG >= 4
 	case FFI_TYPE_UINT32:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT32*) (*args);
+#else
 	  (raw++)->uint = *(UINT32*) (*args);
+#endif
 	  break;

 	case FFI_TYPE_SINT32:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT32*) (*args);
+#else
 	  (raw++)->sint = *(SINT32*) (*args);
-	  break;
 #endif
-        case FFI_TYPE_FLOAT:
+	  break;
+
+	case FFI_TYPE_FLOAT:
 	  (raw++)->flt = *(FLOAT32*) (*args);
 	  break;

Index: src/sparc/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/sparc/ffi.c,v
retrieving revision 1.3
diff -u -p -r1.3 ffi.c
--- src/sparc/ffi.c	2 Mar 2001 22:21:23 -0000	1.3
+++ src/sparc/ffi.c	17 Jul 2002 04:56:46 -0000
@@ -28,6 +28,12 @@

 #include <stdlib.h>

+#ifdef SPARC64
+extern void ffi_closure_v9(void);
+#else
+extern void ffi_closure_v8(void);
+#endif
+
 /* ffi_prep_args is called by the assembly routine once stack space
    has been allocated for the function's arguments */

@@ -419,4 +425,102 @@ void ffi_call(ffi_cif *cif, void (*fn)()
       break;
     }

+}
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn;
+  unsigned long ctx = (unsigned long) closure;
+
+#ifdef SPARC64
+  /* Trampoline address is equal to the closure address.  We take advantage
+     of that to reduce the trampoline size by 8 bytes. */
+  FFI_ASSERT (cif->abi == FFI_V9);
+  fn = (unsigned long) ffi_closure_v9;
+  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
+  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/
+  tramp[2] = 0x81c14000;	/* jmp	%g5		*/
+  tramp[3] = 0x01000000;	/* nop			*/
+  *((unsigned long *) &tramp[4]) = fn;
+#else
+  FFI_ASSERT (cif->abi == FFI_V8);
+  fn = (unsigned long) ffi_closure_v8;
+  tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/
+  tramp[1] = 0x05000000 | ctx >> 10;	/* sethi %hi(ctx), %g2	*/
+  tramp[2] = 0x81c06000 | (fn & 0x3ff);	/* jmp   %g1+%lo(fn)	*/
+  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)	*/
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the Icache.  FIXME: alignment isn't certain, assume 8 bytes */
+#ifdef SPARC64
+  asm volatile ("flush	%0" : : "r" (closure) : "memory");
+  asm volatile ("flush	%0" : : "r" (((char *) closure) + 8) : "memory");
+#else
+  asm volatile ("iflush	%0" : : "r" (closure) : "memory");
+  asm volatile ("iflush	%0" : : "r" (((char *) closure) + 8) : "memory");
+#endif
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_sparc_inner(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, double *fpr)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  int i, avn, argn;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  argn = 0;
+
+  /* Copy the caller's structure return address to that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) gpr[0];
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      /* Assume big-endian.  FIXME */
+      argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+
+#ifdef SPARC64
+      if (i < 6 && (arg_types[i]->type == FFI_TYPE_FLOAT
+		 || arg_types[i]->type == FFI_TYPE_DOUBLE
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+		))
+        avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
+      else
+#endif
+        avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+      i++;
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
 }
Index: src/sparc/v8.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/sparc/v8.S,v
retrieving revision 1.6
diff -u -p -r1.6 v8.S
--- src/sparc/v8.S	28 Apr 2002 19:57:42 -0000	1.6
+++ src/sparc/v8.S	17 Jul 2002 04:56:46 -0000
@@ -94,6 +94,97 @@ longlong:
 .ffi_call_V8_end:
 	.size	ffi_call_V8,.ffi_call_V8_end-ffi_call_V8

+
+#define	STACKFRAME	104	/* 16*4 register window +
+				   1*4 struct return +
+				   6*4 args backing store +
+				   3*4 locals */
+
+/* ffi_closure_v8(...)
+
+   Receives the closure argument in %g2.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v8
+
+ffi_closure_v8:
+	.register	%g2, #scratch
+.LLFB2:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	st	%i0, [%fp+68+0]
+	st	%i1, [%fp+68+4]
+	st	%i2, [%fp+68+8]
+	st	%i3, [%fp+68+12]
+	st	%i4, [%fp+68+16]
+	st	%i5, [%fp+68+20]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g2, %o0
+	add	%fp, -8, %o1
+	add	%fp,  68, %o2
+	call	ffi_closure_sparc_inner
+	 mov	0, %o3
+
+	! Load up the return value in the proper type.
+	cmp	%o0, FFI_TYPE_VOID
+	be	done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be,a	done1
+	 ld	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_POINTER
+	be,a	done1
+	 ld	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a	done1
+	 ld	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a	done1
+	 ldd	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_UINT8
+	be,a	done1
+	 ldub	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_SINT8
+	be,a	done1
+	 ldsb	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_UINT16
+	be,a	done1
+	 lduh	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_SINT16
+	be,a	done1
+	 ldsh	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_UINT32
+	be,a	done1
+	 ld	[%fp-8], %i0
+
+	cmp	%o0, FFI_TYPE_SINT32
+	be,a	done1
+	 ld	[%fp-8], %i0
+
+	! FFI_TYPE_UINT64 | FFI_TYPE_SINT64
+	ld	[%fp-8], %i0
+	ld	[%fp-4], %i1
+
+done1:
+	ret
+	 restore
+.LLFE2:
+
+.ffi_closure_v8_end:
+	.size	ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
+
 #ifdef SPARC64
 #define WS 8
 #define nword	xword
@@ -148,3 +239,26 @@ longlong:
 	.byte	0x1f	! uleb128 0x1f
 	.align	WS
 .LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB2
+	.uanword .LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE2:
Index: src/sparc/v9.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/sparc/v9.S,v
retrieving revision 1.4
diff -u -p -r1.4 v9.S
--- src/sparc/v9.S	28 Apr 2002 19:57:42 -0000	1.4
+++ src/sparc/v9.S	17 Jul 2002 04:56:46 -0000
@@ -99,7 +99,7 @@ _ffi_call_V9:
 	cmp	%i3, FFI_TYPE_STRUCT
 	be,pn	%icc, dostruct

-	 cmp	%i3, FFI_TYPE_LONGDOUBLE
+	cmp	%i3, FFI_TYPE_LONGDOUBLE
 	bne,pt	%icc, done
 	 nop
 	std	%f0, [%i4+0]
@@ -125,6 +125,116 @@ dostruct:
 .ffi_call_V9_end:
 	.size	ffi_call_V9,.ffi_call_V9_end-ffi_call_V9

+
+#define	STACKFRAME	 240	/* 16*8 register window +
+				   6*8 args backing store +
+				   8*8 locals */
+#define	FP		%fp+STACK_BIAS
+
+/* ffi_closure_v9(...)
+
+   Receives the closure argument in %g1.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v9
+
+ffi_closure_v9:
+.LLFB2:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	stx	%i0, [FP+128+0]
+	stx	%i1, [FP+128+8]
+	stx	%i2, [FP+128+16]
+	stx	%i3, [FP+128+24]
+	stx	%i4, [FP+128+32]
+	stx	%i5, [FP+128+40]
+
+	! Store possible floating point argument registers too.
+	std	%f0, [FP-48]
+	std	%f2, [FP-40]
+	std	%f4, [FP-32]
+	std	%f6, [FP-24]
+	std	%f8, [FP-16]
+	std	%f10, [FP-8]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g1, %o0
+	add	%fp, STACK_BIAS-64, %o1
+	add	%fp, STACK_BIAS+128, %o2
+	call	ffi_closure_sparc_inner
+	 add	%fp, STACK_BIAS-48, %o3
+
+	! Load up the return value in the proper type.
+	cmp	%o0, FFI_TYPE_VOID
+	be,pn	%icc, done1
+
+	cmp	%o0, FFI_TYPE_INT
+	be,a,pn	%icc, done1
+	 ldsw	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done1
+	 ld	[FP-64], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done1
+	 ldd	[FP-64], %f0
+
+	cmp	%o0, FFI_TYPE_UINT8
+	be,a,pn	%icc, done1
+	 ldub	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_SINT8
+	be,a,pn	%icc, done1
+	 ldsb	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_UINT16
+	be,a,pn	%icc, done1
+	 lduh	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_SINT16
+	be,a,pn	%icc, done1
+	 ldsh	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_UINT32
+	be,a,pn	%icc, done1
+	 lduw	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_SINT32
+	be,a,pn	%icc, done1
+	 ldsw	[FP-64], %i0
+
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be,a,pn	%icc, longdouble1
+	 ldd	[FP-64], %f0
+
+	cmp	%o0, FFI_TYPE_STRUCT
+	be,pn	%icc, struct1
+
+	! FFI_TYPE_UINT64 | FFI_TYPE_SINT64 | FFI_TYPE_POINTER
+	ldx	[FP-64], %i0
+
+done1:
+	ret
+	 restore
+
+struct1:
+	ldx [FP-56], %i2
+	ret
+	 restore
+
+longdouble1:
+	ldd	[FP-56], %f2
+	ret
+	 restore
+.LLFE2:
+
+.ffi_closure_v9_end:
+	.size	ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
+
 	.section	".eh_frame",#alloc,#write
 .LLframe1:
 	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
@@ -169,5 +279,27 @@ dostruct:
 	.byte	0x1f	! uleb128 0x1f
 	.align 8
 .LLEFDE1:
-
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB2
+	.uaxword	.LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE2:
 #endif


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: libffi: closures for sparc
  2002-07-17  8:09 libffi: closures for sparc Jeff Sturm
@ 2002-07-17  8:57 ` Kresten Krab Thorup
  2002-07-17 14:37   ` Jeff Sturm
  0 siblings, 1 reply; 5+ messages in thread
From: Kresten Krab Thorup @ 2002-07-17  8:57 UTC (permalink / raw)
  To: Jeff Sturm; +Cc: gcc-patches, java-patches

Jeff Sturm wrote:
> b) The mess in java_raw_api.c is mostly caused by treating the `raw'
> argument to ffi_java_raw_call as a pointer to ffi_raw, when it is really a
> pointer to _Jv_word.  The two unions are not compatible, or even close.
> For instance ffi_raw may not have a 32-bit integer member resembling a
> `jint'.
> 
> This whole file ought to be looked at more closely, since it seems to be
> using ffi_raw as something it isn't.  I'd expect ppc64 to have the same
> problems as sparc64.

I'm out of the loop now, but it should be known that the "raw" api was 
thought as an optimized version of the general ffi api which would make 
sense exactly on architectures where the interpreter's stack (i.e. the 
union of jint, jchar, etc.) is very similar to the layout of arguments 
in the host environment's ABI.  As such, it is indeed ugly; and relies 
on all kinds of assumptions...

Also see http://gcc.gnu.org/ml/java/1999-q3/msg00174.html

Kresten


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: libffi: closures for sparc
  2002-07-17  8:57 ` Kresten Krab Thorup
@ 2002-07-17 14:37   ` Jeff Sturm
  0 siblings, 0 replies; 5+ messages in thread
From: Jeff Sturm @ 2002-07-17 14:37 UTC (permalink / raw)
  To: Kresten Krab Thorup; +Cc: gcc-patches, java-patches

On Wed, 17 Jul 2002, Kresten Krab Thorup wrote:
> I'm out of the loop now, but it should be known that the "raw" api was
> thought as an optimized version of the general ffi api which would make
> sense exactly on architectures where the interpreter's stack (i.e. the
> union of jint, jchar, etc.) is very similar to the layout of arguments
> in the host environment's ABI.  As such, it is indeed ugly; and relies
> on all kinds of assumptions...

I remember the discussion... the x86 interpreter is efficient because of
the raw API, which I believe is a good thing, portable or not.

The plain closure API is fairly portable but realistically is too much
overhead for an efficient bytecode interpreter.  This may be one of those
areas we abandon portability.

Specifically for java_raw_api.c, I'm tempted to pull that layer into
libgcj where it can operate directly on _Jv_word and perhaps use a
simpler, more direct interface into libffi.  Perhaps loading argument
registers directly from the java stack.  But I haven't thought this
through yet.

Good to hear from you, Kresten.

Jeff

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: libffi: closures for sparc
  2002-07-17 16:18 Boehm, Hans
@ 2002-07-24  9:54 ` Tom Tromey
  0 siblings, 0 replies; 5+ messages in thread
From: Tom Tromey @ 2002-07-24  9:54 UTC (permalink / raw)
  To: Boehm, Hans
  Cc: 'Jeff Sturm',
	Kresten Krab Thorup, gcc-patches, java-patches, MOSBERGER,
	DAVID (HP-PaloAlto,unix3)

>>>>> "Hans" == Boehm, Hans <hans_boehm@hp.com> writes:

Hans> Given a choice, I'd rather have libffi know about Java stacks
Hans> then having libgcj know about parameter passing.

Sounds good to me.  As far as I know only libgcj uses the raw and
closure APIs (you mentioned Mozilla; does it use this?).  So we should
feel free to change them to suit us.

Hans> But I'd like to run this past Anthony before investing more
Hans> time.  I'd be undoing some other peoples earlier design
Hans> decisions (which I suspect were really nondecisions).

Well, they were based on information available at the time (i.e.,
little).  We've learned stuff since then.  So no harm done.

Tom

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: libffi: closures for sparc
@ 2002-07-17 16:18 Boehm, Hans
  2002-07-24  9:54 ` Tom Tromey
  0 siblings, 1 reply; 5+ messages in thread
From: Boehm, Hans @ 2002-07-17 16:18 UTC (permalink / raw)
  To: 'Jeff Sturm', Kresten Krab Thorup
  Cc: gcc-patches, java-patches, MOSBERGER, DAVID (HP-PaloAlto,unix3)

I dug up a message I sent to a much smaller list about a year ago, and then never got around to doing much about.  It seems to me this leaves the sticky question about where the Java to/from raw conversion should be implemented, since it seems to have to know both about argument passing conventions and Java stacks.  Given a choice, I'd rather have libffi know about Java stacks then having libgcj know about parameter passing.  But if someone can think of a clean way to factor this ...

Hans

--------------------------------

I think conceptually there should be three versions of the interfaces:

1) The original "cooked" model in which argument lists are arrays of pointers.

2) The "raw" model, which should be entirely machine-specific.  On X86, this is the natural in-memory representation of the arguments.  On IA64, it should use the IA64 argument structure I defined, since the arguments are not normally in memory.  In general, it should eventually be the format used by ffi_closure_inner, on something like Alpha.  (It may be that the va_list format is the best choice here.  it seems to be used on Alpha.)  The representation should be opaque to a machine-independent client.  There should be a portable way to convert it to a "cooked" argument list.

Unfortunately, so far this was defined to use the X86 argument representation on all architectures.  Fortunately, I'm not convinced this interface is currently used on anything other than X86, for which it wouldn't change.  (In the short run, I'll only change it for Itanium.)

3) The "java" model, in which arguments are represented as on a JVM stack.  This happens to coincide with (2) for X86, which I think started this confusion.  On X86, this should just be an alias for (2).  On other architectures, there is currently a generic implementation based on (1), which is fine for now, though basing it on (2) in the future would probably make things run faster.

Doing this cleanly would get rid of some ifdefs from libjava.  I think it would make Mozilla happy.  It might also make it possible for someone to actually understand the libffi interface. I would probably change it in unison with libjava to facilitate some renaming (ffi_java_raw -> ffi_java), which shouldn't break any other clients.

But I'd like to run this past Anthony before investing more time.  I'd be undoing some other peoples earlier design decisions (which I suspect were really nondecisions).


> -----Original Message-----
> From: Jeff Sturm [mailto:jsturm@one-point.com]
> Sent: Wednesday, July 17, 2002 2:34 PM
> To: Kresten Krab Thorup
> Cc: gcc-patches@gcc.gnu.org; java-patches@gcc.gnu.org
> Subject: Re: libffi: closures for sparc
> 
> 
> On Wed, 17 Jul 2002, Kresten Krab Thorup wrote:
> > I'm out of the loop now, but it should be known that the 
> "raw" api was
> > thought as an optimized version of the general ffi api 
> which would make
> > sense exactly on architectures where the interpreter's 
> stack (i.e. the
> > union of jint, jchar, etc.) is very similar to the layout 
> of arguments
> > in the host environment's ABI.  As such, it is indeed ugly; 
> and relies
> > on all kinds of assumptions...
> 
> I remember the discussion... the x86 interpreter is efficient 
> because of
> the raw API, which I believe is a good thing, portable or not.
> 
> The plain closure API is fairly portable but realistically is too much
> overhead for an efficient bytecode interpreter.  This may be 
> one of those
> areas we abandon portability.
> 
> Specifically for java_raw_api.c, I'm tempted to pull that layer into
> libgcj where it can operate directly on _Jv_word and perhaps use a
> simpler, more direct interface into libffi.  Perhaps loading argument
> registers directly from the java stack.  But I haven't thought this
> through yet.
> 
> Good to hear from you, Kresten.
> 
> Jeff
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2002-07-24 16:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-17  8:09 libffi: closures for sparc Jeff Sturm
2002-07-17  8:57 ` Kresten Krab Thorup
2002-07-17 14:37   ` Jeff Sturm
2002-07-17 16:18 Boehm, Hans
2002-07-24  9:54 ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).