From c3d72096c4841ebc04a0615917d71f22aaa5e5ff Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 27 Aug 2001 12:16:28 -0300 Subject: [PATCH] use a table to find (and reuse) constants when parsing --- lcode.c | 44 ++++++++++++++++++++------------------------ llimits.h | 8 +------- lobject.h | 5 ++--- lparser.c | 6 +++++- lparser.h | 4 +++- lstring.c | 3 +-- 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/lcode.c b/lcode.c index 252249b6..49b7ed4f 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.77 2001/07/17 14:30:44 roberto Exp roberto $ +** $Id: lcode.c,v 1.78 2001/07/24 17:19:07 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -18,6 +18,7 @@ #include "lobject.h" #include "lopcodes.h" #include "lparser.h" +#include "ltable.h" #define hasjumps(e) ((e)->t != (e)->f) @@ -222,38 +223,33 @@ static void freeexp (FuncState *fs, expdesc *e) { static int addk (FuncState *fs, TObject *k) { - Proto *f = fs->f; - luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, - MAXARG_Bc, l_s("constant table overflow")); - setobj(&f->k[fs->nk], k); - return fs->nk++; + const TObject *index = luaH_get(fs->h, k); + if (ttype(index) == LUA_TNUMBER) { + lua_assert(luaO_equalObj(&fs->f->k[(int)nvalue(index)], k)); + return (int)nvalue(index); + } + else { /* constant not found; create a new entry */ + TObject o; + Proto *f = fs->f; + luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, + MAXARG_Bc, l_s("constant table overflow")); + setobj(&f->k[fs->nk], k); + setnvalue(&o, fs->nk); + setobj(luaH_set(fs->L, fs->h, k), &o); + return fs->nk++; + } } int luaK_stringk (FuncState *fs, TString *s) { - Proto *f = fs->f; - int c = s->tsv.constindex; - if (c >= fs->nk || ttype(&f->k[c]) != LUA_TSTRING || tsvalue(&f->k[c]) != s) { - TObject o; - setsvalue(&o, s); - c = addk(fs, &o); - s->tsv.constindex = (unsigned short)c; /* hint for next time */ - } - return c; + TObject o; + setsvalue(&o, s); + return addk(fs, &o); } static int number_constant (FuncState *fs, lua_Number r) { - /* check whether `r' has appeared within the last LOOKBACKNUMS entries */ TObject o; - Proto *f = fs->f; - int c = fs->nk; - int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS; - while (--c >= lim) { - if (ttype(&f->k[c]) == LUA_TNUMBER && nvalue(&f->k[c]) == r) - return c; - } - /* not found; create a new entry */ setnvalue(&o, r); return addk(fs, &o); } diff --git a/llimits.h b/llimits.h index 27df4ba1..dd210f20 100644 --- a/llimits.h +++ b/llimits.h @@ -1,5 +1,5 @@ /* -** $Id: llimits.h,v 1.29 2001/06/05 18:17:01 roberto Exp roberto $ +** $Id: llimits.h,v 1.30 2001/06/05 20:01:09 roberto Exp roberto $ ** Limits, basic types, and some other `installation-dependent' definitions ** See Copyright Notice in lua.h */ @@ -124,10 +124,4 @@ typedef unsigned long Instruction; -/* maximum lookback to find a real constant (for code generation) */ -#ifndef LOOKBACKNUMS -#define LOOKBACKNUMS 40 /* arbitrary constant */ -#endif - - #endif diff --git a/lobject.h b/lobject.h index 9a19ea8e..9170d81b 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 1.108 2001/06/28 14:48:44 roberto Exp roberto $ +** $Id: lobject.h,v 1.109 2001/06/28 14:56:25 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -90,8 +90,7 @@ typedef union TString { struct { lu_hash hash; size_t len; - unsigned short constindex; /* hint to reuse constants */ - short marked; + int marked; union TString *nexthash; /* chain for hash table */ } tsv; } TString; diff --git a/lparser.c b/lparser.c index e5c38b6c..58b3bcba 100644 --- a/lparser.c +++ b/lparser.c @@ -1,5 +1,5 @@ /* -** $Id: lparser.c,v 1.152 2001/07/10 20:02:22 roberto Exp roberto $ +** $Id: lparser.c,v 1.153 2001/08/10 20:53:03 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -318,6 +318,7 @@ static void open_func (LexState *ls, FuncState *fs) { fs->jlt = NO_JUMP; fs->freereg = 0; fs->nk = 0; + fs->h = luaH_new(ls->L, 0); fs->np = 0; fs->nlineinfo = 0; fs->nlocvars = 0; @@ -339,6 +340,9 @@ static void close_func (LexState *ls) { luaK_codeABC(fs, OP_RETURN, 0, 0, 0); /* final return */ luaK_getlabel(fs); /* close eventual list of pending jumps */ removelocalvars(ls, fs->nactloc); + lua_assert(G(L)->roottable == fs->h); + G(L)->roottable = fs->h->next; + luaH_free(L, fs->h); luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); f->sizecode = fs->pc; luaM_reallocvector(L, f->k, f->sizek, fs->nk, TObject); diff --git a/lparser.h b/lparser.h index 220ae9e7..22482ce2 100644 --- a/lparser.h +++ b/lparser.h @@ -1,5 +1,5 @@ /* -** $Id: lparser.h,v 1.32 2001/06/28 14:56:25 roberto Exp roberto $ +** $Id: lparser.h,v 1.33 2001/08/10 20:53:03 roberto Exp roberto $ ** Lua Parser ** See Copyright Notice in lua.h */ @@ -8,6 +8,7 @@ #define lparser_h #include "lobject.h" +#include "ltable.h" #include "lzio.h" @@ -53,6 +54,7 @@ typedef struct FuncState { int jlt; /* list of jumps to `lasttarget' */ int freereg; /* first free register */ int nk; /* number of elements in `k' */ + Hash *h; /* table to find (and reuse) elements in `k' */ int np; /* number of elements in `p' */ int nlineinfo; /* number of elements in `lineinfo' */ int nlocvars; /* number of elements in `locvars' */ diff --git a/lstring.c b/lstring.c index a71142bb..1454dc17 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 1.64 2001/06/07 15:01:21 roberto Exp roberto $ +** $Id: lstring.c,v 1.65 2001/06/15 20:36:57 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -54,7 +54,6 @@ static TString *newlstr (lua_State *L, const l_char *str, size_t l, lu_hash h) { ts->tsv.len = l; ts->tsv.hash = h; ts->tsv.marked = 0; - ts->tsv.constindex = 0; memcpy(getstr(ts), str, l*sizeof(l_char)); getstr(ts)[l] = l_c('\0'); /* ending 0 */ tb = &G(L)->strt;