Skip to content

Commit a3d4e39

Browse files
authored
Merge pull request #90 from mmtk/dcn-optimize-pinning-in-ast
Don't pin objects permanently in ast.c
2 parents 5e33341 + 367a3ca commit a3d4e39

File tree

3 files changed

+70
-36
lines changed

3 files changed

+70
-36
lines changed

src/ast.c

Lines changed: 53 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,20 @@ typedef struct _jl_ast_context_t {
136136
value_t ssavalue_sym;
137137
value_t slot_sym;
138138
jl_module_t *module; // context module for `current-julia-module-counter`
139-
struct _jl_ast_context_t *next; // invasive list pointer for getting free contexts
139+
arraylist_t pinned_objects;
140140
} jl_ast_context_t;
141141

142+
// FIXME: Ugly hack to get a pointer to the pinned objects
143+
arraylist_t *extract_pinned_objects_from_ast_ctx(void *ctx)
144+
{
145+
// This is used to extract pinned objects from the context
146+
// for the purpose of pinning them in MMTk.
147+
if (ctx == NULL)
148+
return NULL;
149+
jl_ast_context_t *jl_ctx = (jl_ast_context_t*)ctx;
150+
return &jl_ctx->pinned_objects;
151+
}
152+
142153
static jl_ast_context_t jl_ast_main_ctx;
143154

144155
#ifdef __clang_gcanalyzer__
@@ -153,7 +164,7 @@ struct macroctx_stack {
153164
};
154165

155166
static jl_value_t *scm_to_julia(fl_context_t *fl_ctx, value_t e, jl_module_t *mod);
156-
static value_t julia_to_scm(fl_context_t *fl_ctx, jl_value_t *v);
167+
static value_t julia_to_scm(jl_ast_context_t *ctx, jl_value_t *v);
157168
static jl_value_t *jl_expand_macros(jl_value_t *expr, jl_module_t *inmodule, struct macroctx_stack *macroctx, int onelevel, size_t world, int throw_load_error);
158169

159170
static jl_sym_t *scmsym_to_julia(fl_context_t *fl_ctx, value_t s)
@@ -279,27 +290,29 @@ static void jl_init_ast_ctx(jl_ast_context_t *ctx) JL_NOTSAFEPOINT
279290
ctx->slot_sym = symbol(fl_ctx, "slot");
280291
ctx->module = NULL;
281292
set(symbol(fl_ctx, "*scopewarn-opt*"), fixnum(jl_options.warn_scope));
293+
arraylist_new(&ctx->pinned_objects, 0);
282294
}
283295

284296
// There should be no GC allocation while holding this lock
285297
static uv_mutex_t flisp_lock;
286-
static jl_ast_context_t *jl_ast_ctx_freed = NULL;
298+
int flisp_initialized = 0;
299+
arraylist_t jl_ast_ctx_freed;
300+
arraylist_t jl_ast_ctx_used;
287301

288302
static jl_ast_context_t *jl_ast_ctx_enter(jl_module_t *m) JL_GLOBALLY_ROOTED JL_NOTSAFEPOINT
289303
{
290304
JL_SIGATOMIC_BEGIN();
291305
uv_mutex_lock(&flisp_lock);
292-
jl_ast_context_t *ctx = jl_ast_ctx_freed;
293-
if (ctx != NULL) {
294-
jl_ast_ctx_freed = ctx->next;
295-
ctx->next = NULL;
296-
}
306+
jl_ast_context_t *ctx = (jl_ast_context_t*)arraylist_pop(&jl_ast_ctx_freed);
297307
uv_mutex_unlock(&flisp_lock);
298308
if (ctx == NULL) {
299309
// Construct a new one if we can't find any
300310
ctx = (jl_ast_context_t*)calloc(1, sizeof(jl_ast_context_t));
301311
jl_init_ast_ctx(ctx);
302312
}
313+
uv_mutex_lock(&flisp_lock);
314+
arraylist_push(&jl_ast_ctx_used, ctx);
315+
uv_mutex_unlock(&flisp_lock);
303316
ctx->module = m;
304317
return ctx;
305318
}
@@ -308,16 +321,20 @@ static void jl_ast_ctx_leave(jl_ast_context_t *ctx)
308321
{
309322
uv_mutex_lock(&flisp_lock);
310323
ctx->module = NULL;
311-
ctx->next = jl_ast_ctx_freed;
312-
jl_ast_ctx_freed = ctx;
324+
ctx->pinned_objects.len = 0; // clear pinned objects
325+
arraylist_pop(&jl_ast_ctx_used);
326+
arraylist_push(&jl_ast_ctx_freed, ctx);
313327
uv_mutex_unlock(&flisp_lock);
314328
JL_SIGATOMIC_END();
315329
}
316330

317331
void jl_init_flisp(void)
318332
{
319-
if (jl_ast_ctx_freed)
333+
if (flisp_initialized)
320334
return;
335+
flisp_initialized = 1;
336+
arraylist_new(&jl_ast_ctx_freed, 0);
337+
arraylist_new(&jl_ast_ctx_used, 0);
321338
uv_mutex_init(&flisp_lock);
322339
jl_init_ast_ctx(&jl_ast_main_ctx);
323340
// To match the one in jl_ast_ctx_leave
@@ -674,37 +691,40 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, jl_module_t *m
674691
jl_error("malformed tree");
675692
}
676693

677-
static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_valid);
694+
static value_t julia_to_scm_(jl_ast_context_t *ctx, jl_value_t *v, int check_valid);
678695

679-
static value_t julia_to_scm(fl_context_t *fl_ctx, jl_value_t *v)
696+
static value_t julia_to_scm(jl_ast_context_t *ctx, jl_value_t *v)
680697
{
681698
value_t temp;
682699
// need try/catch to reset GC handle stack in case of error
700+
fl_context_t *fl_ctx = &ctx->fl;
683701
FL_TRY_EXTERN(fl_ctx) {
684-
temp = julia_to_scm_(fl_ctx, v, 1);
702+
temp = julia_to_scm_(ctx, v, 1);
685703
}
686704
FL_CATCH_EXTERN(fl_ctx) {
687705
temp = fl_ctx->lasterror;
688706
}
689707
return temp;
690708
}
691709

692-
static void array_to_list(fl_context_t *fl_ctx, jl_array_t *a, value_t *pv, int check_valid)
710+
static void array_to_list(jl_ast_context_t *ctx, jl_array_t *a, value_t *pv, int check_valid)
693711
{
694712
value_t temp;
713+
fl_context_t *fl_ctx = &ctx->fl;
695714
for (long i = jl_array_nrows(a) - 1; i >= 0; i--) {
696715
*pv = fl_cons(fl_ctx, fl_ctx->NIL, *pv);
697-
temp = julia_to_scm_(fl_ctx, jl_array_ptr_ref(a, i), check_valid);
716+
temp = julia_to_scm_(ctx, jl_array_ptr_ref(a, i), check_valid);
698717
// note: must be separate statement
699718
car_(*pv) = temp;
700719
}
701720
}
702721

703-
static value_t julia_to_list2(fl_context_t *fl_ctx, jl_value_t *a, jl_value_t *b, int check_valid)
722+
static value_t julia_to_list2(jl_ast_context_t *ctx, jl_value_t *a, jl_value_t *b, int check_valid)
704723
{
705-
value_t sa = julia_to_scm_(fl_ctx, a, check_valid);
724+
fl_context_t *fl_ctx = &ctx->fl;
725+
value_t sa = julia_to_scm_(ctx, a, check_valid);
706726
fl_gc_handle(fl_ctx, &sa);
707-
value_t sb = julia_to_scm_(fl_ctx, b, check_valid);
727+
value_t sb = julia_to_scm_(ctx, b, check_valid);
708728
value_t l = fl_list2(fl_ctx, sa, sb);
709729
fl_free_gc_handles(fl_ctx, 1);
710730
return l;
@@ -778,12 +798,13 @@ static value_t julia_to_list2_noalloc(fl_context_t *fl_ctx, jl_value_t *a, jl_va
778798
return l;
779799
}
780800

781-
static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_valid)
801+
static value_t julia_to_scm_(jl_ast_context_t *ctx, jl_value_t *v, int check_valid)
782802
{
783803
// The following code will take internal pointers to v's fields. We need to make sure
784804
// that v will not be moved by GC.
785-
OBJ_PIN(v);
805+
arraylist_push(&ctx->pinned_objects, v);
786806
value_t retval;
807+
fl_context_t *fl_ctx = &ctx->fl;
787808
if (julia_to_scm_noalloc1(fl_ctx, v, &retval))
788809
return retval;
789810
if (jl_is_expr(v)) {
@@ -792,12 +813,12 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_vali
792813
fl_gc_handle(fl_ctx, &args);
793814
if (jl_expr_nargs(ex) > 520000 && ex->head != jl_block_sym)
794815
lerror(fl_ctx, symbol(fl_ctx, "error"), "expression too large");
795-
array_to_list(fl_ctx, ex->args, &args, check_valid);
796-
value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)ex->head, check_valid);
816+
array_to_list(ctx, ex->args, &args, check_valid);
817+
value_t hd = julia_to_scm_(ctx, (jl_value_t*)ex->head, check_valid);
797818
if (ex->head == jl_lambda_sym && jl_expr_nargs(ex)>0 && jl_is_array(jl_exprarg(ex,0))) {
798819
value_t llist = fl_ctx->NIL;
799820
fl_gc_handle(fl_ctx, &llist);
800-
array_to_list(fl_ctx, (jl_array_t*)jl_exprarg(ex,0), &llist, check_valid);
821+
array_to_list(ctx, (jl_array_t*)jl_exprarg(ex,0), &llist, check_valid);
801822
car_(args) = llist;
802823
fl_free_gc_handles(fl_ctx, 1);
803824
}
@@ -813,26 +834,26 @@ static value_t julia_to_scm_(fl_context_t *fl_ctx, jl_value_t *v, int check_vali
813834
jl_value_t *line = jl_fieldref(v,0);
814835
value_t args = julia_to_list2_noalloc(fl_ctx, line, file, check_valid);
815836
fl_gc_handle(fl_ctx, &args);
816-
value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)jl_line_sym, check_valid);
837+
value_t hd = julia_to_scm_(ctx, (jl_value_t*)jl_line_sym, check_valid);
817838
value_t scmv = fl_cons(fl_ctx, hd, args);
818839
fl_free_gc_handles(fl_ctx, 1);
819840
return scmv;
820841
}
821842
if (jl_typetagis(v, jl_gotonode_type))
822843
return julia_to_list2_noalloc(fl_ctx, (jl_value_t*)jl_goto_sym, jl_fieldref(v,0), check_valid);
823844
if (jl_typetagis(v, jl_quotenode_type))
824-
return julia_to_list2(fl_ctx, (jl_value_t*)jl_inert_sym, jl_fieldref_noalloc(v,0), 0);
845+
return julia_to_list2(ctx, (jl_value_t*)jl_inert_sym, jl_fieldref_noalloc(v,0), 0);
825846
if (jl_typetagis(v, jl_newvarnode_type))
826847
return julia_to_list2_noalloc(fl_ctx, (jl_value_t*)jl_newvar_sym, jl_fieldref(v,0), check_valid);
827848
if (jl_typetagis(v, jl_globalref_type)) {
828849
jl_module_t *m = jl_globalref_mod(v);
829850
jl_sym_t *sym = jl_globalref_name(v);
830851
if (m == jl_core_module)
831-
return julia_to_list2(fl_ctx, (jl_value_t*)jl_core_sym,
852+
return julia_to_list2(ctx, (jl_value_t*)jl_core_sym,
832853
(jl_value_t*)sym, check_valid);
833-
value_t args = julia_to_list2(fl_ctx, (jl_value_t*)m, (jl_value_t*)sym, check_valid);
854+
value_t args = julia_to_list2(ctx, (jl_value_t*)m, (jl_value_t*)sym, check_valid);
834855
fl_gc_handle(fl_ctx, &args);
835-
value_t hd = julia_to_scm_(fl_ctx, (jl_value_t*)jl_globalref_sym, check_valid);
856+
value_t hd = julia_to_scm_(ctx, (jl_value_t*)jl_globalref_sym, check_valid);
836857
value_t scmv = fl_cons(fl_ctx, hd, args);
837858
fl_free_gc_handles(fl_ctx, 1);
838859
return scmv;
@@ -900,8 +921,8 @@ JL_DLLEXPORT jl_value_t *jl_fl_parse(const char *text, size_t text_len,
900921
static jl_value_t *jl_call_scm_on_ast(const char *funcname, jl_value_t *expr, jl_module_t *inmodule)
901922
{
902923
jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
924+
value_t arg = julia_to_scm(ctx, expr);
903925
fl_context_t *fl_ctx = &ctx->fl;
904-
value_t arg = julia_to_scm(fl_ctx, expr);
905926
value_t e = fl_applyn(fl_ctx, 1, symbol_value(symbol(fl_ctx, funcname)), arg);
906927
jl_value_t *result = scm_to_julia(fl_ctx, e, inmodule);
907928
JL_GC_PUSH1(&result);
@@ -914,8 +935,8 @@ jl_value_t *jl_call_scm_on_ast_and_loc(const char *funcname, jl_value_t *expr,
914935
jl_module_t *inmodule, const char *file, int line)
915936
{
916937
jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
938+
value_t arg = julia_to_scm(ctx, expr);
917939
fl_context_t *fl_ctx = &ctx->fl;
918-
value_t arg = julia_to_scm(fl_ctx, expr);
919940
value_t e = fl_applyn(fl_ctx, 3, symbol_value(symbol(fl_ctx, funcname)), arg,
920941
symbol(fl_ctx, file), fixnum(line));
921942
jl_value_t *result = scm_to_julia(fl_ctx, e, inmodule);
@@ -1316,8 +1337,8 @@ JL_DLLEXPORT jl_value_t *jl_expand_with_loc_warn(jl_value_t *expr, jl_module_t *
13161337
expr = jl_copy_ast(expr);
13171338
expr = jl_expand_macros(expr, inmodule, NULL, 0, ~(size_t)0, 1);
13181339
jl_ast_context_t *ctx = jl_ast_ctx_enter(inmodule);
1340+
value_t arg = julia_to_scm(ctx, expr);
13191341
fl_context_t *fl_ctx = &ctx->fl;
1320-
value_t arg = julia_to_scm(fl_ctx, expr);
13211342
value_t e = fl_applyn(fl_ctx, 4, symbol_value(symbol(fl_ctx, "jl-expand-to-thunk-warn")), arg,
13221343
symbol(fl_ctx, file), fixnum(line), fl_ctx->F);
13231344
expr = scm_to_julia(fl_ctx, e, inmodule);

src/gc-mmtk.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection) {
254254
// print_fragmentation();
255255
}
256256

257-
void gc_pin_objects_from_inference_engine(arraylist_t *objects_pinned_by_call)
257+
void gc_pin_objects_from_compiler_frontend(arraylist_t *objects_pinned_by_call)
258258
{
259259
for (size_t i = 0; i < gc_pinned_objects.len; i++) {
260260
void *obj = gc_pinned_objects.items[i];
@@ -263,9 +263,20 @@ void gc_pin_objects_from_inference_engine(arraylist_t *objects_pinned_by_call)
263263
arraylist_push(objects_pinned_by_call, obj);
264264
}
265265
}
266+
for (size_t i = 0; i < jl_ast_ctx_used.len; i++) {
267+
void *ctx = jl_ast_ctx_used.items[i];
268+
arraylist_t *pinned_objects = extract_pinned_objects_from_ast_ctx(ctx);
269+
for (size_t j = 0; j < pinned_objects->len; j++) {
270+
void *obj = pinned_objects->items[j];
271+
unsigned char got_pinned = mmtk_pin_object(obj);
272+
if (got_pinned) {
273+
arraylist_push(objects_pinned_by_call, obj);
274+
}
275+
}
276+
}
266277
}
267278

268-
void gc_unpin_objects_from_inference_engine(arraylist_t *objects_pinned_by_call)
279+
void gc_unpin_objects_from_compiler_frontend(arraylist_t *objects_pinned_by_call)
269280
{
270281
for (size_t i = 0; i < objects_pinned_by_call->len; i++) {
271282
void *obj = objects_pinned_by_call->items[i];
@@ -337,9 +348,9 @@ JL_DLLEXPORT void jl_gc_prepare_to_collect(void)
337348
#ifndef __clang_gcanalyzer__
338349
arraylist_t objects_pinned_by_call;
339350
arraylist_new(&objects_pinned_by_call, 0);
340-
gc_pin_objects_from_inference_engine(&objects_pinned_by_call);
351+
gc_pin_objects_from_compiler_frontend(&objects_pinned_by_call);
341352
mmtk_block_thread_for_gc();
342-
gc_unpin_objects_from_inference_engine(&objects_pinned_by_call);
353+
gc_unpin_objects_from_compiler_frontend(&objects_pinned_by_call);
343354
arraylist_free(&objects_pinned_by_call);
344355
#endif
345356
JL_UNLOCK_NOGC(&finalizers_lock);

src/julia.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2439,6 +2439,8 @@ JL_DLLEXPORT void jl_register_newmeth_tracer(void (*callback)(jl_method_t *trace
24392439

24402440
// AST access
24412441
JL_DLLEXPORT jl_value_t *jl_copy_ast(jl_value_t *expr JL_MAYBE_UNROOTED);
2442+
arraylist_t *extract_pinned_objects_from_ast_ctx(void *ctx);
2443+
extern arraylist_t jl_ast_ctx_used;
24422444

24432445
// IR representation
24442446
JL_DLLEXPORT jl_value_t *jl_compress_ir(jl_method_t *m, jl_code_info_t *code);

0 commit comments

Comments
 (0)