Skip to content

Commit

Permalink
core: set SharedArrayBuffer allocator functions
Browse files Browse the repository at this point in the history
It's important to make sure the memory is not allocated with the JS
allocator, since we might send the SAB over to a worker, for example.
  • Loading branch information
saghul committed Jul 16, 2024
1 parent 84267a1 commit 1412882
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@
#include "tjs.h"

#include <signal.h>
#include <stdatomic.h>
#include <stdio.h>
#include <string.h>

#define TJS__DEFAULT_STACK_SIZE 10 * 1024 * 1024 // 10 MB

/* JS malloc functions */

static void *tjs__mf_malloc(JSMallocState *s, size_t size) {
void *ptr;

Expand Down Expand Up @@ -92,6 +95,48 @@ static const JSMallocFunctions tjs_mf = {
.js_malloc_usable_size = tjs__malloc_usable_size,
};

/* SharedArrayBuffer functions */

typedef struct {
int ref_count;
uint64_t buf[0];
} TJSSABHeader;

static int atomic_add_int(int *ptr, int v) {
return atomic_fetch_add((_Atomic(uint32_t) *) ptr, v) + v;
}

static void *tjs__sab_alloc(void *opaque, size_t size) {
TJSSABHeader *sab = tjs__malloc(sizeof(*sab) + size);
if (!sab)
return NULL;
sab->ref_count = 1;
return sab->buf;
}

static void tjs__sab_free(void *opaque, void *ptr) {
TJSSABHeader *sab;
int ref_count;
sab = (TJSSABHeader *) ((uint8_t *) ptr - sizeof(TJSSABHeader));
ref_count = atomic_add_int(&sab->ref_count, -1);
assert(ref_count >= 0);
if (ref_count == 0)
tjs__free(sab);
}

static void tjs__sab_dup(void *opaque, void *ptr) {
TJSSABHeader *sab;
sab = (TJSSABHeader *) ((uint8_t *) ptr - sizeof(TJSSABHeader));
atomic_add_int(&sab->ref_count, 1);
}

static const JSSharedArrayBufferFunctions tjs_sf = {
.sab_alloc = tjs__sab_alloc,
.sab_dup = tjs__sab_dup,
.sab_free = tjs__sab_free,
.sab_opaque = NULL,
};

/* core */
extern const uint8_t tjs__core[];
extern const uint32_t tjs__core_size;
Expand Down Expand Up @@ -247,6 +292,9 @@ TJSRuntime *TJS_NewRuntimeInternal(bool is_worker, TJSRunOptions *options) {
/* Set stack size */
JS_SetMaxStackSize(rt, options->stack_size);

/* SharedArrayBuffer functions */
JS_SetSharedArrayBufferFunctions(rt, &tjs_sf);

qrt->is_worker = is_worker;

CHECK_EQ(uv_loop_init(&qrt->loop), 0);
Expand Down

0 comments on commit 1412882

Please sign in to comment.