diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 9d0b16109..b016cc395 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,24 @@ +2003-09-14 Dirk Herrmann + + * tags.h: Reduced the number of short instructions from 14 to 13. + The typecode of the former 14th short instruction is now used to + represent long instructions. Changed some comments to reflect + this fact. + + (SCM_MAKISYM): ISYMs get a new tc7 code, namely the one that was + previously used by SCM_IM_DEFINE. + + (SCM_IM_DEFINE): Turned into a long instruction. + + * eval.c (unmemocopy, SCM_CEVAL): Treat SCM_IM_DEFINE as a long + instruction. + + * eval.c (SCM_CEVAL): Since characters and iflags have now a tc7 + code that is separate from all instructions, one level of dispatch + for long instructions can be eliminated. + + * print.c (scm_isymnames): Removed some commented code. + 2003-09-12 Marius Vollmer * __scm.h (SCM_FENCE): Use __memory_barrier with the Intel diff --git a/libguile/eval.c b/libguile/eval.c index e84ac23f9..f4ea80630 100644 --- a/libguile/eval.c +++ b/libguile/eval.c @@ -1618,25 +1618,23 @@ unmemocopy (SCM x, SCM env) case SCM_BIT7 (SCM_IM_SET_X): ls = z = scm_cons (scm_sym_set_x, SCM_UNSPECIFIED); break; - case SCM_BIT7 (SCM_IM_DEFINE): - { - SCM n; - x = SCM_CDR (x); - n = SCM_CAR (x); - z = scm_cons (n, SCM_UNSPECIFIED); - ls = scm_cons (scm_sym_define, z); - if (!SCM_NULLP (env)) - env = scm_cons (scm_cons (scm_cons (n, SCM_CAAR (env)), - SCM_CDAR (env)), - SCM_CDR (env)); - break; - } case SCM_BIT7 (SCM_MAKISYM (0)): z = SCM_CAR (x); - if (!SCM_ISYMP (z)) - goto unmemo; switch (SCM_ISYMNUM (z)) { + case (SCM_ISYMNUM (SCM_IM_DEFINE)): + { + SCM n; + x = SCM_CDR (x); + n = SCM_CAR (x); + z = scm_cons (n, SCM_UNSPECIFIED); + ls = scm_cons (scm_sym_define, z); + if (!SCM_NULLP (env)) + env = scm_cons (scm_cons (scm_cons (n, SCM_CAAR (env)), + SCM_CDAR (env)), + SCM_CDR (env)); + break; + } case (SCM_ISYMNUM (SCM_IM_APPLY)): ls = z = scm_cons (scm_sym_atapply, SCM_UNSPECIFIED); goto loop; @@ -1657,7 +1655,6 @@ unmemocopy (SCM x, SCM env) default: /* appease the Sun compiler god: */ ; } - unmemo: default: ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env), SCM_UNSPECIFIED), @@ -2441,20 +2438,23 @@ dispatch: RETURN (SCM_UNSPECIFIED); - case SCM_BIT7 (SCM_IM_DEFINE): /* only for internal defines */ - scm_misc_error (NULL, "Bad define placement", SCM_EOL); - - /* new syntactic forms go here. */ case SCM_BIT7 (SCM_MAKISYM (0)): proc = SCM_CAR (x); - if (!SCM_ISYMP (proc)) - goto evapply; - switch (SCM_ISYMNUM (proc)) { + case (SCM_ISYMNUM (SCM_IM_DEFINE)): + /* Top level defines are handled directly by the memoizer and thus + * will never generate memoized code with SCM_IM_DEFINE. Internal + * defines which occur at valid positions will be transformed into + * letrec expressions. Thus, whenever the executor detects + * SCM_IM_DEFINE, this must come from an internal definition at an + * illegal position. */ + scm_misc_error (NULL, "Bad define placement", SCM_EOL); + + case (SCM_ISYMNUM (SCM_IM_APPLY)): x = SCM_CDR (x); proc = EVALCAR (x, env); diff --git a/libguile/print.c b/libguile/print.c index e2544be93..af297941d 100644 --- a/libguile/print.c +++ b/libguile/print.c @@ -66,10 +66,6 @@ char *scm_isymnames[] = "#@quote", "#@set!", "#@define", -#if 0 - "#@literal-variable-ref", - "#@literal-variable-set!", -#endif "#@apply", "#@call-with-current-continuation", diff --git a/libguile/tags.h b/libguile/tags.h index 8cc293f67..4aa8764e7 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -309,18 +309,17 @@ typedef unsigned long scm_t_bits; * subdivision is of interest are the ones with tc3==100. * * tc7, tc8, tc9 (for objects with tc3==100): - * xx-0000-100: \ evaluator byte codes ('short instructions'). The byte + * 00-0000-100: \ evaluator byte codes ('short instructions'). The byte * ... } code interpreter can dispatch on them in one step based - * xx-1101-100: / on their tc7 value. - * 00-1110-100: evaluator byte codes ('long instructions'). The byte code - * interpreter needs to dispatch on them in three steps: - * The first dispatch is based on the tc7-code. The second - * dispatch checks for tc9==00-1110-100. The third dispatch - * is based on the actual byte code that is extracted from the - * upper bits. + * 00-1100-100: / on their tc7 value. + * 00-1101-100: evaluator byte codes ('long instructions'). The byte code + * interpreter needs to dispatch on them in two steps: The + * first dispatch is based on the tc7-code. The second + * dispatch is based on the actual byte code that is extracted + * from the upper bits. * x1-1110-100: characters with x as their least significant bit * 10-1110-100: various constants ('flags') - * xx-1111-100: evaluator byte codes ('ilocs') + * x1-1111-100: evaluator byte codes ('ilocs') * * * Summary of type codes on the heap @@ -515,18 +514,24 @@ enum scm_tags #define SCM_ISYMNUM(n) (SCM_UNPACK (n) >> 9) #define SCM_ISYMCHARS(n) (scm_isymnames[SCM_ISYMNUM (n)]) #define SCM_MAKSPCSYM(n) SCM_PACK (((n) << 9) + ((n) << 3) + 4L) -#define SCM_MAKISYM(n) SCM_PACK (((n) << 9) + 0x74L) +#define SCM_MAKISYM(n) SCM_PACK (((n) << 9) + 0x6cL) #define SCM_MAKIFLAG(n) SCM_PACK (((n) << 9) + 0x174L) SCM_API char *scm_isymnames[]; /* defined in print.c */ /* This table must agree with the declarations - * in repl.c: {Names of immediate symbols}. + * in print.c: {Names of immediate symbols}. * * These are used only in eval but their values * have to be allocated here. */ +/* Evaluator bytecodes (short instructions): These are uniquely identified by + * their tc7 value. This makes it possible for the evaluator to dispatch on + * them in one step. However, the type system allows for at most 13 short + * instructions. Consequently, the most frequent instructions are chosen to + * be represented as short instructions. */ + #define SCM_IM_AND SCM_MAKSPCSYM (0) #define SCM_IM_BEGIN SCM_MAKSPCSYM (1) #define SCM_IM_CASE SCM_MAKSPCSYM (2) @@ -540,7 +545,17 @@ SCM_API char *scm_isymnames[]; /* defined in print.c */ #define SCM_IM_OR SCM_MAKSPCSYM (10) #define SCM_IM_QUOTE SCM_MAKSPCSYM (11) #define SCM_IM_SET_X SCM_MAKSPCSYM (12) -#define SCM_IM_DEFINE SCM_MAKSPCSYM (13) + +/* Evaluator bytecodes (long instructions): All these share a common tc7 + * value. Thus, the evaluator needs to dispatch on them in two steps. */ + +/* Evaluator bytecode for (define ...) statements. We make it a long + * instruction since the executor will see this bytecode only for a very + * limited number of times, namely once for every top-level and internal + * definition: Top-level definitions are only executed once and internal + * definitions are converted to letrec expressions. */ +#define SCM_IM_DEFINE SCM_MAKISYM (13) + #define SCM_IM_APPLY SCM_MAKISYM (14) #define SCM_IM_CONT SCM_MAKISYM (15) #define SCM_BOOL_F SCM_MAKIFLAG (16)