[M3devel] elimination of jmpbuf size from cm3 frontend?
hendrik at topoi.pooq.com
Sun Jul 19 01:21:40 CEST 2015
On Sat, Jul 18, 2015 at 10:17:03PM +0000, Jay K wrote:
> I want to eliminate the knowledge of jmpbuf size from the frontend.This is an old goal that I failed at previously.
> I believe I need to:
> Extend M3.CheckState to include jmpbuf_count. The various Try*.m3.Check increment it and store its previous value in the statement's state. And then a few choices. 1) At the start of a function, call alloca with that count times external variable jmpbuf_size, initialized in C.
> At each try, multiply its index by external variable jmpbuf_size and add to the start of the buffer and use that. or also have an array of n pointers filled in by C and index into that, eliminating the runtime non-const multiplication and/or
> include that array in the alloca even having a "composite" not called simply "alloca" but "m3_alloc_jmpbufs", which backends still have to special case to look kinda the same, alloca being very special
> add to functions themselves a notion of jmpbuf count, still the same underlying mechanism..
> and/or also add a m3cg primitive "jmpbuf_ref(n)", which gets the address of the n'th jmpbuf of the current function, i.e. building in the multiplication by jmpbuf size.
> Note that some of these combinations of proposals imply an m3cg change. All require at least a minimum of backend cooperation -- at least recognizing "m3_alloca" as "alloca" or "_alloca" or "builtin_alloca" or such.
> Note that hopefully/ideally there is a much higher level way to do this, whose design currently eludes me, something that a backend could translate to setjmp/longjmp, or Win32 C __try, or C++ try, or something. The "lowering" of try/finally in the frontend is portable but very inefficient.
> Another solution is for the function to have an n-array of pointers or merely n locals, initialized to null, and have each TRY dynamically call alloca if the pointer isn't null.
> This reduces stack use for the case of IF...TRY.
> At the cost of extra initialization and the test and branch.
> This is currently my favorite proposal so I should restate: have a local pointer for each TRY; initialized to null; at each TRY, if the pointer is null, call alloca(external jmpbuf_size). TRY is already super expensive in code size and speed. This solution adds a pointer per TRY and a test and conditional jmp. Multiplication is avoided. IF...TRY ends up using much less stack than before, if not executed, but most code will pay extra stack, a pointer per TRY. What I was missing before is that I need to extend M3.CheckState to count the jmpbufs and do some of the work at the start of the function, not merely at each TRY -- declare, and more importantly, initialize the pointers.
Unless things have changed recently, alloca() is not standard.
see the discussion and links in http://c-faq.com/malloc/alloca.html
That page also contains the sentence
Now that C99 supports variable-length arrays (VLA's), they can be used to more cleanly accomplish most of the tasks which alloca used to be put to.
Not clear at aall if the VLA's can be used for this.
> Thanks, - Jay
> M3devel mailing list
> M3devel at elegosoft.com
More information about the M3devel