[M3devel] elimination of jmpbuf size from cm3 frontend?

Jay K jay.krell at cornell.edu
Sun Jul 19 00:17:03 CEST 2015

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.

 Thanks, - Jay

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20150718/6b1c1349/attachment-0001.html>

More information about the M3devel mailing list