On Fri, 2013-10-04 at 15:00 +0000, Joseph S. Myers wrote: > On Thu, 3 Oct 2013, David Malcolm wrote: > > > Right now all you get back from the result is a "void*" which you're > > meant to cast to machine code for the CPU. I guess we could add an > > And right now the library is calling dlopen. Which means that although > what the user gets is a void *, the dynamic linker processing has dealt > with registering eh_frame information and the right hooks have been passed > through for GDB to see that an object has been loaded and access its debug > information. Is this use of dlopen intended to be part of the interface, > or just a temporary hack with users eventually needing to use other > interfaces for eh_frame and debug info handling? (GDB has some support > for JITs, but I haven't looked into the details of how it works.)
The use of dlopen does indeed lead to a nice user-experience within gdb; my plan (vague at this stage) is that by enabling the flag GCC_JIT_BOOL_OPTION_DEBUGINFO on the gcc_jit_context that the client is asking the library to "do the right thing" to integrate the generated code with a debugger. Right now that's implemented using the dlopen hack (and by setting -g), but potentially we could implement it in other ways. There are other behaviors due to using dlopen: if you JIT-compile a function, that function can then be accessed by name from other code within the process using dlsym. That could be useful, perhaps, or could be just weird - perhaps the kludge should be using RTLD_LOCAL so that symbols are only accessible through the gcc_jit_result object, and don't pollute the dlsym namespace within the process (though using the term "pollute" there is perhaps a value-judgment) - not sure. > > option on the gcc_jit_context for setting which ISA you want code for. > > Even apart from completely separate ISAs, there's also the matter of other > command-line options such as -march=, which I'd think users should be able > to specify. And the complication that default options to cc1 can be > determined by specs, whether in .h files or from configure options such as > --with=arch=, so cc1's defaults may not be the same as the defaults when > you run the driver (which are likely to be better defaults for the JIT > than cc1's). And if the user wants to use -march=native (which seems > sensible for the common use case of a JIT, generating code for the same > system as runs the compiler), that's handled through specs. > > Maybe the driver should be converted to library code so it's possible to > run command-line options through it and generate the command line that > would get passed to cc1 (but then use that to call a function in the same > process - with a different copy of global options data, diagnostic context > etc. to avoid any issues from those being initialized twice - rather than > running a subprocess). That would also allow generating the right options > for the assembler to pass to the library version of the assembler. I like these ideas - if nothing else, having the driver as a library would enable me to get rid of one of the fork&exec pairs in my kludge. > > > > * There are some grotesque kludges in internal-api.c, especially in > > > > how we go from .s assembler files to a DSO (grep for "gross hack" ;) ) > > > > > > Apart from making the assembler into a shared library itself, it would > > > also be nice to avoid needing those files at all (via an API for writing > > > assembler text that doesn't depend on a FILE * pointer, although on GNU > > > hosts you can always use in-memory files via open_memstream, which would > > > make the internal changes much smaller). But in the absence of such a > > > cleanup, running the assembler via the driver should work, although > > > inefficient. > > > > (nods) Note that all of the kludgery (if that's a word) is hidden > > inside the library, so we can fix it all up without affecting client > > code: the client-facing API doesn't expose any of this. > > > > FWIW I added timevars for measuring the invocation of the driver; that > > kludge makes up about 50% of the overall time taken. I haven't yet > > broken that down into assembler vs linker vs fork/exec overhead, but > > clearly this is something that could use optimization - leading to > > (very) vague thoughts involving turning parts of binutils into libraries > > also. > > First I guess it might simply be a library that receives blocks of text > that currently go to asm_out_file - but eventually there might be > efficiency to be gained by passing binary data to the assembler in some > cases (e.g. for large blocks of debug info) rather than generating and > then parsing text. (So some asm_out methods would gain implementations > passing such data instead of generating text.) Agreed - though I think this is something of a version 2 thing, in that this is an optimization, and a decidedly non-trivial one (converting binutils into a library, then embedding it). Thanks for the great ideas. Dave