Compile table traversals: next(), pairs(), BC_ISNEXT/BC_ITERN.
Sponsored by OpenResty Inc.
This commit is contained in:
@@ -2424,6 +2424,64 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|//-- Miscellaneous functions --------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
|
|
||||
|.define NEXT_TAB, TAB:CARG1
|
||||
|.define NEXT_RES, CARG1
|
||||
|.define NEXT_IDX, CARG2
|
||||
|.define NEXT_TMP0, CARG3
|
||||
|.define NEXT_TMP1, CARG4
|
||||
|.define NEXT_LIM, r12
|
||||
|.define NEXT_RES_PTR, sp
|
||||
|.define NEXT_RES_VAL, [sp]
|
||||
|.define NEXT_RES_KEY_I, [sp, #8]
|
||||
|.define NEXT_RES_KEY_IT, [sp, #12]
|
||||
|
|
||||
|// TValue *lj_vm_next(GCtab *t, uint32_t idx)
|
||||
|// Next idx returned in CRET2.
|
||||
|->vm_next:
|
||||
|.if JIT
|
||||
| ldr NEXT_TMP0, NEXT_TAB->array
|
||||
| ldr NEXT_LIM, NEXT_TAB->asize
|
||||
| add NEXT_TMP0, NEXT_TMP0, NEXT_IDX, lsl #3
|
||||
|1: // Traverse array part.
|
||||
| subs NEXT_TMP1, NEXT_IDX, NEXT_LIM
|
||||
| bhs >5
|
||||
| ldr NEXT_TMP1, [NEXT_TMP0, #4]
|
||||
| str NEXT_IDX, NEXT_RES_KEY_I
|
||||
| add NEXT_TMP0, NEXT_TMP0, #8
|
||||
| add NEXT_IDX, NEXT_IDX, #1
|
||||
| checktp NEXT_TMP1, LJ_TNIL
|
||||
| beq <1 // Skip holes in array part.
|
||||
| ldr NEXT_TMP0, [NEXT_TMP0, #-8]
|
||||
| mov NEXT_RES, NEXT_RES_PTR
|
||||
| strd NEXT_TMP0, NEXT_RES_VAL // Stores NEXT_TMP1, too.
|
||||
| mvn NEXT_TMP0, #~LJ_TISNUM
|
||||
| str NEXT_TMP0, NEXT_RES_KEY_IT
|
||||
| bx lr
|
||||
|
|
||||
|5: // Traverse hash part.
|
||||
| ldr NEXT_TMP0, NEXT_TAB->hmask
|
||||
| ldr NODE:NEXT_RES, NEXT_TAB->node
|
||||
| add NEXT_TMP1, NEXT_TMP1, NEXT_TMP1, lsl #1
|
||||
| add NEXT_LIM, NEXT_LIM, NEXT_TMP0
|
||||
| add NODE:NEXT_RES, NODE:NEXT_RES, NEXT_TMP1, lsl #3
|
||||
|6:
|
||||
| cmp NEXT_IDX, NEXT_LIM
|
||||
| bhi >9
|
||||
| ldr NEXT_TMP1, NODE:NEXT_RES->val.it
|
||||
| checktp NEXT_TMP1, LJ_TNIL
|
||||
| add NEXT_IDX, NEXT_IDX, #1
|
||||
| bxne lr
|
||||
| // Skip holes in hash part.
|
||||
| add NEXT_RES, NEXT_RES, #sizeof(Node)
|
||||
| b <6
|
||||
|
|
||||
|9: // End of iteration. Set the key to nil (not the value).
|
||||
| mvn NEXT_TMP0, #0
|
||||
| mov NEXT_RES, NEXT_RES_PTR
|
||||
| str NEXT_TMP0, NEXT_RES_KEY_IT
|
||||
| bx lr
|
||||
|.endif
|
||||
|
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- FFI helper functions -----------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
@@ -3914,10 +3972,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
break;
|
||||
|
||||
case BC_ITERN:
|
||||
| // RA = base*8, (RB = nresults+1, RC = nargs+1 (2+1))
|
||||
|.if JIT
|
||||
| // NYI: add hotloop, record BC_ITERN.
|
||||
| hotloop
|
||||
|.endif
|
||||
|->vm_IITERN:
|
||||
| // RA = base*8, (RB = nresults+1, RC = nargs+1 (2+1))
|
||||
| add RA, BASE, RA
|
||||
| ldr TAB:RB, [RA, #-16]
|
||||
| ldr CARG1, [RA, #-8] // Get index from control var.
|
||||
@@ -3992,9 +4051,25 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| mov OP, #BC_ITERC
|
||||
| strb CARG1, [PC, #-4]
|
||||
| sub PC, RC, #0x20000
|
||||
|.if JIT
|
||||
| ldrb CARG1, [PC]
|
||||
| cmp CARG1, #BC_ITERN
|
||||
| bne >6
|
||||
|.endif
|
||||
| strb OP, [PC] // Subsumes ins_next1.
|
||||
| ins_next2
|
||||
| b <1
|
||||
|.if JIT
|
||||
|6: // Unpatch JLOOP.
|
||||
| ldr CARG1, [DISPATCH, #DISPATCH_J(trace)]
|
||||
| ldrh CARG2, [PC, #2]
|
||||
| ldr TRACE:CARG1, [CARG1, CARG2, lsl #2]
|
||||
| // Subsumes ins_next1 and ins_next2.
|
||||
| ldr INS, TRACE:CARG1->startins
|
||||
| bfi INS, OP, #0, #8
|
||||
| str INS, [PC], #4
|
||||
| b <1
|
||||
|.endif
|
||||
break;
|
||||
|
||||
case BC_VARG:
|
||||
|
||||
Reference in New Issue
Block a user