• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tarantool / luajit / 10774454435

09 Sep 2024 01:39PM UTC coverage: 92.806% (-0.08%) from 92.882%
10774454435

push

github

Buristan
FFI: Drop finalizer table rehash after GC cycle.

Reported by Sergey Kaplun.

(cherry picked from commit fb22d0f80)

The raising of the OOM error when rehashing the finalizer table (when we
can't allocate a new hash part) leads to crashes in either
`lj_trace_exit()` or `lj_trace_unwind()` due to unprotected error
raising, which either has no DWARF eh_frame [1] or loses the context of
the JIT compiler.

This patch drops rehashing of the cdata finalizer table to avoid these
crashes. It will prevent the cdata finalizer table from shrinking when a
huge amount of the cdata objects is collected by the GC. OTOH, the
finzlizer table most probably will grow anyway to the old size, so this
is not crucial.

Sergey Kaplun:
* added the description and the test for the problem

[1]: https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html

Part of tarantool/tarantool#10199
Resolves tarantool/tarantool#10290

5681 of 6025 branches covered (94.29%)

Branch coverage included in aggregate %.

21655 of 23430 relevant lines covered (92.42%)

2945096.28 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.84
/src/lj_vmevent.c
1
/*
2
** VM event handling.
3
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
4
*/
5

6
#include <stdio.h>
7

8
#define lj_vmevent_c
9
#define LUA_CORE
10

11
#include "lj_obj.h"
12
#include "lj_str.h"
13
#include "lj_tab.h"
14
#include "lj_state.h"
15
#include "lj_dispatch.h"
16
#include "lj_vm.h"
17
#include "lj_vmevent.h"
18

19
ptrdiff_t lj_vmevent_prepare(lua_State *L, VMEvent ev)
20,317✔
20
{
21
  global_State *g = G(L);
20,317✔
22
  GCstr *s = lj_str_newlit(L, LJ_VMEVENTS_REGKEY);
20,317✔
23
  cTValue *tv = lj_tab_getstr(tabV(registry(L)), s);
20,317✔
24
  if (tvistab(tv)) {
20,317✔
25
    int hash = VMEVENT_HASH(ev);
20,317✔
26
    tv = lj_tab_getint(tabV(tv), hash);
20,317✔
27
    if (tv && tvisfunc(tv)) {
20,317✔
28
      lj_state_checkstack(L, LUA_MINSTACK);
20,270✔
29
      setfuncV(L, L->top++, funcV(tv));
20,270✔
30
      if (LJ_FR2) setnilV(L->top++);
20,270✔
31
      return savestack(L, L->top);
20,270✔
32
    }
33
  }
34
  g->vmevmask &= ~VMEVENT_MASK(ev);  /* No handler: cache this fact. */
47✔
35
  return 0;
47✔
36
}
37

38
void lj_vmevent_call(lua_State *L, ptrdiff_t argbase)
20,270✔
39
{
40
  global_State *g = G(L);
20,270✔
41
  uint8_t oldmask = g->vmevmask;
20,270✔
42
  uint8_t oldh = hook_save(g);
20,270✔
43
  int status;
20,270✔
44
  g->vmevmask = 0;  /* Disable all events. */
20,270✔
45
  hook_vmevent(g);
20,270✔
46
  status = lj_vm_pcall(L, restorestack(L, argbase), 0+1, 0);
20,270✔
47
  if (LJ_UNLIKELY(status)) {
20,270✔
48
    /* Really shouldn't use stderr here, but where else to complain? */
49
    L->top--;
×
50
    fputs("VM handler failed: ", stderr);
×
51
    fputs(tvisstr(L->top) ? strVdata(L->top) : "?", stderr);
×
52
    fputc('\n', stderr);
×
53
  }
54
  hook_restore(g, oldh);
20,270✔
55
  if (g->vmevmask != VMEVENT_NOCACHE)
20,270✔
56
    g->vmevmask = oldmask;  /* Restore event mask, but not if not modified. */
20,270✔
57
}
20,270✔
58

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc