diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-09-19 10:57:50 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-09-19 10:57:50 -0300 |
commit | d1ef7e0ec6f0b3c40a4abedb3f79a3eaabe01631 (patch) | |
tree | 38a4baf7abb3c0683fb4d0e5b527d210f7077210 /lvm.c | |
parent | d513c3c66b3c71412d87a3f24b8f792b7b728e93 (diff) | |
download | lua-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.c | 84 |
1 files changed, 38 insertions, 46 deletions
@@ -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 | ||
60 | static void traceexec (lua_State *L, const Instruction *pc) { | 60 | static 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)); |