Refactor table traversal.
Sponsored by OpenResty Inc.
This commit is contained in:
@@ -1673,55 +1673,35 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| je >2 // Missing 2nd arg?
|
||||
|1:
|
||||
| cmp dword [BASE+4], LJ_TTAB; jne ->fff_fallback
|
||||
| mov L:RB, SAVE_L
|
||||
| mov L:RB->base, BASE // Add frame since C call can throw.
|
||||
| mov L:RB->top, BASE // Dummy frame length is ok.
|
||||
| mov PC, [BASE-4]
|
||||
| mov RB, BASE // Save BASE.
|
||||
|.if X64WIN
|
||||
| lea CARG3d, [BASE+8]
|
||||
| mov CARG2d, [BASE] // Caveat: CARG2d == BASE.
|
||||
| mov CARG1d, L:RB
|
||||
| mov CARG1d, [BASE]
|
||||
| lea CARG3d, [BASE-8]
|
||||
| lea CARG2d, [BASE+8] // Caveat: CARG2d == BASE.
|
||||
|.elif X64
|
||||
| mov CARG2d, [BASE]
|
||||
| lea CARG3d, [BASE+8] // Caveat: CARG3d == BASE.
|
||||
| mov CARG1d, L:RB
|
||||
| mov CARG1d, [BASE]
|
||||
| lea CARG2d, [BASE+8]
|
||||
| lea CARG3d, [BASE-8] // Caveat: CARG3d == BASE.
|
||||
|.else
|
||||
| mov TAB:RD, [BASE]
|
||||
| mov ARG2, TAB:RD
|
||||
| mov ARG1, L:RB
|
||||
| mov ARG1, TAB:RD
|
||||
| add BASE, 8
|
||||
| mov ARG2, BASE
|
||||
| sub BASE, 8+8
|
||||
| mov ARG3, BASE
|
||||
|.endif
|
||||
| mov SAVE_PC, PC // Needed for ITERN fallback.
|
||||
| call extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key)
|
||||
| // Flag returned in eax (RD).
|
||||
| mov BASE, L:RB->base
|
||||
| test RD, RD; jz >3 // End of traversal?
|
||||
| // Copy key and value to results.
|
||||
|.if X64
|
||||
| mov RBa, [BASE+8]
|
||||
| mov RDa, [BASE+16]
|
||||
| mov [BASE-8], RBa
|
||||
| mov [BASE], RDa
|
||||
|.else
|
||||
| mov RB, [BASE+8]
|
||||
| mov RD, [BASE+12]
|
||||
| mov [BASE-8], RB
|
||||
| mov [BASE-4], RD
|
||||
| mov RB, [BASE+16]
|
||||
| mov RD, [BASE+20]
|
||||
| mov [BASE], RB
|
||||
| mov [BASE+4], RD
|
||||
|.endif
|
||||
|->fff_res2:
|
||||
| mov RD, 1+2
|
||||
| jmp ->fff_res
|
||||
| call extern lj_tab_next // (GCtab *t, cTValue *key, TValue *o)
|
||||
| // 1=found, 0=end, -1=error returned in eax (RD).
|
||||
| mov BASE, RB // Restore BASE.
|
||||
| test RD, RD; jg ->fff_res2 // Found key/value.
|
||||
| js ->fff_fallback_2 // Invalid key.
|
||||
| // End of traversal: return nil.
|
||||
| mov dword [BASE-4], LJ_TNIL
|
||||
| jmp ->fff_res1
|
||||
|2: // Set missing 2nd arg to nil.
|
||||
| mov dword [BASE+12], LJ_TNIL
|
||||
| jmp <1
|
||||
|3: // End of traversal: return nil.
|
||||
| mov dword [BASE-4], LJ_TNIL
|
||||
| jmp ->fff_res1
|
||||
|
|
||||
|.ffunc_1 pairs
|
||||
| mov TAB:RB, [BASE]
|
||||
@@ -1775,7 +1755,9 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| mov [BASE], RB
|
||||
| mov [BASE+4], RD
|
||||
|.endif
|
||||
| jmp ->fff_res2
|
||||
|->fff_res2:
|
||||
| mov RD, 1+2
|
||||
| jmp ->fff_res
|
||||
|2: // Check for empty hash part first. Otherwise call C function.
|
||||
| cmp dword TAB:RB->hmask, 0; je ->fff_res0
|
||||
| mov FCARG1, TAB:RB
|
||||
@@ -4880,7 +4862,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
||||
| cmp byte CFUNC:RB->ffid, FF_next_N; jne >5
|
||||
| branchPC RD
|
||||
| mov dword [BASE+RA*8-8], 0 // Initialize control var.
|
||||
| mov dword [BASE+RA*8-4], 0xfffe7fff
|
||||
| mov dword [BASE+RA*8-4], LJ_KEYINDEX
|
||||
|1:
|
||||
| ins_next
|
||||
|5: // Despecialize bytecode if any of the checks fail.
|
||||
|
||||
Reference in New Issue
Block a user