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

@@ -2064,6 +2064,63 @@ static void build_subroutines(BuildCtx *ctx)
|//-- Miscellaneous functions --------------------------------------------
|//-----------------------------------------------------------------------
|
|.define NEXT_TAB, TAB:CARG1
|.define NEXT_RES, CARG1
|.define NEXT_IDX, CARG2w
|.define NEXT_LIM, CARG3w
|.define NEXT_TMP0, TMP0
|.define NEXT_TMP0w, TMP0w
|.define NEXT_TMP1, TMP1
|.define NEXT_TMP1w, TMP1w
|.define NEXT_RES_PTR, sp
|.define NEXT_RES_VAL, [sp]
|.define NEXT_RES_KEY, [sp, #8]
|
|// TValue *lj_vm_next(GCtab *t, uint32_t idx)
|// Next idx returned in CRET2w.
|->vm_next:
|.if JIT
| ldr NEXT_LIM, NEXT_TAB->asize
| ldr NEXT_TMP1, NEXT_TAB->array
|1: // Traverse array part.
| subs NEXT_TMP0w, NEXT_IDX, NEXT_LIM
| bhs >5 // Index points after array part?
| ldr NEXT_TMP0, [NEXT_TMP1, NEXT_IDX, uxtw #3]
| cmn NEXT_TMP0, #-LJ_TNIL
| cinc NEXT_IDX, NEXT_IDX, eq
| beq <1 // Skip holes in array part.
| str NEXT_TMP0, NEXT_RES_VAL
| movz NEXT_TMP0w, #(LJ_TISNUM>>1)&0xffff, lsl #16
| stp NEXT_IDX, NEXT_TMP0w, NEXT_RES_KEY
| add NEXT_IDX, NEXT_IDX, #1
| mov NEXT_RES, NEXT_RES_PTR
|4:
| ret
|
|5: // Traverse hash part.
| ldr NEXT_TMP1w, NEXT_TAB->hmask
| ldr NODE:NEXT_RES, NEXT_TAB->node
| add NEXT_TMP0w, NEXT_TMP0w, NEXT_TMP0w, lsl #1
| add NEXT_LIM, NEXT_LIM, NEXT_TMP1w
| add NODE:NEXT_RES, NODE:NEXT_RES, NEXT_TMP0w, uxtw #3
|6:
| cmp NEXT_IDX, NEXT_LIM
| bhi >9
| ldr NEXT_TMP0, NODE:NEXT_RES->val
| cmn NEXT_TMP0, #-LJ_TNIL
| add NEXT_IDX, NEXT_IDX, #1
| bne <4
| // Skip holes in hash part.
| add NODE:NEXT_RES, NODE:NEXT_RES, #sizeof(Node)
| b <6
|
|9: // End of iteration. Set the key to nil (not the value).
| movn NEXT_TMP0, #0
| str NEXT_TMP0, NEXT_RES_KEY
| mov NEXT_RES, NEXT_RES_PTR
| ret
|.endif
|
|//-----------------------------------------------------------------------
|//-- FFI helper functions -----------------------------------------------
|//-----------------------------------------------------------------------
@@ -3320,10 +3377,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
break;
case BC_ITERN:
| // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
|.if JIT
| // NYI: add hotloop, record BC_ITERN.
| hotloop
|.endif
|->vm_IITERN:
| // RA = base, (RB = nresults+1, RC = nargs+1 (2+1))
| add RA, BASE, RA, lsl #3
| ldr TAB:RB, [RA, #-16]
| ldrh TMP3w, [PC, # OFS_RD]
@@ -3390,11 +3448,28 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| ins_next
|
|5: // Despecialize bytecode if any of the checks fail.
|.if JIT
| ldrb TMP2w, [RC, # OFS_OP]
|.endif
| mov TMP0, #BC_JMP
| mov TMP1, #BC_ITERC
| strb TMP0w, [PC, #-4+OFS_OP]
|.if JIT
| cmp TMP2w, #BC_ITERN
| bne >6
|.endif
| strb TMP1w, [RC, # OFS_OP]
| b <1
|.if JIT
|6: // Unpatch JLOOP.
| ldr RA, [GL, #GL_J(trace)]
| ldrh TMP2w, [RC, # OFS_RD]
| ldr TRACE:RA, [RA, TMP2, lsl #3]
| ldr TMP2w, TRACE:RA->startins
| bfxil TMP2w, TMP1w, #0, #8
| str TMP2w, [RC]
| b <1
|.endif
break;
case BC_VARG: