Skip to content

Add GC callbacks, and a mechanism to fix the threshold #407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions quickjs.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ struct JSRuntime {
struct list_head tmp_obj_list; /* used during GC */
JSGCPhaseEnum gc_phase : 8;
size_t malloc_gc_threshold;
BOOL fix_malloc_gc_threshold : 8;
BOOL (*gc_before_callback)(); /* Callback before the gc event takes place */
void (*gc_after_callback)(); /* Callback after the gc event takes place */
#ifdef DUMP_LEAKS
struct list_head string_list; /* list of JSString.link */
#endif
Expand Down Expand Up @@ -1362,9 +1365,21 @@ static void js_trigger_gc(JSRuntime *rt, size_t size)
(uint64_t)rt->malloc_state.malloc_size);
}
#endif
JS_RunGC(rt);
rt->malloc_gc_threshold = rt->malloc_state.malloc_size +
(rt->malloc_state.malloc_size >> 1);
//To ensure JS_RunGC cannot be executed again within callbacks, disable and restore it after.
size_t tmp_threshold = rt->malloc_gc_threshold;
rt->malloc_gc_threshold=-1;

if((rt->gc_before_callback == NULL) || rt->gc_before_callback()){
JS_RunGC(rt);
if(rt->gc_after_callback != NULL)rt->gc_after_callback();
}

rt->malloc_gc_threshold=tmp_threshold;

if(rt->fix_malloc_gc_threshold == FALSE) {
rt->malloc_gc_threshold = rt->malloc_state.malloc_size +
(rt->malloc_state.malloc_size >> 1);
}
}
}

Expand Down Expand Up @@ -1631,6 +1646,10 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
rt->malloc_state = ms;
rt->malloc_gc_threshold = 256 * 1024;

rt->fix_malloc_gc_threshold = FALSE;
rt->gc_after_callback = NULL;
rt->gc_before_callback = NULL;

bf_context_init(&rt->bf_ctx, js_bf_realloc, rt);

init_list_head(&rt->context_list);
Expand Down Expand Up @@ -1777,6 +1796,22 @@ void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold)
rt->malloc_gc_threshold = gc_threshold;
}

void JS_SetGCThresholdFixed(JSRuntime *rt, BOOL fix)
{
rt->fix_malloc_gc_threshold = fix;
}


void JS_SetGCBeforeCallback(JSRuntime *rt, BOOL(*fn)())
{
rt->gc_before_callback = fn;
}

void JS_SetGCAfterCallback(JSRuntime *rt, void(*fn)())
{
rt->gc_after_callback = fn;
}

#define malloc(s) malloc_is_forbidden(s)
#define free(p) free_is_forbidden(p)
#define realloc(p,s) realloc_is_forbidden(p,s)
Expand Down
3 changes: 3 additions & 0 deletions quickjs.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN size_t JS_GetGCThreshold(JSRuntime *rt);
JS_EXTERN void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
JS_EXTERN void JS_SetGCThresholdFixed(JSRuntime *rt, JS_BOOL fixed);
JS_EXTERN void JS_SetGCBeforeCallback(JSRuntime *rt, JS_BOOL(*cb)());
JS_EXTERN void JS_SetGCAfterCallback(JSRuntime *rt, void(*cb)());
/* use 0 to disable maximum stack size check */
JS_EXTERN void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
/* should be called when changing thread to update the stack top value
Expand Down
Loading