This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] ifunc suck, use ufunc.


* Ond??ej B?lka <neleai@seznam.cz> [2015-05-24 23:38:58 +0200]:
> A main benefit would be interlibrary constant folding. Why waste cycles
> on reinitializing constant, just save it to ufunc structure. Resolver 
> then could precompute tables to improve speed.
> 
> As interposing these you would need to interpose resolver.
> 
> An gcc support is not needed but we could get something with alternate
> calling convention as passing resolver struct is common and could be
> preserved for loops with tail calls.
> 
> A future direction could be replace plt and linker with ufunc, it would
> require adding function string pointer to structure and calling first
> generic resolver to select specific resolver.
> 
> Comments?
> 

this makes memset non-async-signal-safe. (qoi issue)

it is not thread-safe either and would need an acquire
load barrier on every invocation of memset to fix that
or the use of thread local storage. (conformance issue)

(in the example only resolve->fn is modified and idempotently,
this would work in practice but as soon as ->data is accessed
too the memory ordering guarantees are required.. which can
be made efficient on some archs but only in asm)

in the example memset is called through the wrong type
of function pointer: the resolver and resolvee are
incompatible so this is invalid c, only works in asm.

it is not clear to me how many such ufunc structs will be
in a program for a specific function and how their redundant
initialization is avoided.
(one for every call site? every tu? every dso?)

> An simplified example is here (for arch that pass four arguments in registers):
> 
> struct memset_ufunc
> {
>   void *(*fn)(void *, int, size_t, struct memset_ufunc *);
>   char  __attribute__((aligned (32))) data[32];
> };
> # define memset(s, c, n) \
>    (__extension__({ \
>     static struct memset_ufunc __resolve = {.fn = memset_resolver}; \
>     __resolve.fn (s, c, n, &__resolve); \
>     }))
> 
> void *
> memset_resolver (void *s, int c, size_t n, struct memset_ufunc *resolve)
> {
>   resolve->fn = dlsym (RTLD_DEFAULT, "memset");
>   return resolve->fn (s, c, n, resolve);
> }
> 
> void foo (char *c);
> int main ()
> {
>   char u[32];
>   memset (u, 1, 32);
> }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]