diff options
author | Miguel Sofer <miguel.sofer@gmail.com> | 2016-01-26 16:59:29 (GMT) |
---|---|---|
committer | Miguel Sofer <miguel.sofer@gmail.com> | 2016-01-26 16:59:29 (GMT) |
commit | 9a6a7e39980e6125f37e6d87520ebf213ad83a4b (patch) | |
tree | 2c115d40d7c8f932a9746448ac12354bde42e89b /generic/tclNRE.h | |
parent | 1acb0742e2003b2986c75a8f0967b7a7fdd5d661 (diff) | |
download | tcl-9a6a7e39980e6125f37e6d87520ebf213ad83a4b.zip tcl-9a6a7e39980e6125f37e6d87520ebf213ad83a4b.tar.gz tcl-9a6a7e39980e6125f37e6d87520ebf213ad83a4b.tar.bz2 |
using gcc's sibling call optimisation: calls between NRE_callbacks are optimised to tailcalls, also indirect calls
Diffstat (limited to 'generic/tclNRE.h')
-rw-r--r-- | generic/tclNRE.h | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/generic/tclNRE.h b/generic/tclNRE.h index ca8dd7f..c1df6d2 100644 --- a/generic/tclNRE.h +++ b/generic/tclNRE.h @@ -63,12 +63,25 @@ typedef struct NRE_stack { #define NEXT_CB(ptr) TclNextCallback(ptr) +#define NRE_TRAMPOLINE 0 +#if NRE_TRAMPOLINE +#define NRE_JUMP(interp,postProcPtr,data0,data1,data2,data3) \ + TclNRAddCallback((interp),(postProcPtr),(data0),(data1),(data2),(data3)); \ + NRE_NEXT(TCL_OK) #define NRE_NEXT(result) \ return (result) - +#else +/* no trampoline, optimized sibcalls */ #define NRE_JUMP(interp,postProcPtr,data0,data1,data2,data3) \ TclNRAddCallback((interp),(postProcPtr),(data0),(data1),(data2),(data3)); \ - NRE_NEXT(TCL_OK) + return TCL_OK +#define NRE_NEXT(result) \ + do { /* optimized indirect sibling calls?! */ \ + NRE_callback *cbPtr; \ + POP_CB(interp, cbPtr); \ + return (cbPtr->procPtr)(cbPtr->data, interp, result); \ + } while (0) +#endif MODULE_SCOPE TCL_NOINLINE NRE_callback *TclNewCallback(Tcl_Interp *interp); MODULE_SCOPE TCL_NOINLINE NRE_callback *TclPopCallback(Tcl_Interp *interp); |