aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2006-09-19 10:57:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2006-09-19 10:57:50 -0300
commitd1ef7e0ec6f0b3c40a4abedb3f79a3eaabe01631 (patch)
tree38a4baf7abb3c0683fb4d0e5b527d210f7077210 /lvm.c
parentd513c3c66b3c71412d87a3f24b8f792b7b728e93 (diff)
downloadlua-d1ef7e0ec6f0b3c40a4abedb3f79a3eaabe01631.tar.gz
lua-d1ef7e0ec6f0b3c40a4abedb3f79a3eaabe01631.tar.bz2
lua-d1ef7e0ec6f0b3c40a4abedb3f79a3eaabe01631.zip
avoid local "pc" in interpreter loop (tricky optimization with no real gain)
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c84
1 files changed, 38 insertions, 46 deletions
diff --git a/lvm.c b/lvm.c
index 98846bc9..9357fe2b 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.66 2006/08/07 19:14:30 roberto Exp roberto $ 2** $Id: lvm.c,v 2.67 2006/09/11 14:07:24 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -57,25 +57,22 @@ int luaV_tostring (lua_State *L, StkId obj) {
57} 57}
58 58
59 59
60static void traceexec (lua_State *L, const Instruction *pc) { 60static void traceexec (lua_State *L) {
61 lu_byte mask = L->hookmask; 61 lu_byte mask = L->hookmask;
62 const Instruction *oldpc = L->savedpc; 62 if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
63 L->savedpc = pc; 63 resethookcount(L);
64 if (mask > LUA_MASKLINE) { /* instruction-hook set? */ 64 luaD_callhook(L, LUA_HOOKCOUNT, -1);
65 if (L->hookcount == 0) {
66 resethookcount(L);
67 luaD_callhook(L, LUA_HOOKCOUNT, -1);
68 }
69 } 65 }
70 if (mask & LUA_MASKLINE) { 66 if (mask & LUA_MASKLINE) {
71 Proto *p = ci_func(L->ci)->l.p; 67 Proto *p = ci_func(L->ci)->l.p;
72 int npc = pcRel(pc, p); 68 int npc = pcRel(L->savedpc, p);
73 int newline = getline(p, npc); 69 int newline = getline(p, npc);
74 /* call linehook when enter a new function, when jump back (loop), 70 if (npc == 0 || /* call linehook when enter a new function, */
75 or when enter a new line */ 71 L->savedpc <= L->oldpc || /* when jump back (loop), or when */
76 if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p))) 72 newline != getline(p, pcRel(L->oldpc, p))) /* enter a new line */
77 luaD_callhook(L, LUA_HOOKLINE, newline); 73 luaD_callhook(L, LUA_HOOKLINE, newline);
78 } 74 }
75 L->oldpc = L->savedpc;
79} 76}
80 77
81 78
@@ -351,10 +348,10 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
351#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i)) 348#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
352 349
353 350
354#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);} 351#define dojump(L,i) { L->savedpc += (i); luai_threadyield(L);}
355 352
356 353
357#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; } 354#define Protect(x) { {x;}; base = L->base; }
358 355
359 356
360#define arith_op(op,tm) { \ 357#define arith_op(op,tm) { \
@@ -374,22 +371,20 @@ void luaV_execute (lua_State *L, int nexeccalls) {
374 LClosure *cl; 371 LClosure *cl;
375 StkId base; 372 StkId base;
376 TValue *k; 373 TValue *k;
377 const Instruction *pc;
378 reentry: /* entry point */ 374 reentry: /* entry point */
379 lua_assert(isLua(L->ci)); 375 lua_assert(isLua(L->ci));
380 pc = L->savedpc;
381 cl = &clvalue(L->ci->func)->l; 376 cl = &clvalue(L->ci->func)->l;
382 base = L->base; 377 base = L->base;
383 k = cl->p->k; 378 k = cl->p->k;
384 /* main loop of interpreter */ 379 /* main loop of interpreter */
385 for (;;) { 380 for (;;) {
386 const Instruction i = *pc++; 381 const Instruction i = *(L->savedpc++);
387 StkId ra; 382 StkId ra;
388 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && 383 if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
389 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { 384 (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
390 traceexec(L, pc); 385 traceexec(L);
391 if (L->status == LUA_YIELD) { /* did hook yield? */ 386 if (L->status == LUA_YIELD) { /* did hook yield? */
392 L->savedpc = pc - 1; 387 L->savedpc--; /* undo increment */
393 return; 388 return;
394 } 389 }
395 base = L->base; 390 base = L->base;
@@ -410,7 +405,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
410 } 405 }
411 case OP_LOADBOOL: { 406 case OP_LOADBOOL: {
412 setbvalue(ra, GETARG_B(i)); 407 setbvalue(ra, GETARG_B(i));
413 if (GETARG_C(i)) pc++; /* skip next instruction (if C) */ 408 if (GETARG_C(i)) L->savedpc++; /* skip next instruction (if C) */
414 continue; 409 continue;
415 } 410 }
416 case OP_LOADNIL: { 411 case OP_LOADNIL: {
@@ -538,7 +533,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
538 continue; 533 continue;
539 } 534 }
540 case OP_JMP: { 535 case OP_JMP: {
541 dojump(L, pc, GETARG_sBx(i)); 536 dojump(L, GETARG_sBx(i));
542 continue; 537 continue;
543 } 538 }
544 case OP_EQ: { 539 case OP_EQ: {
@@ -546,47 +541,46 @@ void luaV_execute (lua_State *L, int nexeccalls) {
546 TValue *rc = RKC(i); 541 TValue *rc = RKC(i);
547 Protect( 542 Protect(
548 if (equalobj(L, rb, rc) == GETARG_A(i)) 543 if (equalobj(L, rb, rc) == GETARG_A(i))
549 dojump(L, pc, GETARG_sBx(*pc)); 544 dojump(L, GETARG_sBx(*L->savedpc));
550 ) 545 )
551 pc++; 546 L->savedpc++;
552 continue; 547 continue;
553 } 548 }
554 case OP_LT: { 549 case OP_LT: {
555 Protect( 550 Protect(
556 if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i)) 551 if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
557 dojump(L, pc, GETARG_sBx(*pc)); 552 dojump(L, GETARG_sBx(*L->savedpc));
558 ) 553 )
559 pc++; 554 L->savedpc++;
560 continue; 555 continue;
561 } 556 }
562 case OP_LE: { 557 case OP_LE: {
563 Protect( 558 Protect(
564 if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i)) 559 if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
565 dojump(L, pc, GETARG_sBx(*pc)); 560 dojump(L, GETARG_sBx(*L->savedpc));
566 ) 561 )
567 pc++; 562 L->savedpc++;
568 continue; 563 continue;
569 } 564 }
570 case OP_TEST: { 565 case OP_TEST: {
571 if (l_isfalse(ra) != GETARG_C(i)) 566 if (l_isfalse(ra) != GETARG_C(i))
572 dojump(L, pc, GETARG_sBx(*pc)); 567 dojump(L, GETARG_sBx(*L->savedpc));
573 pc++; 568 L->savedpc++;
574 continue; 569 continue;
575 } 570 }
576 case OP_TESTSET: { 571 case OP_TESTSET: {
577 TValue *rb = RB(i); 572 TValue *rb = RB(i);
578 if (l_isfalse(rb) != GETARG_C(i)) { 573 if (l_isfalse(rb) != GETARG_C(i)) {
579 setobjs2s(L, ra, rb); 574 setobjs2s(L, ra, rb);
580 dojump(L, pc, GETARG_sBx(*pc)); 575 dojump(L, GETARG_sBx(*L->savedpc));
581 } 576 }
582 pc++; 577 L->savedpc++;
583 continue; 578 continue;
584 } 579 }
585 case OP_CALL: { 580 case OP_CALL: {
586 int b = GETARG_B(i); 581 int b = GETARG_B(i);
587 int nresults = GETARG_C(i) - 1; 582 int nresults = GETARG_C(i) - 1;
588 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 583 if (b != 0) L->top = ra+b; /* else previous instruction set top */
589 L->savedpc = pc;
590 switch (luaD_precall(L, ra, nresults)) { 584 switch (luaD_precall(L, ra, nresults)) {
591 case PCRLUA: { 585 case PCRLUA: {
592 nexeccalls++; 586 nexeccalls++;
@@ -606,7 +600,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
606 case OP_TAILCALL: { 600 case OP_TAILCALL: {
607 int b = GETARG_B(i); 601 int b = GETARG_B(i);
608 if (b != 0) L->top = ra+b; /* else previous instruction set top */ 602 if (b != 0) L->top = ra+b; /* else previous instruction set top */
609 L->savedpc = pc;
610 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); 603 lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
611 switch (luaD_precall(L, ra, LUA_MULTRET)) { 604 switch (luaD_precall(L, ra, LUA_MULTRET)) {
612 case PCRLUA: { 605 case PCRLUA: {
@@ -639,7 +632,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
639 int b = GETARG_B(i); 632 int b = GETARG_B(i);
640 if (b != 0) L->top = ra+b-1; 633 if (b != 0) L->top = ra+b-1;
641 if (L->openupval) luaF_close(L, base); 634 if (L->openupval) luaF_close(L, base);
642 L->savedpc = pc;
643 b = luaD_poscall(L, ra); 635 b = luaD_poscall(L, ra);
644 if (--nexeccalls == 0) /* was previous function running `here'? */ 636 if (--nexeccalls == 0) /* was previous function running `here'? */
645 return; /* no: return */ 637 return; /* no: return */
@@ -656,7 +648,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
656 lua_Number limit = nvalue(ra+1); 648 lua_Number limit = nvalue(ra+1);
657 if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) 649 if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
658 : luai_numle(L, limit, idx)) { 650 : luai_numle(L, limit, idx)) {
659 dojump(L, pc, GETARG_sBx(i)); /* jump back */ 651 dojump(L, GETARG_sBx(i)); /* jump back */
660 setnvalue(ra, idx); /* update internal index... */ 652 setnvalue(ra, idx); /* update internal index... */
661 setnvalue(ra+3, idx); /* ...and external index */ 653 setnvalue(ra+3, idx); /* ...and external index */
662 } 654 }
@@ -666,7 +658,6 @@ void luaV_execute (lua_State *L, int nexeccalls) {
666 const TValue *init = ra; 658 const TValue *init = ra;
667 const TValue *plimit = ra+1; 659 const TValue *plimit = ra+1;
668 const TValue *pstep = ra+2; 660 const TValue *pstep = ra+2;
669 L->savedpc = pc; /* next steps may throw errors */
670 if (!tonumber(init, ra)) 661 if (!tonumber(init, ra))
671 luaG_runerror(L, LUA_QL("for") " initial value must be a number"); 662 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
672 else if (!tonumber(plimit, ra+1)) 663 else if (!tonumber(plimit, ra+1))
@@ -674,7 +665,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
674 else if (!tonumber(pstep, ra+2)) 665 else if (!tonumber(pstep, ra+2))
675 luaG_runerror(L, LUA_QL("for") " step must be a number"); 666 luaG_runerror(L, LUA_QL("for") " step must be a number");
676 setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); 667 setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
677 dojump(L, pc, GETARG_sBx(i)); 668 dojump(L, GETARG_sBx(i));
678 continue; 669 continue;
679 } 670 }
680 case OP_TFORLOOP: { 671 case OP_TFORLOOP: {
@@ -688,9 +679,9 @@ void luaV_execute (lua_State *L, int nexeccalls) {
688 cb = RA(i) + 3; /* previous call may change the stack */ 679 cb = RA(i) + 3; /* previous call may change the stack */
689 if (!ttisnil(cb)) { /* continue loop? */ 680 if (!ttisnil(cb)) { /* continue loop? */
690 setobjs2s(L, cb-1, cb); /* save control variable */ 681 setobjs2s(L, cb-1, cb); /* save control variable */
691 dojump(L, pc, GETARG_sBx(*pc)); /* jump back */ 682 dojump(L, GETARG_sBx(*L->savedpc)); /* jump back */
692 } 683 }
693 pc++; 684 L->savedpc++;
694 continue; 685 continue;
695 } 686 }
696 case OP_SETLIST: { 687 case OP_SETLIST: {
@@ -699,7 +690,7 @@ void luaV_execute (lua_State *L, int nexeccalls) {
699 int last; 690 int last;
700 Table *h; 691 Table *h;
701 if (n == 0) n = cast_int(L->top - ra) - 1; 692 if (n == 0) n = cast_int(L->top - ra) - 1;
702 if (c == 0) c = cast_int(*pc++); 693 if (c == 0) c = cast_int(*L->savedpc++);
703 runtime_check(L, ttistable(ra)); 694 runtime_check(L, ttistable(ra));
704 h = hvalue(ra); 695 h = hvalue(ra);
705 last = ((c-1)*LFIELDS_PER_FLUSH) + n; 696 last = ((c-1)*LFIELDS_PER_FLUSH) + n;
@@ -726,12 +717,13 @@ void luaV_execute (lua_State *L, int nexeccalls) {
726 ncl = luaF_newLclosure(L, nup, cl->env); 717 ncl = luaF_newLclosure(L, nup, cl->env);
727 ncl->l.p = p; 718 ncl->l.p = p;
728 setclvalue(L, ra, ncl); 719 setclvalue(L, ra, ncl);
729 for (j=0; j<nup; j++, pc++) { 720 for (j=0; j<nup; j++, L->savedpc++) {
730 if (GET_OPCODE(*pc) == OP_GETUPVAL) 721 Instruction u = *L->savedpc;
731 ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)]; 722 if (GET_OPCODE(u) == OP_GETUPVAL)
723 ncl->l.upvals[j] = cl->upvals[GETARG_B(u)];
732 else { 724 else {
733 lua_assert(GET_OPCODE(*pc) == OP_MOVE); 725 lua_assert(GET_OPCODE(u) == OP_MOVE);
734 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc)); 726 ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(u));
735 } 727 }
736 } 728 }
737 Protect(luaC_checkGC(L)); 729 Protect(luaC_checkGC(L));