History

Inline doubles and interned string pointers in the byte code.

Avoid linearly searched per function string and number tables.

Tor Andersson committed 5 years ago

Commit 33ffe6e1 parent 06a6f9f5 files · +62 −59Browse files

Unified · Split

5 files
  1. jscompile.c +15 −32
  2. jscompile.h +0 −6
  3. jsdump.c +14 −5
  4. jsgc.c +0 −2
  5. jsrun.c +33 −14
jscompile.c+15−32
@@ -110,34 +110,6 @@ static int addfunction(JF, js_Function *value) · 109 unmodified lines
110 return F->funlen++;110 return F->funlen++;
111}111}
112 112
113static int addnumber(JF, double value)
114{
115 int i;
116 for (i = 0; i < F->numlen; ++i)
117 if (F->numtab[i] == value)
118 return i;
119 if (F->numlen >= F->numcap) {
120 F->numcap = F->numcap ? F->numcap * 2 : 16;
121 F->numtab = js_realloc(J, F->numtab, F->numcap * sizeof *F->numtab);
122 }
123 F->numtab[F->numlen] = value;
124 return F->numlen++;
125}
126
127static int addstring(JF, const char *value)
128{
129 int i;
130 for (i = 0; i < F->strlen; ++i)
131 if (!strcmp(F->strtab[i], value))
132 return i;
133 if (F->strlen >= F->strcap) {
134 F->strcap = F->strcap ? F->strcap * 2 : 16;
135 F->strtab = js_realloc(J, F->strtab, F->strcap * sizeof *F->strtab);
136 }
137 F->strtab[F->strlen] = value;
138 return F->strlen++;
139}
140
141static int addlocal(JF, js_Ast *ident, int reuse)113static int addlocal(JF, js_Ast *ident, int reuse)
142{114{
143 const char *name = ident->string;115 const char *name = ident->string;
@@ -196,15 +168,27 @@ static void emitnumber(JF, double num) · 52 unmodified lines
196 emit(J, F, OP_INTEGER);168 emit(J, F, OP_INTEGER);
197 emitarg(J, F, num + 32768);169 emitarg(J, F, num + 32768);
198 } else {170 } else {
171#define N (sizeof(num) / sizeof(js_Instruction))
172 js_Instruction x[N];
173 size_t i;
199 emit(J, F, OP_NUMBER);174 emit(J, F, OP_NUMBER);
200 emitarg(J, F, addnumber(J, F, num));175 memcpy(x, &num, sizeof(num));
176 for (i = 0; i < N; ++i)
177 emitarg(J, F, x[i]);
178#undef N
201 }179 }
202}180}
203 181
204static void emitstring(JF, int opcode, const char *str)182static void emitstring(JF, int opcode, const char *str)
205{183{
184#define N (sizeof(str) / sizeof(js_Instruction))
185 js_Instruction x[N];
186 size_t i;
206 emit(J, F, opcode);187 emit(J, F, opcode);
207 emitarg(J, F, addstring(J, F, str));188 memcpy(x, &str, sizeof(str));
189 for (i = 0; i < N; ++i)
190 emitarg(J, F, x[i]);
191#undef N
208}192}
209 193
210static void emitlocal(JF, int oploc, int opvar, js_Ast *ident)194static void emitlocal(JF, int oploc, int opvar, js_Ast *ident)
@@ -623,8 +607,7 @@ static void cexp(JF, js_Ast *exp) · 412 unmodified lines
623 607
624 case EXP_REGEXP:608 case EXP_REGEXP:
625 emitline(J, F, exp);609 emitline(J, F, exp);
626 emit(J, F, OP_NEWREGEXP);610 emitstring(J, F, OP_NEWREGEXP, exp->string);
627 emitarg(J, F, addstring(J, F, exp->string));
628 emitarg(J, F, exp->number);611 emitarg(J, F, exp->number);
629 break;612 break;
630 613
jscompile.h+0−6
@@ -123,12 +123,6 @@ struct js_Function · 122 unmodified lines
123 js_Function **funtab;123 js_Function **funtab;
124 int funcap, funlen;124 int funcap, funlen;
125 125
126 double *numtab;
127 int numcap, numlen;
128
129 const char **strtab;
130 int strcap, strlen;
131
132 const char **vartab;126 const char **vartab;
133 int varcap, varlen;127 int varcap, varlen;
134 128
jsdump.c+14−5
@@ -781,6 +781,8 @@ void jsC_dumpfunction(js_State *J, js_Function *F) · 780 unmodified lines
781{781{
782 js_Instruction *p = F->code;782 js_Instruction *p = F->code;
783 js_Instruction *end = F->code + F->codelen;783 js_Instruction *end = F->code + F->codelen;
784 char *s;
785 double n;
784 int i;786 int i;
785 787
786 minify = 0;788 minify = 0;
@@ -807,16 +809,21 @@ void jsC_dumpfunction(js_State *J, js_Function *F) · 20 unmodified lines
807 printf(" %ld", (long)((*p++) - 32768));809 printf(" %ld", (long)((*p++) - 32768));
808 break;810 break;
809 case OP_NUMBER:811 case OP_NUMBER:
810 printf(" %.9g", F->numtab[*p++]);812 memcpy(&n, p, sizeof(n));
813 p += sizeof(n) / sizeof(*p);
814 printf(" %.9g", n);
811 break;815 break;
812 case OP_STRING:816 case OP_STRING:
817 memcpy(&s, p, sizeof(s));
818 p += sizeof(s) / sizeof(*p);
813 pc(' ');819 pc(' ');
814 pstr(F->strtab[*p++]);820 pstr(s);
815 break;821 break;
816 case OP_NEWREGEXP:822 case OP_NEWREGEXP:
817 pc(' ');823 pc(' ');
818 pregexp(F->strtab[p[0]], p[1]);824 memcpy(&s, p, sizeof(s));
819 p += 2;825 p += sizeof(s) / sizeof(*p);
826 pregexp(s, *p++);
820 break;827 break;
821 828
822 case OP_GETVAR:829 case OP_GETVAR:
@@ -827,8 +834,10 @@ void jsC_dumpfunction(js_State *J, js_Function *F) · 4 unmodified lines
827 case OP_SETPROP_S:834 case OP_SETPROP_S:
828 case OP_DELPROP_S:835 case OP_DELPROP_S:
829 case OP_CATCH:836 case OP_CATCH:
837 memcpy(&s, p, sizeof(s));
838 p += sizeof(s) / sizeof(*p);
830 pc(' ');839 pc(' ');
831 ps(F->strtab[*p++]);840 ps(s);
832 break;841 break;
833 842
834 case OP_GETLOCAL:843 case OP_GETLOCAL:
jsgc.c+0−2
@@ -13,8 +13,6 @@ static void jsG_freeenvironment(js_State *J, js_Environment *env) · 12 unmodified lines
13static void jsG_freefunction(js_State *J, js_Function *fun)13static void jsG_freefunction(js_State *J, js_Function *fun)
14{14{
15 js_free(J, fun->funtab);15 js_free(J, fun->funtab);
16 js_free(J, fun->numtab);
17 js_free(J, fun->strtab);
18 js_free(J, fun->vartab);16 js_free(J, fun->vartab);
19 js_free(J, fun->code);17 js_free(J, fun->code);
20 js_free(J, fun);18 js_free(J, fun);
jsrun.c+33−14
@@ -1314,8 +1314,6 @@ void js_trap(js_State *J, int pc) · 1313 unmodified lines
1314static void jsR_run(js_State *J, js_Function *F)1314static void jsR_run(js_State *J, js_Function *F)
1315{1315{
1316 js_Function **FT = F->funtab;1316 js_Function **FT = F->funtab;
1317 double *NT = F->numtab;
1318 const char **ST = F->strtab;
1319 const char **VT = F->vartab-1;1317 const char **VT = F->vartab-1;
1320 int lightweight = F->lightweight;1318 int lightweight = F->lightweight;
1321 js_Instruction *pcstart = F->code;1319 js_Instruction *pcstart = F->code;
@@ -1335,6 +1333,10 @@ static void jsR_run(js_State *J, js_Function *F) · 13 unmodified lines
1335 savestrict = J->strict;1333 savestrict = J->strict;
1336 J->strict = F->strict;1334 J->strict = F->strict;
1337 1335
1336#define READSTRING() \
1337 memcpy(&str, pc, sizeof(str)); \
1338 pc += sizeof(str) / sizeof(*pc)
1339
1338 while (1) {1340 while (1) {
1339 if (J->gccounter > J->gcthresh)1341 if (J->gccounter > J->gcthresh)
1340 js_gc(J, 0);1342 js_gc(J, 0);
@@ -1351,14 +1353,28 @@ static void jsR_run(js_State *J, js_Function *F) · 10 unmodified lines
1351 case OP_ROT3: js_rot3(J); break;1353 case OP_ROT3: js_rot3(J); break;
1352 case OP_ROT4: js_rot4(J); break;1354 case OP_ROT4: js_rot4(J); break;
1353 1355
1354 case OP_INTEGER: js_pushnumber(J, *pc++ - 32768); break;1356 case OP_INTEGER:
1355 case OP_NUMBER: js_pushnumber(J, NT[*pc++]); break;1357 js_pushnumber(J, *pc++ - 32768);
1356 case OP_STRING: js_pushliteral(J, ST[*pc++]); break;1358 break;
1359
1360 case OP_NUMBER:
1361 memcpy(&x, pc, sizeof(x));
1362 pc += sizeof(x) / sizeof(*pc);
1363 js_pushnumber(J, x);
1364 break;
1365
1366 case OP_STRING:
1367 READSTRING();
1368 js_pushliteral(J, str);
1369 break;
1357 1370
1358 case OP_CLOSURE: js_newfunction(J, FT[*pc++], J->E); break;1371 case OP_CLOSURE: js_newfunction(J, FT[*pc++], J->E); break;
1359 case OP_NEWOBJECT: js_newobject(J); break;1372 case OP_NEWOBJECT: js_newobject(J); break;
1360 case OP_NEWARRAY: js_newarray(J); break;1373 case OP_NEWARRAY: js_newarray(J); break;
1361 case OP_NEWREGEXP: js_newregexp(J, ST[pc[0]], pc[1]); pc += 2; break;1374 case OP_NEWREGEXP:
1375 READSTRING();
1376 js_newregexp(J, str, *pc++);
1377 break;
1362 1378
1363 case OP_UNDEF: js_pushundefined(J); break;1379 case OP_UNDEF: js_pushundefined(J); break;
1364 case OP_NULL: js_pushnull(J); break;1380 case OP_NULL: js_pushnull(J); break;
@@ -1410,22 +1426,25 @@ static void jsR_run(js_State *J, js_Function *F) · 45 unmodified lines
1410 break;1426 break;
1411 1427
1412 case OP_GETVAR:1428 case OP_GETVAR:
1413 str = ST[*pc++];1429 READSTRING();
1414 if (!js_hasvar(J, str))1430 if (!js_hasvar(J, str))
1415 js_referenceerror(J, "'%s' is not defined", str);1431 js_referenceerror(J, "'%s' is not defined", str);
1416 break;1432 break;
1417 1433
1418 case OP_HASVAR:1434 case OP_HASVAR:
1419 if (!js_hasvar(J, ST[*pc++]))1435 READSTRING();
1436 if (!js_hasvar(J, str))
1420 js_pushundefined(J);1437 js_pushundefined(J);
1421 break;1438 break;
1422 1439
1423 case OP_SETVAR:1440 case OP_SETVAR:
1424 js_setvar(J, ST[*pc++]);1441 READSTRING();
1442 js_setvar(J, str);
1425 break;1443 break;
1426 1444
1427 case OP_DELVAR:1445 case OP_DELVAR:
1428 b = js_delvar(J, ST[*pc++]);1446 READSTRING();
1447 b = js_delvar(J, str);
1429 js_pushboolean(J, b);1448 js_pushboolean(J, b);
1430 break;1449 break;
1431 1450
@@ -1471,7 +1490,7 @@ static void jsR_run(js_State *J, js_Function *F) · 39 unmodified lines
1471 break;1490 break;
1472 1491
1473 case OP_GETPROP_S:1492 case OP_GETPROP_S:
1474 str = ST[*pc++];1493 READSTRING();
1475 obj = js_toobject(J, -1);1494 obj = js_toobject(J, -1);
1476 jsR_getproperty(J, obj, str);1495 jsR_getproperty(J, obj, str);
1477 js_rot2pop1(J);1496 js_rot2pop1(J);
@@ -1486,7 +1505,7 @@ static void jsR_run(js_State *J, js_Function *F) · 8 unmodified lines
1486 break;1505 break;
1487 1506
1488 case OP_SETPROP_S:1507 case OP_SETPROP_S:
1489 str = ST[*pc++];1508 READSTRING();
1490 obj = js_toobject(J, -2);1509 obj = js_toobject(J, -2);
1491 transient = !js_isobject(J, -2);1510 transient = !js_isobject(J, -2);
1492 jsR_setproperty(J, obj, str, transient);1511 jsR_setproperty(J, obj, str, transient);
@@ -1502,7 +1521,7 @@ static void jsR_run(js_State *J, js_Function *F) · 9 unmodified lines
1502 break;1521 break;
1503 1522
1504 case OP_DELPROP_S:1523 case OP_DELPROP_S:
1505 str = ST[*pc++];1524 READSTRING();
1506 obj = js_toobject(J, -1);1525 obj = js_toobject(J, -1);
1507 b = jsR_delproperty(J, obj, str);1526 b = jsR_delproperty(J, obj, str);
1508 js_pop(J, 1);1527 js_pop(J, 1);
@@ -1738,7 +1757,7 @@ static void jsR_run(js_State *J, js_Function *F) · 229 unmodified lines
1738 break;1757 break;
1739 1758
1740 case OP_CATCH:1759 case OP_CATCH:
1741 str = ST[*pc++];1760 READSTRING();
1742 obj = jsV_newobject(J, JS_COBJECT, NULL);1761 obj = jsV_newobject(J, JS_COBJECT, NULL);
1743 js_pushobject(J, obj);1762 js_pushobject(J, obj);
1744 js_rot2(J);1763 js_rot2(J);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t