]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Merge branch 'master' into v2.1
authorMike Pall <mike>
Wed, 31 Jan 2024 13:39:50 +0000 (14:39 +0100)
committerMike Pall <mike>
Wed, 31 Jan 2024 13:39:50 +0000 (14:39 +0100)
1  2 
src/lj_bcwrite.c

index c062dc498bf8684ddd418187ce0ee9fed24b8933,9820ad122bffc412d07c413d1e85d1ae90eb2564..ddfa46c56d1322b2d4729cc929186f2f7d7fabe7
@@@ -91,64 -108,8 +91,64 @@@ static LJ_AINLINE int bcwrite_ktabk_lt(
    }
  }
  
-     if (!tvisnil(&node->val)) {
 +/* Insert key into a sorted heap. */
 +static void bcwrite_ktabk_heap_insert(TValue **heap, MSize idx, MSize end,
 +                                    TValue *key)
 +{
 +  MSize child;
 +  while ((child = idx * 2 + 1) < end) {
 +    /* Find lower of the two children. */
 +    TValue *c0 = heap[child];
 +    if (child + 1 < end) {
 +      TValue *c1 = heap[child + 1];
 +      if (bcwrite_ktabk_lt(c1, c0)) {
 +      c0 = c1;
 +      child++;
 +      }
 +    }
 +    if (bcwrite_ktabk_lt(key, c0)) break;  /* Key lower? Found our position. */
 +    heap[idx] = c0;  /* Move lower child up. */
 +    idx = child;  /* Descend. */
 +  }
 +  heap[idx] = key;  /* Insert key here. */
 +}
 +
 +/* Resize heap, dropping content. */
 +static void bcwrite_heap_resize(BCWriteCtx *ctx, uint32_t nsz)
 +{
 +  lua_State *L = sbufL(&ctx->sb);
 +  if (ctx->heapsz) {
 +    lj_mem_freevec(G(L), ctx->heap, ctx->heapsz, TValue *);
 +    ctx->heapsz = 0;
 +  }
 +  if (nsz) {
 +    ctx->heap = lj_mem_newvec(L, nsz, TValue *);
 +    ctx->heapsz = nsz;
 +  }
 +}
 +
 +/* Write hash part of template table in sorted order. */
 +static void bcwrite_ktab_sorted_hash(BCWriteCtx *ctx, Node *node, MSize nhash)
 +{
 +  TValue **heap = ctx->heap;
 +  MSize i = nhash;
 +  for (;; node--) {  /* Build heap. */
++    if (!tvisnil(&node->key)) {
 +      bcwrite_ktabk_heap_insert(heap, --i, nhash, &node->key);
 +      if (i == 0) break;
 +    }
 +  }
 +  do {  /* Drain heap. */
 +    TValue *key = heap[0];  /* Output lowest key from top. */
 +    bcwrite_ktabk(ctx, key, 0);
 +    bcwrite_ktabk(ctx, (TValue *)((char *)key - offsetof(Node, key)), 1);
 +    key = heap[--nhash];  /* Remove last key. */
 +    bcwrite_ktabk_heap_insert(heap, 0, nhash, key);  /* Re-insert. */
 +  } while (nhash);
 +}
 +
  /* Write a template table. */
 -static void bcwrite_ktab(BCWriteCtx *ctx, const GCtab *t)
 +static void bcwrite_ktab(BCWriteCtx *ctx, char *p, const GCtab *t)
  {
    MSize narray = 0, nhash = 0;
    if (t->asize > 0) {  /* Determine max. length of array part. */
      MSize i, hmask = t->hmask;
      Node *node = noderef(t->node);
      for (i = 0; i <= hmask; i++)
-       nhash += !tvisnil(&node[i].val);
+       nhash += !tvisnil(&node[i].key);
    }
    /* Write number of array slots and hash slots. */
 -  bcwrite_uleb128(ctx, narray);
 -  bcwrite_uleb128(ctx, nhash);
 +  p = lj_strfmt_wuleb128(p, narray);
 +  p = lj_strfmt_wuleb128(p, nhash);
 +  ctx->sb.w = p;
    if (narray) {  /* Write array entries (may contain nil). */
      MSize i;
      TValue *o = tvref(t->array);
        bcwrite_ktabk(ctx, o, 1);
    }
    if (nhash) {  /* Write hash entries. */
 -    MSize i = nhash;
      Node *node = noderef(t->node) + t->hmask;
 -    for (;; node--)
 -      if (!tvisnil(&node->key)) {
 -      bcwrite_ktabk(ctx, &node->key, 0);
 -      bcwrite_ktabk(ctx, &node->val, 1);
 -      if (--i == 0) break;
 -      }
 +    if ((ctx->flags & BCDUMP_F_DETERMINISTIC) && nhash > 1) {
 +      if (ctx->heapsz < nhash)
 +      bcwrite_heap_resize(ctx, t->hmask + 1);
 +      bcwrite_ktab_sorted_hash(ctx, node, nhash);
 +    } else {
 +      MSize i = nhash;
 +      for (;; node--)
-       if (!tvisnil(&node->val)) {
++      if (!tvisnil(&node->key)) {
 +        bcwrite_ktabk(ctx, &node->key, 0);
 +        bcwrite_ktabk(ctx, &node->val, 1);
 +        if (--i == 0) break;
 +      }
 +    }
    }
  }