* [Patch] libffi: Fixes for MIPS n32 ABI. @ 2007-11-29 7:09 David Daney 2007-12-01 12:08 ` Richard Sandiford 0 siblings, 1 reply; 7+ messages in thread From: David Daney @ 2007-11-29 7:09 UTC (permalink / raw) To: Java Patches; +Cc: gcc-patches [-- Attachment #1: Type: text/plain, Size: 2188 bytes --] The initial patches for mips64/n32 ABI support passed the libffi testsuite, however the java_raw_api support that is used by libjava still contained several problems. This patch attempts to correct them. With the patch applied we now have zero failures in the libjava testsuite (down from around 30). The problem was that libffi and libjava's interpreter use different union definitions to describe stack elements. In the case of mips64/n32, these unions had different sizes (8 vs. 4 bytes). This caused most interpreter method calls to fail. My patch adds a new macro FFI_SIZEOF_RAW that can be set by a libffi target as well as allowing the target to define its own ffi_raw union. If the target does not override these the FFI_SIZEOF_RAW is set to FFI_SIZEOF_ARG, and the default definition of the ffi_raw union is used. The code in java_raw_api, was changed to use FFI_SIZEOF_RAW in most places it was using FFI_SIZEOF_ARG. In addition special handling was added for pointer return values where FFI_SIZEOF_RAW != FFI_SIZEOF_ARG. There were several places where the alignment of the raw pointer was adjusted all using different but equivalent size calculations. I change thse so that they all use sizeof(ffi_raw) as that seemed more correct. Tested on mips64-linux-gnu/n32 and x86_64-pc-linux-gnu{m64,m32} with no regressions. I will also test it on mipsel-linux. OK to commit? 2007-11-28 David Daney <ddaney@avtrex.com> * include/ffi.h.in (FFI_SIZEOF_RAW): Define ifndef. (ffi_raw): Make declaration conditional on FFI_RAW_DEFINED. Make length of data element FFI_SIZEOF_RAW. * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with FFI_SIZEOF_RAW. (ffi_java_raw_to_ptrarray): ReplaceFFI_SIZEOF_ARG with FFI_SIZEOF_RAW. Use sizeof(ffi_raw) for alignment calculations. (ffi_java_ptrarray_to_raw): Same. (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER if FFI_SIZEOF_RAW == 4. (ffi_java_raw_to_rvalue): Same. * src/mips/ffitarget.h (FFI_SIZEOF_RAW): Define for N32 and N64 ABIs. (ffi_raw_arg, ffi_raw_sarg, ffi_raw) Declare for N32 ABI. (FFI_RAW_DEFINED): Define for N32 ABI. [-- Attachment #2: ffi.diff --] [-- Type: text/x-patch, Size: 4694 bytes --] Index: include/ffi.h.in =================================================================== --- include/ffi.h.in (revision 130154) +++ include/ffi.h.in (working copy) @@ -193,13 +193,19 @@ typedef struct { # endif #endif +#ifndef FFI_SIZEOF_RAW +# define FFI_SIZEOF_RAW FFI_SIZEOF_ARG +#endif + +#ifndef FFI_RAW_DEFINED typedef union { ffi_sarg sint; ffi_arg uint; float flt; - char data[FFI_SIZEOF_ARG]; + char data[FFI_SIZEOF_RAW]; void* ptr; } ffi_raw; +#endif void ffi_raw_call (ffi_cif *cif, void (*fn)(), Index: src/java_raw_api.c =================================================================== --- src/java_raw_api.c (revision 130154) +++ src/java_raw_api.c (working copy) @@ -54,13 +54,13 @@ ffi_java_raw_size (ffi_cif *cif) case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: - result += 2 * FFI_SIZEOF_ARG; + result += 2 * FFI_SIZEOF_RAW; break; case FFI_TYPE_STRUCT: /* No structure parameters in Java. */ abort(); default: - result += FFI_SIZEOF_ARG; + result += FFI_SIZEOF_RAW; } } @@ -90,7 +90,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, *args = (void*) ((char*)(raw++) + 2); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -105,7 +105,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, default: *args = raw; - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += ALIGN ((*tp)->size, sizeof(ffi_raw)) / sizeof(ffi_raw); } } @@ -116,7 +116,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, /* then assume little endian */ for (i = 0; i < cif->nargs; i++, tp++, args++) { -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_RAW == 8 switch((*tp)->type) { case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: @@ -127,10 +127,10 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, default: *args = (void*) raw++; } -#else /* FFI_SIZEOF_ARG != 8 */ +#else /* FFI_SIZEOF_RAW != 8 */ *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); -#endif /* FFI_SIZEOF_ARG == 8 */ + raw += ALIGN ((*tp)->size, sizeof(ffi_raw)) / sizeof(ffi_raw); +#endif /* FFI_SIZEOF_RAW == 8 */ } #else @@ -202,7 +202,7 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, (raw++)->flt = *(FLOAT32*) (*args); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -216,11 +216,11 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, break; default: -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_RAW == 8 FFI_ASSERT(0); /* Should have covered all cases */ #else memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += ALIGN ((*tp)->size, sizeof(ffi_raw)) / sizeof(ffi_raw); #endif } } @@ -244,6 +244,9 @@ ffi_java_rvalue_to_raw (ffi_cif *cif, vo case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue <<= 32; break; @@ -269,6 +272,9 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, vo case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue >>= 32; break; Index: src/mips/ffitarget.h =================================================================== --- src/mips/ffitarget.h (revision 130154) +++ src/mips/ffitarget.h (working copy) @@ -42,10 +42,15 @@ #ifdef FFI_MIPS_O32 /* O32 stack frames have 32bit integer args */ -#define FFI_SIZEOF_ARG 4 +# define FFI_SIZEOF_ARG 4 #else /* N32 and N64 frames have 64bit integer args */ -#define FFI_SIZEOF_ARG 8 +# define FFI_SIZEOF_ARG 8 +# ifdef FFI_MIPS_N32 +# define FFI_SIZEOF_RAW 4 +# else /* N64 */ +# define FFI_SIZEOF_RAW FFI_SIZEOF_ARG +# endif #endif #define FFI_FLAG_BITS 2 @@ -136,6 +141,20 @@ typedef signed int ffi_sarg __attr /* N32 and N64 frames have 64bit integer args */ typedef unsigned int ffi_arg __attribute__((__mode__(__DI__))); typedef signed int ffi_sarg __attribute__((__mode__(__DI__))); + +# ifdef FFI_MIPS_N32 +typedef unsigned int ffi_raw_arg __attribute__((__mode__(__SI__))); +typedef signed int ffi_raw_sarg __attribute__((__mode__(__SI__))); +# define FFI_RAW_DEFINED +typedef union { + ffi_raw_sarg sint; + ffi_raw_arg uint; + float flt; + char data[FFI_SIZEOF_RAW]; + void* ptr; +} ffi_raw; +# endif /* FFI_MIPS_N32 */ + #endif typedef enum ffi_abi { ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch] libffi: Fixes for MIPS n32 ABI. 2007-11-29 7:09 [Patch] libffi: Fixes for MIPS n32 ABI David Daney @ 2007-12-01 12:08 ` Richard Sandiford 2007-12-01 18:43 ` David Daney 0 siblings, 1 reply; 7+ messages in thread From: Richard Sandiford @ 2007-12-01 12:08 UTC (permalink / raw) To: David Daney; +Cc: Java Patches, gcc-patches David mentioned privately that the Java maintainers wanted a target maintainer to look at this. TBH, I don't think much of this is target-specific, but: David Daney <ddaney@avtrex.com> writes: > The initial patches for mips64/n32 ABI support passed the libffi > testsuite, however the java_raw_api support that is used by libjava > still contained several problems. This patch attempts to correct them. > With the patch applied we now have zero failures in the libjava > testsuite (down from around 30). > > The problem was that libffi and libjava's interpreter use different > union definitions to describe stack elements. In the case of > mips64/n32, these unions had different sizes (8 vs. 4 bytes). This > caused most interpreter method calls to fail. ...you're talking about ffi_raw vs. _Jv_word, right? As far as reviewing the patch goes, I'll sign off on the former being 8 bytes and the latter being 4, if that helps. Naively, rather than have an n32-specific definition of ffi_raw, I'd have thought that we'd want some new target-controllable macro that causes ffi_raw to be defined in the same way as _Jv_Word. It sounds like this issue could affect other 64-bit targets with an ILP32 ABI. I don't really know much about the subtleties of the ffi_raw_* vs. ffi_java_raw_* APIs though. What does ffi_raw correspond to when using the ffi_raw_* API (rather than the ffi_java_raw_* API) on a !FFI_NATIVE_RAW_API target? Is there any significance to the structure's size? Clearly ffi_raw as it stands is an accurate description of the smallest possible n32 stack argument, whereas the new ffi_raw would be more like half a stack argument. As far as ffi_raw and java goes, the comment in java_raw_api.c says: /* This defines a Java- and 64-bit specific variant of the raw API. */ /* It assumes that "raw" argument blocks look like Java stacks on a */ /* 64-bit machine. Arguments that can be stored in a single stack */ /* stack slots (longs, doubles) occupy 128 bits, but only the first */ /* 64 bits are actually used. */ But why doesn't the ffi_java_raw_* API use a separate union that matches the layout of _Jv_Word on all targets? I realise that ffi_raw and _Jv_word really must match if FFI_NATIVE_RAW_API, but must they match otherwise? Even if backwards compatibility weren't a concern for some targets? (I realise it _is_ a concern for targets that were supported in 4.2.) Sorry for the barage of questions. I'm just trying to get a feel for the issues. Richard ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch] libffi: Fixes for MIPS n32 ABI. 2007-12-01 12:08 ` Richard Sandiford @ 2007-12-01 18:43 ` David Daney 2007-12-01 19:14 ` Richard Sandiford 0 siblings, 1 reply; 7+ messages in thread From: David Daney @ 2007-12-01 18:43 UTC (permalink / raw) To: Java Patches, gcc-patches, rsandifo Richard Sandiford wrote: > David mentioned privately that the Java maintainers wanted a target > maintainer to look at this. TBH, I don't think much of this is > target-specific, but: > > David Daney <ddaney@avtrex.com> writes: > >> The initial patches for mips64/n32 ABI support passed the libffi >> testsuite, however the java_raw_api support that is used by libjava >> still contained several problems. This patch attempts to correct them. >> With the patch applied we now have zero failures in the libjava >> testsuite (down from around 30). >> >> The problem was that libffi and libjava's interpreter use different >> union definitions to describe stack elements. In the case of >> mips64/n32, these unions had different sizes (8 vs. 4 bytes). This >> caused most interpreter method calls to fail. >> > > ...you're talking about ffi_raw vs. _Jv_word, right? Correct. > As far as > reviewing the patch goes, I'll sign off on the former being 8 bytes > and the latter being 4, That was the state for n32 before the patch and the cause of the problems. > if that helps. > Well, it helps it the sense that it clarifies my thinking and leads me to think that the patch should be withdrawn. Instead I think we want to define a java_ffi_raw union that agrees with _Jv_word. All of the functions in java_raw_api would then be modified to take java_ffi_raw* parameters. > Naively, rather than have an n32-specific definition of ffi_raw, > I'd have thought that we'd want some new target-controllable macro > that causes ffi_raw to be defined in the same way as _Jv_Word. > It sounds like this issue could affect other 64-bit targets > with an ILP32 ABI. > Presumably there are users of the ffi_raw API and we cannot change the definition of the ffi_raw union. > I don't really know much about the subtleties of the ffi_raw_* > vs. ffi_java_raw_* APIs though. What does ffi_raw correspond to > when using the ffi_raw_* API (rather than the ffi_java_raw_* API) > on a !FFI_NATIVE_RAW_API target? Is there any significance to the > structure's size? Clearly ffi_raw as it stands is an accurate > description of the smallest possible n32 stack argument, whereas > the new ffi_raw would be more like half a stack argument. > > As far as ffi_raw and java goes, the comment in java_raw_api.c says: > > /* This defines a Java- and 64-bit specific variant of the raw API. */ > /* It assumes that "raw" argument blocks look like Java stacks on a */ > /* 64-bit machine. Arguments that can be stored in a single stack */ > /* stack slots (longs, doubles) occupy 128 bits, but only the first */ > /* 64 bits are actually used. */ > > But why doesn't the ffi_java_raw_* API use a separate union that matches > the layout of _Jv_Word on all targets? That is what my new patch will do. > I realise that ffi_raw and _Jv_word > really must match if FFI_NATIVE_RAW_API, but must they match otherwise? > Even if backwards compatibility weren't a concern for some targets? > (I realise it _is_ a concern for targets that were supported in 4.2.) > > Sorry for the barage of questions. I'm just trying to get a feel > for the issues. > > Richard > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch] libffi: Fixes for MIPS n32 ABI. 2007-12-01 18:43 ` David Daney @ 2007-12-01 19:14 ` Richard Sandiford 2007-12-03 18:56 ` David Daney 0 siblings, 1 reply; 7+ messages in thread From: Richard Sandiford @ 2007-12-01 19:14 UTC (permalink / raw) To: David Daney; +Cc: Java Patches, gcc-patches David Daney <ddaney@avtrex.com> writes: > Richard Sandiford wrote: >> ...you're talking about ffi_raw vs. _Jv_word, right? > > Correct. > >> As far as >> reviewing the patch goes, I'll sign off on the former being 8 bytes >> and the latter being 4, > > That was the state for n32 before the patch and the cause of the problems. Right. Sorry for being ambiguous (twice in two days!). I meant: I agree that the problem you describe exists for n32, and that it needs to be fixed. (As far as I could tell, that was the only really target-specific item of interest here, so I thought it was the only reviewing input I was qualified to give.) >> But why doesn't the ffi_java_raw_* API use a separate union that matches >> the layout of _Jv_Word on all targets? > > That is what my new patch will do. OK, great. Richard ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch] libffi: Fixes for MIPS n32 ABI. 2007-12-01 19:14 ` Richard Sandiford @ 2007-12-03 18:56 ` David Daney 2007-12-03 19:16 ` Andrew Haley 0 siblings, 1 reply; 7+ messages in thread From: David Daney @ 2007-12-03 18:56 UTC (permalink / raw) To: Java Patches; +Cc: gcc-patches, rsandifo [-- Attachment #1: Type: text/plain, Size: 2951 bytes --] Richard Sandiford wrote: > David Daney <ddaney@avtrex.com> writes: > >> Richard Sandiford wrote: >> >>> ...you're talking about ffi_raw vs. _Jv_word, right? >>> >> Correct. >> >> >>> As far as >>> reviewing the patch goes, I'll sign off on the former being 8 bytes >>> and the latter being 4, >>> >> That was the state for n32 before the patch and the cause of the problems. >> > > Right. Sorry for being ambiguous (twice in two days!). I meant: > I agree that the problem you describe exists for n32, and that it > needs to be fixed. (As far as I could tell, that was the only really > target-specific item of interest here, so I thought it was the only > reviewing input I was qualified to give.) > > >>> But why doesn't the ffi_java_raw_* API use a separate union that matches >>> the layout of _Jv_Word on all targets? >>> >> That is what my new patch will do. >> And here it is: This patch defines a new type ffi_java_raw that agrees with the size of _Jv_Word. It is mostly a mechanical patch except for one place in java_raw_api.c where a change was needed to extract pointers from the return value on big-endian systems with a FFI_SIZEOF_ARG FFI_SIZEOF_JAVA_RAW size disagreement. Is this version preferable to the previous version? Tested on mips64-linux/n32 and x86_64-pc-linux-gnu{-m64,-m32} I will also be testing on mipsel-linux. 2007-12-3 David Daney <ddaney@avtrex.com> * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already defined. (ffi_java_raw): New typedef. (ffi_java_raw_call, ffi_java_ptrarray_to_raw, ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to ffi_java_raw. (ffi_java_raw_closure) : Same. (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change parameter types. * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use sizeof(ffi_java_raw) for alignment calculations. (ffi_java_ptrarray_to_raw): Same. (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER if FFI_SIZEOF_JAVA_RAW == 4. (ffi_java_raw_to_rvalue): Same. (ffi_java_raw_call): Change type of raw to ffi_java_raw. (ffi_java_translate_args): Same. (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change parameter types. * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. 2007-12-3 David Daney <ddaney@avtrex.com> * interpret.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE throughout. (ncode_closure, ffi_closure_fun): Define versions for non-FFI_NATIVE_RAW_API case. * include/java-interp.h (INTERP_FFI_RAW_TYPE): Define and use to replace ffi_raw throughout. * jni.cc, interpret-run.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE throughout. [-- Attachment #2: ffi-1.diff --] [-- Type: text/x-patch, Size: 16587 bytes --] Index: libffi/include/ffi.h.in =================================================================== --- libffi/include/ffi.h.in (revision 130154) +++ libffi/include/ffi.h.in (working copy) @@ -193,6 +193,10 @@ typedef struct { # endif #endif +#ifndef FFI_SIZEOF_JAVA_RAW +# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG +#endif + typedef union { ffi_sarg sint; ffi_arg uint; @@ -201,6 +205,19 @@ typedef union { void* ptr; } ffi_raw; +#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8 +typedef union { + signed int sint; + unsigned int uint; + float flt; + char data[FFI_SIZEOF_JAVA_RAW]; + void* ptr; +} ffi_java_raw; +#else +typedef ffi_raw ffi_java_raw; +#endif + + void ffi_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, @@ -217,10 +234,10 @@ size_t ffi_raw_size (ffi_cif *cif); void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, - ffi_raw *avalue); + ffi_java_raw *avalue); -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); size_t ffi_java_raw_size (ffi_cif *cif); /* ---- Definitions for closures ----------------------------------------- */ @@ -271,6 +288,27 @@ typedef struct { } ffi_raw_closure; +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); + void *user_data; + +} ffi_java_raw_closure; + ffi_status ffi_prep_raw_closure (ffi_raw_closure*, ffi_cif *cif, @@ -285,15 +323,15 @@ ffi_prep_raw_closure_loc (ffi_raw_closur void *codeloc); ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure*, +ffi_prep_java_raw_closure (ffi_java_raw_closure*, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data); ffi_status -ffi_prep_java_raw_closure_loc (ffi_raw_closure*, +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data, void *codeloc); Index: libffi/src/java_raw_api.c =================================================================== --- libffi/src/java_raw_api.c (revision 130154) +++ libffi/src/java_raw_api.c (working copy) @@ -54,13 +54,13 @@ ffi_java_raw_size (ffi_cif *cif) case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: - result += 2 * FFI_SIZEOF_ARG; + result += 2 * FFI_SIZEOF_JAVA_RAW; break; case FFI_TYPE_STRUCT: /* No structure parameters in Java. */ abort(); default: - result += FFI_SIZEOF_ARG; + result += FFI_SIZEOF_JAVA_RAW; } } @@ -69,7 +69,7 @@ ffi_java_raw_size (ffi_cif *cif) void -ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) +ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) { unsigned i; ffi_type **tp = cif->arg_types; @@ -90,7 +90,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, *args = (void*) ((char*)(raw++) + 2); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -105,7 +105,8 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, default: *args = raw; - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += ALIGN ((*tp)->size, + sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); } } @@ -116,7 +117,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, /* then assume little endian */ for (i = 0; i < cif->nargs; i++, tp++, args++) { -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 switch((*tp)->type) { case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: @@ -127,10 +128,11 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, default: *args = (void*) raw++; } -#else /* FFI_SIZEOF_ARG != 8 */ +#else /* FFI_SIZEOF_JAVA_RAW != 8 */ *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); -#endif /* FFI_SIZEOF_ARG == 8 */ + raw += ALIGN ((*tp)->size, + sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); +#endif /* FFI_SIZEOF_JAVA_RAW == 8 */ } #else @@ -141,7 +143,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, } void -ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) +ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) { unsigned i; ffi_type **tp = cif->arg_types; @@ -202,7 +204,7 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, (raw++)->flt = *(FLOAT32*) (*args); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -216,11 +218,12 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, break; default: -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 FFI_ASSERT(0); /* Should have covered all cases */ #else memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += ALIGN ((*tp)->size, + sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); #endif } } @@ -244,6 +247,9 @@ ffi_java_rvalue_to_raw (ffi_cif *cif, vo case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue <<= 32; break; @@ -269,6 +275,9 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, vo case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue >>= 32; break; @@ -285,7 +294,8 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, vo * these following couple of functions will handle the translation forth * and back automatically. */ -void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw) +void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, + ffi_java_raw *raw) { void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); ffi_java_raw_to_ptrarray (cif, raw, avalue); @@ -299,7 +309,7 @@ static void ffi_java_translate_args (ffi_cif *cif, void *rvalue, void **avalue, void *user_data) { - ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif)); + ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif)); ffi_raw_closure *cl = (ffi_raw_closure*)user_data; ffi_java_ptrarray_to_raw (cif, avalue, raw); @@ -308,9 +318,9 @@ ffi_java_translate_args (ffi_cif *cif, v } ffi_status -ffi_prep_java_raw_closure_loc (ffi_raw_closure* cl, +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data, void *codeloc) { @@ -335,9 +345,9 @@ ffi_prep_java_raw_closure_loc (ffi_raw_c * the pointer-array format, to the raw format */ ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure* cl, +ffi_prep_java_raw_closure (ffi_java_raw_closure* cl, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data) { return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl); Index: libffi/src/mips/ffitarget.h =================================================================== --- libffi/src/mips/ffitarget.h (revision 130154) +++ libffi/src/mips/ffitarget.h (working copy) @@ -42,10 +42,13 @@ #ifdef FFI_MIPS_O32 /* O32 stack frames have 32bit integer args */ -#define FFI_SIZEOF_ARG 4 +# define FFI_SIZEOF_ARG 4 #else /* N32 and N64 frames have 64bit integer args */ -#define FFI_SIZEOF_ARG 8 +# define FFI_SIZEOF_ARG 8 +# ifdef FFI_MIPS_N32 +# define FFI_SIZEOF_JAVA_RAW 4 +# endif #endif #define FFI_FLAG_BITS 2 Index: libjava/interpret.cc =================================================================== --- libjava/interpret.cc (revision 130154) +++ libjava/interpret.cc (working copy) @@ -346,7 +346,7 @@ get4 (unsigned char* loc) void _Jv_InterpMethod::run_normal (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -356,7 +356,7 @@ _Jv_InterpMethod::run_normal (ffi_cif *, void _Jv_InterpMethod::run_normal_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -366,7 +366,7 @@ _Jv_InterpMethod::run_normal_debug (ffi_ void _Jv_InterpMethod::run_synch_object (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -380,7 +380,7 @@ _Jv_InterpMethod::run_synch_object (ffi_ void _Jv_InterpMethod::run_synch_object_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -394,7 +394,7 @@ _Jv_InterpMethod::run_synch_object_debug void _Jv_InterpMethod::run_class (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -405,7 +405,7 @@ _Jv_InterpMethod::run_class (ffi_cif *, void _Jv_InterpMethod::run_class_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -416,7 +416,7 @@ _Jv_InterpMethod::run_class_debug (ffi_c void _Jv_InterpMethod::run_synch_class (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -431,7 +431,7 @@ _Jv_InterpMethod::run_synch_class (ffi_c void _Jv_InterpMethod::run_synch_class_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -975,7 +975,8 @@ _Jv_InterpMethod::compile (const void * /* Run the given method. When args is NULL, don't run anything -- just compile it. */ void -_Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) +_Jv_InterpMethod::run (void *retp, INTERP_FFI_RAW_TYPE *args, + _Jv_InterpMethod *meth) { #undef DEBUG #undef DEBUG_LOCALS_INSN @@ -985,7 +986,8 @@ _Jv_InterpMethod::run (void *retp, ffi_r } void -_Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) +_Jv_InterpMethod::run_debug (void *retp, INTERP_FFI_RAW_TYPE *args, + _Jv_InterpMethod *meth) { #define DEBUG #undef DEBUG_LOCALS_INSN @@ -1306,27 +1308,32 @@ _Jv_init_cif (_Jv_Utf8Const* signature, return item_count; } -#if FFI_NATIVE_RAW_API -# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc -# define FFI_RAW_SIZE ffi_raw_size -#else -# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc -# define FFI_RAW_SIZE ffi_java_raw_size -#endif - /* we put this one here, and not in interpret.cc because it * calls the utility routines _Jv_count_arguments * which are static to this module. The following struct defines the * layout we use for the stubs, it's only used in the ncode method. */ +#if FFI_NATIVE_RAW_API +# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc +# define FFI_RAW_SIZE ffi_raw_size typedef struct { ffi_raw_closure closure; _Jv_ClosureList list; ffi_cif cif; ffi_type *arg_types[0]; } ncode_closure; - -typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*); +typedef void (*ffi_closure_fun) (ffi_cif*,void*,INTERP_FFI_RAW_TYPE*,void*); +#else +# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc +# define FFI_RAW_SIZE ffi_java_raw_size +typedef struct { + ffi_java_raw_closure closure; + _Jv_ClosureList list; + ffi_cif cif; + ffi_type *arg_types[0]; +} ncode_closure; +typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_java_raw*,void*); +#endif void * _Jv_InterpMethod::ncode (jclass klass) Index: libjava/include/java-interp.h =================================================================== --- libjava/include/java-interp.h (revision 130154) +++ libjava/include/java-interp.h (working copy) @@ -222,18 +222,26 @@ class _Jv_InterpMethod : public _Jv_Meth void *ncode (jclass); void compile (const void * const *); - static void run_normal (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_object (ffi_cif*, void*, ffi_raw*, void*); - static void run_class (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_class (ffi_cif*, void*, ffi_raw*, void*); - - static void run_normal_debug (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_object_debug (ffi_cif*, void*, ffi_raw*, void*); - static void run_class_debug (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_class_debug (ffi_cif*, void*, ffi_raw*, void*); +#if FFI_NATIVE_RAW_API +# define INTERP_FFI_RAW_TYPE ffi_raw +#else +# define INTERP_FFI_RAW_TYPE ffi_java_raw +#endif + + static void run_normal (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_object (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + + static void run_normal_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_object_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, + void*); + static void run_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, + void*); - static void run (void *, ffi_raw *, _Jv_InterpMethod *); - static void run_debug (void *, ffi_raw *, _Jv_InterpMethod *); + static void run (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *); + static void run_debug (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *); @@ -361,7 +369,7 @@ class _Jv_JNIMethod : public _Jv_MethodB ffi_type **jni_arg_types; // This function is used when making a JNI call from the interpreter. - static void call (ffi_cif *, void *, ffi_raw *, void *); + static void call (ffi_cif *, void *, INTERP_FFI_RAW_TYPE *, void *); void *ncode (jclass); Index: libjava/jni.cc =================================================================== --- libjava/jni.cc (revision 130154) +++ libjava/jni.cc (working copy) @@ -2293,7 +2293,8 @@ _Jv_LookupJNIMethod (jclass klass, _Jv_U // This function is the stub which is used to turn an ordinary (CNI) // method call into a JNI call. void -_Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this) +_Jv_JNIMethod::call (ffi_cif *, void *ret, INTERP_FFI_RAW_TYPE *args, + void *__this) { _Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this; @@ -2325,8 +2326,9 @@ _Jv_JNIMethod::call (ffi_cif *, void *re } } - JvAssert (_this->args_raw_size % sizeof (ffi_raw) == 0); - ffi_raw real_args[2 + _this->args_raw_size / sizeof (ffi_raw)]; + JvAssert (_this->args_raw_size % sizeof (INTERP_FFI_RAW_TYPE) == 0); + INTERP_FFI_RAW_TYPE + real_args[2 + _this->args_raw_size / sizeof (INTERP_FFI_RAW_TYPE)]; int offset = 0; // First argument is always the environment pointer. Index: libjava/interpret-run.cc =================================================================== --- libjava/interpret-run.cc (revision 130154) +++ libjava/interpret-run.cc (working copy) @@ -576,7 +576,7 @@ details. */ { /* here goes the magic again... */ ffi_cif *cif = &rmeth->cif; - ffi_raw *raw = (ffi_raw*) sp; + INTERP_FFI_RAW_TYPE *raw = (INTERP_FFI_RAW_TYPE *) sp; _Jv_value rvalue; ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch] libffi: Fixes for MIPS n32 ABI. 2007-12-03 18:56 ` David Daney @ 2007-12-03 19:16 ` Andrew Haley 2007-12-06 22:39 ` David Daney 0 siblings, 1 reply; 7+ messages in thread From: Andrew Haley @ 2007-12-03 19:16 UTC (permalink / raw) To: David Daney; +Cc: Java Patches, gcc-patches, rsandifo David Daney writes: > > 2007-12-3 David Daney <ddaney@avtrex.com> > > * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already > defined. > (ffi_java_raw): New typedef. > (ffi_java_raw_call, ffi_java_ptrarray_to_raw, > ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to > ffi_java_raw. > (ffi_java_raw_closure) : Same. > (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change > parameter types. > * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with > FFI_SIZEOF_JAVA_RAW. > (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. > Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use > sizeof(ffi_java_raw) for alignment calculations. > (ffi_java_ptrarray_to_raw): Same. > (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER > if FFI_SIZEOF_JAVA_RAW == 4. > (ffi_java_raw_to_rvalue): Same. > (ffi_java_raw_call): Change type of raw to ffi_java_raw. > (ffi_java_translate_args): Same. > (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change > parameter types. > * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. > > 2007-12-3 David Daney <ddaney@avtrex.com> > > * interpret.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE throughout. > (ncode_closure, ffi_closure_fun): Define versions for > non-FFI_NATIVE_RAW_API case. > * include/java-interp.h (INTERP_FFI_RAW_TYPE): Define and use to > replace ffi_raw throughout. > * jni.cc, interpret-run.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE > throughout. OK. Andrew. -- Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SL4 1TE, UK Registered in England and Wales No. 3798903 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Patch] libffi: Fixes for MIPS n32 ABI. 2007-12-03 19:16 ` Andrew Haley @ 2007-12-06 22:39 ` David Daney 0 siblings, 0 replies; 7+ messages in thread From: David Daney @ 2007-12-06 22:39 UTC (permalink / raw) To: Java Patches; +Cc: Andrew Haley, gcc-patches, rsandifo [-- Attachment #1: Type: text/plain, Size: 3485 bytes --] Andrew Haley wrote: > David Daney writes: > > > > > 2007-12-3 David Daney <ddaney@avtrex.com> > > > > * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already > > defined. > > (ffi_java_raw): New typedef. > > (ffi_java_raw_call, ffi_java_ptrarray_to_raw, > > ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to > > ffi_java_raw. > > (ffi_java_raw_closure) : Same. > > (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change > > parameter types. > > * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with > > FFI_SIZEOF_JAVA_RAW. > > (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. > > Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use > > sizeof(ffi_java_raw) for alignment calculations. > > (ffi_java_ptrarray_to_raw): Same. > > (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER > > if FFI_SIZEOF_JAVA_RAW == 4. > > (ffi_java_raw_to_rvalue): Same. > > (ffi_java_raw_call): Change type of raw to ffi_java_raw. > > (ffi_java_translate_args): Same. > > (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change > > parameter types. > > * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. > > > > 2007-12-3 David Daney <ddaney@avtrex.com> > > > > * interpret.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE throughout. > > (ncode_closure, ffi_closure_fun): Define versions for > > non-FFI_NATIVE_RAW_API case. > > * include/java-interp.h (INTERP_FFI_RAW_TYPE): Define and use to > > replace ffi_raw throughout. > > * jni.cc, interpret-run.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE > > throughout. > > OK. > > This is the version I actually committed. The original patch used the wrong test for n32 ABI and had a couple of code formatting issues. 2007-12-06 David Daney <ddaney@avtrex.com> * include/ffi.h.in (FFI_SIZEOF_JAVA_RAW): Define if not already defined. (ffi_java_raw): New typedef. (ffi_java_raw_call, ffi_java_ptrarray_to_raw, ffi_java_raw_to_ptrarray): Change parameter types from ffi_raw to ffi_java_raw. (ffi_java_raw_closure) : Same. (ffi_prep_java_raw_closure, ffi_prep_java_raw_closure_loc): Change parameter types. * src/java_raw_api.c (ffi_java_raw_size): Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. (ffi_java_raw_to_ptrarray): Change type of raw to ffi_java_raw. Replace FFI_SIZEOF_ARG with FFI_SIZEOF_JAVA_RAW. Use sizeof(ffi_java_raw) for alignment calculations. (ffi_java_ptrarray_to_raw): Same. (ffi_java_rvalue_to_raw): Add special handling for FFI_TYPE_POINTER if FFI_SIZEOF_JAVA_RAW == 4. (ffi_java_raw_to_rvalue): Same. (ffi_java_raw_call): Change type of raw to ffi_java_raw. (ffi_java_translate_args): Same. (ffi_prep_java_raw_closure_loc, ffi_prep_java_raw_closure): Change parameter types. * src/mips/ffitarget.h (FFI_SIZEOF_JAVA_RAW): Define for N32 ABI. 2007-12-06 David Daney <ddaney@avtrex.com> * interpret.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE throughout. (ncode_closure, ffi_closure_fun): Define versions for non-FFI_NATIVE_RAW_API case. * include/java-interp.h (INTERP_FFI_RAW_TYPE): Define and use to replace ffi_raw throughout. * jni.cc, interpret-run.cc: Replace ffi_raw with INTERP_FFI_RAW_TYPE throughout. [-- Attachment #2: ffi-1.diff --] [-- Type: text/x-patch, Size: 16717 bytes --] Index: libffi/include/ffi.h.in =================================================================== --- libffi/include/ffi.h.in (revision 130154) +++ libffi/include/ffi.h.in (working copy) @@ -193,6 +193,10 @@ typedef struct { # endif #endif +#ifndef FFI_SIZEOF_JAVA_RAW +# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG +#endif + typedef union { ffi_sarg sint; ffi_arg uint; @@ -201,6 +205,21 @@ typedef union { void* ptr; } ffi_raw; +#if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8 +/* This is a special case for mips64/n32 ABI (and perhaps others) where + sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */ +typedef union { + signed int sint; + unsigned int uint; + float flt; + char data[FFI_SIZEOF_JAVA_RAW]; + void* ptr; +} ffi_java_raw; +#else +typedef ffi_raw ffi_java_raw; +#endif + + void ffi_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, @@ -217,10 +236,10 @@ size_t ffi_raw_size (ffi_cif *cif); void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, - ffi_raw *avalue); + ffi_java_raw *avalue); -void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); -void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); +void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw); +void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args); size_t ffi_java_raw_size (ffi_cif *cif); /* ---- Definitions for closures ----------------------------------------- */ @@ -271,6 +290,27 @@ typedef struct { } ffi_raw_closure; +typedef struct { + char tramp[FFI_TRAMPOLINE_SIZE]; + + ffi_cif *cif; + +#if !FFI_NATIVE_RAW_API + + /* if this is enabled, then a raw closure has the same layout + as a regular closure. We use this to install an intermediate + handler to do the transaltion, void** -> ffi_raw*. */ + + void (*translate_args)(ffi_cif*,void*,void**,void*); + void *this_closure; + +#endif + + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*); + void *user_data; + +} ffi_java_raw_closure; + ffi_status ffi_prep_raw_closure (ffi_raw_closure*, ffi_cif *cif, @@ -285,15 +325,15 @@ ffi_prep_raw_closure_loc (ffi_raw_closur void *codeloc); ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure*, +ffi_prep_java_raw_closure (ffi_java_raw_closure*, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data); ffi_status -ffi_prep_java_raw_closure_loc (ffi_raw_closure*, +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data, void *codeloc); Index: libffi/src/java_raw_api.c =================================================================== --- libffi/src/java_raw_api.c (revision 130154) +++ libffi/src/java_raw_api.c (working copy) @@ -54,13 +54,13 @@ ffi_java_raw_size (ffi_cif *cif) case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: - result += 2 * FFI_SIZEOF_ARG; + result += 2 * FFI_SIZEOF_JAVA_RAW; break; case FFI_TYPE_STRUCT: /* No structure parameters in Java. */ abort(); default: - result += FFI_SIZEOF_ARG; + result += FFI_SIZEOF_JAVA_RAW; } } @@ -69,7 +69,7 @@ ffi_java_raw_size (ffi_cif *cif) void -ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) +ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args) { unsigned i; ffi_type **tp = cif->arg_types; @@ -90,7 +90,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, *args = (void*) ((char*)(raw++) + 2); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -105,7 +105,8 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, default: *args = raw; - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); } } @@ -116,7 +117,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, /* then assume little endian */ for (i = 0; i < cif->nargs; i++, tp++, args++) { -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 switch((*tp)->type) { case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: @@ -127,10 +128,11 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, default: *args = (void*) raw++; } -#else /* FFI_SIZEOF_ARG != 8 */ +#else /* FFI_SIZEOF_JAVA_RAW != 8 */ *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); -#endif /* FFI_SIZEOF_ARG == 8 */ + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); +#endif /* FFI_SIZEOF_JAVA_RAW == 8 */ } #else @@ -141,7 +143,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, } void -ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) +ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw) { unsigned i; ffi_type **tp = cif->arg_types; @@ -202,7 +204,7 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, (raw++)->flt = *(FLOAT32*) (*args); break; -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 case FFI_TYPE_UINT64: case FFI_TYPE_SINT64: case FFI_TYPE_DOUBLE: @@ -216,11 +218,12 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, break; default: -#if FFI_SIZEOF_ARG == 8 +#if FFI_SIZEOF_JAVA_RAW == 8 FFI_ASSERT(0); /* Should have covered all cases */ #else memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; + raw += + ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw); #endif } } @@ -244,6 +247,9 @@ ffi_java_rvalue_to_raw (ffi_cif *cif, vo case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue <<= 32; break; @@ -269,6 +275,9 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, vo case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: case FFI_TYPE_INT: +#if FFI_SIZEOF_JAVA_RAW == 4 + case FFI_TYPE_POINTER: +#endif *(SINT64 *)rvalue >>= 32; break; @@ -285,7 +294,8 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, vo * these following couple of functions will handle the translation forth * and back automatically. */ -void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw) +void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, + ffi_java_raw *raw) { void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); ffi_java_raw_to_ptrarray (cif, raw, avalue); @@ -299,7 +309,7 @@ static void ffi_java_translate_args (ffi_cif *cif, void *rvalue, void **avalue, void *user_data) { - ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif)); + ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif)); ffi_raw_closure *cl = (ffi_raw_closure*)user_data; ffi_java_ptrarray_to_raw (cif, avalue, raw); @@ -308,9 +318,9 @@ ffi_java_translate_args (ffi_cif *cif, v } ffi_status -ffi_prep_java_raw_closure_loc (ffi_raw_closure* cl, +ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data, void *codeloc) { @@ -335,9 +345,9 @@ ffi_prep_java_raw_closure_loc (ffi_raw_c * the pointer-array format, to the raw format */ ffi_status -ffi_prep_java_raw_closure (ffi_raw_closure* cl, +ffi_prep_java_raw_closure (ffi_java_raw_closure* cl, ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), + void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*), void *user_data) { return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl); Index: libffi/src/mips/ffitarget.h =================================================================== --- libffi/src/mips/ffitarget.h (revision 130154) +++ libffi/src/mips/ffitarget.h (working copy) @@ -42,10 +42,13 @@ #ifdef FFI_MIPS_O32 /* O32 stack frames have 32bit integer args */ -#define FFI_SIZEOF_ARG 4 +# define FFI_SIZEOF_ARG 4 #else /* N32 and N64 frames have 64bit integer args */ -#define FFI_SIZEOF_ARG 8 +# define FFI_SIZEOF_ARG 8 +# if _MIPS_SIM == _ABIN32 +# define FFI_SIZEOF_JAVA_RAW 4 +# endif #endif #define FFI_FLAG_BITS 2 Index: libjava/interpret.cc =================================================================== --- libjava/interpret.cc (revision 130154) +++ libjava/interpret.cc (working copy) @@ -346,7 +346,7 @@ get4 (unsigned char* loc) void _Jv_InterpMethod::run_normal (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -356,7 +356,7 @@ _Jv_InterpMethod::run_normal (ffi_cif *, void _Jv_InterpMethod::run_normal_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -366,7 +366,7 @@ _Jv_InterpMethod::run_normal_debug (ffi_ void _Jv_InterpMethod::run_synch_object (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -380,7 +380,7 @@ _Jv_InterpMethod::run_synch_object (ffi_ void _Jv_InterpMethod::run_synch_object_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -394,7 +394,7 @@ _Jv_InterpMethod::run_synch_object_debug void _Jv_InterpMethod::run_class (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -405,7 +405,7 @@ _Jv_InterpMethod::run_class (ffi_cif *, void _Jv_InterpMethod::run_class_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -416,7 +416,7 @@ _Jv_InterpMethod::run_class_debug (ffi_c void _Jv_InterpMethod::run_synch_class (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -431,7 +431,7 @@ _Jv_InterpMethod::run_synch_class (ffi_c void _Jv_InterpMethod::run_synch_class_debug (ffi_cif *, void *ret, - ffi_raw *args, + INTERP_FFI_RAW_TYPE *args, void *__this) { _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this; @@ -975,7 +975,8 @@ _Jv_InterpMethod::compile (const void * /* Run the given method. When args is NULL, don't run anything -- just compile it. */ void -_Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) +_Jv_InterpMethod::run (void *retp, INTERP_FFI_RAW_TYPE *args, + _Jv_InterpMethod *meth) { #undef DEBUG #undef DEBUG_LOCALS_INSN @@ -985,7 +986,8 @@ _Jv_InterpMethod::run (void *retp, ffi_r } void -_Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth) +_Jv_InterpMethod::run_debug (void *retp, INTERP_FFI_RAW_TYPE *args, + _Jv_InterpMethod *meth) { #define DEBUG #undef DEBUG_LOCALS_INSN @@ -1306,27 +1308,32 @@ _Jv_init_cif (_Jv_Utf8Const* signature, return item_count; } -#if FFI_NATIVE_RAW_API -# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc -# define FFI_RAW_SIZE ffi_raw_size -#else -# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc -# define FFI_RAW_SIZE ffi_java_raw_size -#endif - /* we put this one here, and not in interpret.cc because it * calls the utility routines _Jv_count_arguments * which are static to this module. The following struct defines the * layout we use for the stubs, it's only used in the ncode method. */ +#if FFI_NATIVE_RAW_API +# define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc +# define FFI_RAW_SIZE ffi_raw_size typedef struct { ffi_raw_closure closure; _Jv_ClosureList list; ffi_cif cif; ffi_type *arg_types[0]; } ncode_closure; - -typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*); +typedef void (*ffi_closure_fun) (ffi_cif*,void*,INTERP_FFI_RAW_TYPE*,void*); +#else +# define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc +# define FFI_RAW_SIZE ffi_java_raw_size +typedef struct { + ffi_java_raw_closure closure; + _Jv_ClosureList list; + ffi_cif cif; + ffi_type *arg_types[0]; +} ncode_closure; +typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_java_raw*,void*); +#endif void * _Jv_InterpMethod::ncode (jclass klass) Index: libjava/include/java-interp.h =================================================================== --- libjava/include/java-interp.h (revision 130154) +++ libjava/include/java-interp.h (working copy) @@ -222,18 +222,26 @@ class _Jv_InterpMethod : public _Jv_Meth void *ncode (jclass); void compile (const void * const *); - static void run_normal (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_object (ffi_cif*, void*, ffi_raw*, void*); - static void run_class (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_class (ffi_cif*, void*, ffi_raw*, void*); - - static void run_normal_debug (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_object_debug (ffi_cif*, void*, ffi_raw*, void*); - static void run_class_debug (ffi_cif*, void*, ffi_raw*, void*); - static void run_synch_class_debug (ffi_cif*, void*, ffi_raw*, void*); +#if FFI_NATIVE_RAW_API +# define INTERP_FFI_RAW_TYPE ffi_raw +#else +# define INTERP_FFI_RAW_TYPE ffi_java_raw +#endif + + static void run_normal (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_object (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + + static void run_normal_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_object_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, + void*); + static void run_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*); + static void run_synch_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, + void*); - static void run (void *, ffi_raw *, _Jv_InterpMethod *); - static void run_debug (void *, ffi_raw *, _Jv_InterpMethod *); + static void run (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *); + static void run_debug (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *); @@ -361,7 +369,7 @@ class _Jv_JNIMethod : public _Jv_MethodB ffi_type **jni_arg_types; // This function is used when making a JNI call from the interpreter. - static void call (ffi_cif *, void *, ffi_raw *, void *); + static void call (ffi_cif *, void *, INTERP_FFI_RAW_TYPE *, void *); void *ncode (jclass); Index: libjava/jni.cc =================================================================== --- libjava/jni.cc (revision 130154) +++ libjava/jni.cc (working copy) @@ -2293,7 +2293,8 @@ _Jv_LookupJNIMethod (jclass klass, _Jv_U // This function is the stub which is used to turn an ordinary (CNI) // method call into a JNI call. void -_Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this) +_Jv_JNIMethod::call (ffi_cif *, void *ret, INTERP_FFI_RAW_TYPE *args, + void *__this) { _Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this; @@ -2325,8 +2326,9 @@ _Jv_JNIMethod::call (ffi_cif *, void *re } } - JvAssert (_this->args_raw_size % sizeof (ffi_raw) == 0); - ffi_raw real_args[2 + _this->args_raw_size / sizeof (ffi_raw)]; + JvAssert (_this->args_raw_size % sizeof (INTERP_FFI_RAW_TYPE) == 0); + INTERP_FFI_RAW_TYPE + real_args[2 + _this->args_raw_size / sizeof (INTERP_FFI_RAW_TYPE)]; int offset = 0; // First argument is always the environment pointer. Index: libjava/interpret-run.cc =================================================================== --- libjava/interpret-run.cc (revision 130154) +++ libjava/interpret-run.cc (working copy) @@ -576,7 +576,7 @@ details. */ { /* here goes the magic again... */ ffi_cif *cif = &rmeth->cif; - ffi_raw *raw = (ffi_raw*) sp; + INTERP_FFI_RAW_TYPE *raw = (INTERP_FFI_RAW_TYPE *) sp; _Jv_value rvalue; ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2007-12-06 22:39 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-11-29 7:09 [Patch] libffi: Fixes for MIPS n32 ABI David Daney 2007-12-01 12:08 ` Richard Sandiford 2007-12-01 18:43 ` David Daney 2007-12-01 19:14 ` Richard Sandiford 2007-12-03 18:56 ` David Daney 2007-12-03 19:16 ` Andrew Haley 2007-12-06 22:39 ` David Daney
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).