Skip to content

Commit 2840b13

Browse files
committed
Add tracing of specializations/new methods
This adds a new API that allows code to register two callbacks to be informed of new specializations/methods in the system: - jl_register_tracer, which will call the passed callback on any newly added specialization of a lambda info that has the `traced` flag set. - jl_register_newmeth_tracer, which will call the passed callback on any newly created method in the system.
1 parent 810e53f commit 2840b13

File tree

5 files changed

+45
-1
lines changed

5 files changed

+45
-1
lines changed

src/alloc.c

+1
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ jl_lambda_info_t *jl_new_lambda_info(jl_value_t *ast, jl_svec_t *tvars, jl_svec_
373373
li->pure = 0;
374374
li->called = 0xff;
375375
li->needs_sparam_vals_ducttape = 2;
376+
li->traced = 0;
376377
if (ast != NULL) {
377378
JL_GC_PUSH1(&li);
378379
jl_lambda_info_set_ast(li, ast);

src/dump.c

+1
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,7 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t
14751475
jl_delayed_fptrs(li, func_llvm, cfunc_llvm);
14761476
li->jlcall_api = func_llvm ? read_int8(s) : 0;
14771477
li->needs_sparam_vals_ducttape = read_int8(s);
1478+
li->traced = 0;
14781479
return (jl_value_t*)li;
14791480
}
14801481
else if (vtag == (jl_value_t*)jl_module_type) {

src/gf.c

+9-1
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,8 @@ static int is_kind(jl_value_t *v)
465465
static jl_value_t *ml_matches(jl_methlist_t *ml, jl_value_t *type,
466466
jl_sym_t *name, int lim);
467467

468+
extern void (*jl_linfo_tracer)(jl_lambda_info_t *tracee);
469+
468470
static jl_lambda_info_t *cache_method(jl_methtable_t *mt, jl_tupletype_t *type,
469471
jl_lambda_info_t *method, jl_methlist_t *m,
470472
jl_svec_t *sparams)
@@ -839,6 +841,8 @@ static jl_lambda_info_t *cache_method(jl_methtable_t *mt, jl_tupletype_t *type,
839841
}
840842
JL_GC_POP();
841843
JL_UNLOCK(codegen);
844+
if (method->traced)
845+
jl_linfo_tracer(newmeth);
842846
return newmeth;
843847
}
844848

@@ -2020,6 +2024,8 @@ JL_DLLEXPORT jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t
20202024
return jl_new_generic_function_with_supertype(name, module, jl_function_type, 0);
20212025
}
20222026

2027+
2028+
extern void (*jl_newmeth_tracer)(jl_methlist_t *tracee);
20232029
void jl_add_method_to_table(jl_methtable_t *mt, jl_tupletype_t *types, jl_lambda_info_t *meth,
20242030
jl_svec_t *tvars, int8_t isstaged)
20252031
{
@@ -2035,7 +2041,9 @@ void jl_add_method_to_table(jl_methtable_t *mt, jl_tupletype_t *types, jl_lambda
20352041
meth->unspecialized = NULL;
20362042
}
20372043
meth->name = n;
2038-
(void)jl_method_table_insert(mt, types, meth, tvars, isstaged);
2044+
jl_methlist_t *newmeth = jl_method_table_insert(mt, types, meth, tvars, isstaged);
2045+
if (jl_newmeth_tracer)
2046+
jl_newmeth_tracer(newmeth);
20392047
JL_GC_POP();
20402048
}
20412049

src/jlapi.c

+25
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,31 @@ JL_DLLEXPORT const char *jl_git_commit(void)
308308
return commit;
309309
}
310310

311+
JL_DLLEXPORT void jl_trace_linfo(jl_lambda_info_t *li)
312+
{
313+
assert(jl_is_lambda_info(li));
314+
li->traced = 1;
315+
}
316+
317+
JL_DLLEXPORT void jl_untrace_linfo(jl_lambda_info_t *li)
318+
{
319+
assert(jl_is_lambda_info(li));
320+
li->traced = 0;
321+
}
322+
323+
void (*jl_linfo_tracer)(jl_lambda_info_t *tracee) = 0;
324+
JL_DLLEXPORT void jl_register_tracer(void (*callback)(jl_lambda_info_t *tracee))
325+
{
326+
jl_linfo_tracer = callback;
327+
}
328+
329+
void (*jl_newmeth_tracer)(jl_methlist_t *tracee) = 0;
330+
JL_DLLEXPORT void jl_register_newmeth_tracer(void (*callback)(jl_methlist_t *tracee))
331+
{
332+
jl_newmeth_tracer = callback;
333+
}
334+
335+
311336
// Create function versions of some useful macros
312337
JL_DLLEXPORT jl_taggedvalue_t *(jl_astaggedvalue)(jl_value_t *v)
313338
{

src/julia.h

+9
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ typedef struct _jl_lambda_info_t {
210210
// and so unspecialized will be created for each linfo instead of once in linfo->def.
211211
// 0 = no, 1 = yes, 2 = not yet known
212212
uint8_t needs_sparam_vals_ducttape : 2;
213+
// If this flag is set, the system will call a callback if a specialization
214+
// is added to this lambda info. See jl_register_tracer below.
215+
uint8_t traced : 1;
213216
jl_fptr_t fptr; // jlcall entry point
214217

215218
// On the old JIT, handles to all Functions generated for this linfo
@@ -1243,6 +1246,12 @@ JL_DLLEXPORT jl_value_t *jl_interpret_toplevel_expr_in(jl_module_t *m, jl_value_
12431246
jl_lambda_info_t *lam);
12441247
JL_DLLEXPORT jl_module_t *jl_base_relative_to(jl_module_t *m);
12451248

1249+
// tracing
1250+
JL_DLLEXPORT void jl_trace_linfo(jl_lambda_info_t *li);
1251+
JL_DLLEXPORT void jl_untrace_linfo(jl_lambda_info_t *li);
1252+
JL_DLLEXPORT void jl_register_tracer(void (*callback)(jl_lambda_info_t *tracee));
1253+
JL_DLLEXPORT void jl_register_newmeth_tracer(void (*callback)(jl_methlist_t *tracee));
1254+
12461255
// AST access
12471256
JL_DLLEXPORT int jl_is_rest_arg(jl_value_t *ex);
12481257

0 commit comments

Comments
 (0)