Hi! Neil Jerram <[EMAIL PROTECTED]> writes:
> "Mikael Djurfeldt" <[EMAIL PROTECTED]> writes: > >> I was thinking about inserting code which actually *measures* the size >> of frames during startup. This could be done, for example, by >> introducing a primitive which uses the internal stack measuring >> functions. One could use this primitive to measure how much stack >> space some code sample uses. By our knowledge of how many evaluator >> stack frames this code sample uses, we can compute a reliable estimate >> for the running instance of Guile. > > Below is a proposed patch to do this. When and if this gets deployed, > the third arg to %calibrate-stack-depth would be removed, so that it > doesn't generate any output. But for now it's interesting to see what > results people on various OSs get. That's the second important thing that should go in 1.8.6 IMO. A few notes. > --- ice-9/boot-9.scm 1 Sep 2007 17:11:00 -0000 1.356.2.10 > +++ ice-9/boot-9.scm 25 Feb 2008 21:45:44 -0000 > @@ -2289,6 +2289,14 @@ > (print-options print-enable print-disable) > (print-set!))) > > +;;; Stack depth calibration, for the 'stack debug option. > + > +(let ((x (%get-stack-depth))) > + (let loop ((count 10)) > + (if (zero? count) > + (%calibrate-stack-depth x (%get-stack-depth) 'report) > + (cons count (loop (- count 1)))))) > + [...] > +SCM_DEFINE (scm_sys_calibrate_stack_depth, "%calibrate-stack-depth", 2, 1, 0, > + (SCM d1, SCM d2, SCM debugp), > + "Calibrate linear transformation for stack depth limit checking.") > +#define FUNC_NAME s_scm_sys_calibrate_stack_depth > +{ > + /* x1 and x2 are the stack depth values that we get on a Debian > + GNU/Linux ia32 system - which we take as our canonical system. > + y1 and y2 are the values measured on the system where Guile is > + currently running. */ > + int x1 = 170, x2 = 690, y1, y2; These results are dependent on what the loop in `boot-9.scm' does. Thus, it'd be nicer if they weren't that far away from it. It might be worth mentioning the GCC version and optimization level that led to this result. Also, `x1' and `x2' can be made "static const" or some such. > + SCM_VALIDATE_INT_COPY (1, d1, y1); > + SCM_VALIDATE_INT_COPY (2, d2, y2); > + > + calibrated_m = ((double) (y2 - y1)) / (x2 - x1); > + calibrated_c = ((double) y2) - calibrated_m * x2; Shouldn't it be: calibrated_c = y1 - x1; Also, the computation of `calibrated_m' needs more casts to `double' I think. > + if (scm_is_true (debugp) && !SCM_UNBNDP (debugp)) > + { > + scm_puts (";; Stack calibration: (x1 x2 y1 y2 m c) = ", > + scm_current_output_port ()); > + scm_write (scm_list_n (scm_from_int (x1), scm_from_int (x2), > + d1, d2, > + scm_from_double (calibrated_m), > + scm_from_double (calibrated_c), > + SCM_UNDEFINED), > + SCM_UNDEFINED); > + scm_newline (SCM_UNDEFINED); > + } Could it be moved to a `%print-stack-calibration' function that we'd use for troubleshooting? > +void > +scm_calculate_stack_limit () > +{ > + scm_stack_limit = (int) (calibrated_m * SCM_STACK_LIMIT + calibrated_c); > +} How about entirely removing the startup overhead by computing the calibration factors only once, at installation time? This would mean: 1. Compile all of Guile with the default calibration factors (m = 1 and c = 0). 2. Run a Scheme script that computes `m' and `c' and produces, say, `calibration.h', which is included by `stackchk.c'. Both the computation and the reference stack depths (`x1' and `x2' above) would live in this script, which is clearer IMO. 3. Invoke `make' recursively, which should rebuild libguile with the appropriate calibration factor (typically, only `stackchk.lo' would need to be recompiled). Would you like to do something like this? Also, the on-line and Texi documentation of `eval-options' must be updated to specify that the stack depth unit is "abstract" and (hopefully) portable across platforms. Thanks, Ludo'.