Compile table traversals: next(), pairs(), BC_ISNEXT/BC_ITERN.

Sponsored by OpenResty Inc.
This commit is contained in:
Mike Pall
2021-09-19 17:49:25 +02:00
parent 986bb406ad
commit bb0f241015
27 changed files with 781 additions and 47 deletions

View File

@@ -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: