diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-02-02 14:43:55 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-02-02 14:43:55 -0300 |
commit | e500892e18e994781760819e33098322728796e8 (patch) | |
tree | 0a954761f83effd9aaf4c650e7dfe6e0564e37e7 | |
parent | 949187b049ce329c93d6639b91e244f2b208c807 (diff) | |
download | lua-e500892e18e994781760819e33098322728796e8.tar.gz lua-e500892e18e994781760819e33098322728796e8.tar.bz2 lua-e500892e18e994781760819e33098322728796e8.zip |
Optimization/simplification of 'getbaseline'
By producing absolute line information at regular intervals, a simple
division can compute the correct entry for a given instruction.
-rw-r--r-- | lcode.c | 4 | ||||
-rw-r--r-- | ldebug.c | 35 | ||||
-rw-r--r-- | ldebug.h | 4 |
3 files changed, 19 insertions, 24 deletions
@@ -328,13 +328,13 @@ void luaK_patchtohere (FuncState *fs, int list) { | |||
328 | static void savelineinfo (FuncState *fs, Proto *f, int line) { | 328 | static void savelineinfo (FuncState *fs, Proto *f, int line) { |
329 | int linedif = line - fs->previousline; | 329 | int linedif = line - fs->previousline; |
330 | int pc = fs->pc - 1; /* last instruction coded */ | 330 | int pc = fs->pc - 1; /* last instruction coded */ |
331 | if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) { | 331 | if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ >= MAXIWTHABS) { |
332 | luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, | 332 | luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, |
333 | f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); | 333 | f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); |
334 | f->abslineinfo[fs->nabslineinfo].pc = pc; | 334 | f->abslineinfo[fs->nabslineinfo].pc = pc; |
335 | f->abslineinfo[fs->nabslineinfo++].line = line; | 335 | f->abslineinfo[fs->nabslineinfo++].line = line; |
336 | linedif = ABSLINEINFO; /* signal that there is absolute information */ | 336 | linedif = ABSLINEINFO; /* signal that there is absolute information */ |
337 | fs->iwthabs = 0; /* restart counter */ | 337 | fs->iwthabs = 1; /* restart counter */ |
338 | } | 338 | } |
339 | luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, | 339 | luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, |
340 | MAX_INT, "opcodes"); | 340 | MAX_INT, "opcodes"); |
@@ -46,10 +46,14 @@ static int currentpc (CallInfo *ci) { | |||
46 | 46 | ||
47 | /* | 47 | /* |
48 | ** Get a "base line" to find the line corresponding to an instruction. | 48 | ** Get a "base line" to find the line corresponding to an instruction. |
49 | ** For that, search the array of absolute line info for the largest saved | 49 | ** Base lines are regularly placed at MAXIWTHABS intervals, so usually |
50 | ** instruction smaller or equal to the wanted instruction. A special | 50 | ** an integer division gets the right place. When the source file has |
51 | ** case is when there is no absolute info or the instruction is before | 51 | ** large sequences of empty/comment lines, it may need extra entries, |
52 | ** the first absolute one. | 52 | ** so the original estimate needs a correction. |
53 | ** The assertion that the estimate is a lower bound for the correct base | ||
54 | ** is valid as long as the debug info has been generated with the same | ||
55 | ** value for MAXIWTHABS or smaller. (Previous releases use a little | ||
56 | ** smaller value.) | ||
53 | */ | 57 | */ |
54 | static int getbaseline (const Proto *f, int pc, int *basepc) { | 58 | static int getbaseline (const Proto *f, int pc, int *basepc) { |
55 | if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) { | 59 | if (f->sizeabslineinfo == 0 || pc < f->abslineinfo[0].pc) { |
@@ -57,20 +61,11 @@ static int getbaseline (const Proto *f, int pc, int *basepc) { | |||
57 | return f->linedefined; | 61 | return f->linedefined; |
58 | } | 62 | } |
59 | else { | 63 | else { |
60 | unsigned int i; | 64 | int i = cast_uint(pc) / MAXIWTHABS - 1; /* get an estimate */ |
61 | if (pc >= f->abslineinfo[f->sizeabslineinfo - 1].pc) | 65 | /* estimate must be a lower bond of the correct base */ |
62 | i = f->sizeabslineinfo - 1; /* instruction is after last saved one */ | 66 | lua_assert(i < f->sizeabslineinfo && f->abslineinfo[i].pc <= pc); |
63 | else { /* binary search */ | 67 | while (i + 1 < f->sizeabslineinfo && pc >= f->abslineinfo[i + 1].pc) |
64 | unsigned int j = f->sizeabslineinfo - 1; /* pc < anchorlines[j] */ | 68 | i++; /* low estimate; adjust it */ |
65 | i = 0; /* abslineinfo[i] <= pc */ | ||
66 | while (i < j - 1) { | ||
67 | unsigned int m = (j + i) / 2; | ||
68 | if (pc >= f->abslineinfo[m].pc) | ||
69 | i = m; | ||
70 | else | ||
71 | j = m; | ||
72 | } | ||
73 | } | ||
74 | *basepc = f->abslineinfo[i].pc; | 69 | *basepc = f->abslineinfo[i].pc; |
75 | return f->abslineinfo[i].line; | 70 | return f->abslineinfo[i].line; |
76 | } | 71 | } |
@@ -303,8 +298,8 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |||
303 | sethvalue2s(L, L->top, t); /* push it on stack */ | 298 | sethvalue2s(L, L->top, t); /* push it on stack */ |
304 | api_incr_top(L); | 299 | api_incr_top(L); |
305 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ | 300 | setbtvalue(&v); /* boolean 'true' to be the value of all indices */ |
306 | for (i = 0; i < p->sizelineinfo; i++) { /* for all lines with code */ | 301 | for (i = 0; i < p->sizelineinfo; i++) { /* for all instructions */ |
307 | currentline = nextline(p, currentline, i); | 302 | currentline = nextline(p, currentline, i); /* get its line */ |
308 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ | 303 | luaH_setint(L, t, currentline, &v); /* table[line] = true */ |
309 | } | 304 | } |
310 | } | 305 | } |
@@ -29,10 +29,10 @@ | |||
29 | 29 | ||
30 | /* | 30 | /* |
31 | ** MAXimum number of successive Instructions WiTHout ABSolute line | 31 | ** MAXimum number of successive Instructions WiTHout ABSolute line |
32 | ** information. | 32 | ** information. (A power of two allows fast divisions.) |
33 | */ | 33 | */ |
34 | #if !defined(MAXIWTHABS) | 34 | #if !defined(MAXIWTHABS) |
35 | #define MAXIWTHABS 120 | 35 | #define MAXIWTHABS 128 |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | 38 | ||