aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-02 14:43:55 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2021-02-02 14:43:55 -0300
commite500892e18e994781760819e33098322728796e8 (patch)
tree0a954761f83effd9aaf4c650e7dfe6e0564e37e7
parent949187b049ce329c93d6639b91e244f2b208c807 (diff)
downloadlua-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.c4
-rw-r--r--ldebug.c35
-rw-r--r--ldebug.h4
3 files changed, 19 insertions, 24 deletions
diff --git a/lcode.c b/lcode.c
index 9741d7cd..31f23f47 100644
--- a/lcode.c
+++ b/lcode.c
@@ -328,13 +328,13 @@ void luaK_patchtohere (FuncState *fs, int list) {
328static void savelineinfo (FuncState *fs, Proto *f, int line) { 328static 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");
diff --git a/ldebug.c b/ldebug.c
index 8dfa18cf..0038d1b3 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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*/
54static int getbaseline (const Proto *f, int pc, int *basepc) { 58static 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 }
diff --git a/ldebug.h b/ldebug.h
index 8e912a8e..974960e9 100644
--- a/ldebug.h
+++ b/ldebug.h
@@ -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