Skip to content

Commit

Permalink
record binding module in new generic functions
Browse files Browse the repository at this point in the history
  • Loading branch information
vtjnash committed Jul 17, 2015
1 parent fee6081 commit 22dfad5
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 34 deletions.
46 changes: 35 additions & 11 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,18 @@ static void jl_serialize_value_(ios_t *s, jl_value_t *v)
}
else if (jl_is_function(v)) {
writetag(s, jl_function_type);
if (mode == MODE_MODULE || mode == MODE_MODULE_POSTWORK) {
if (jl_is_gf(v)) {
jl_methtable_t *mt = jl_gf_mtable(v);
if (mt->module && !module_in_worklist(mt->module)) {
write_int8(s, 1);
jl_serialize_value(s, (jl_value_t*)mt->module);
jl_serialize_value(s, (jl_value_t*)mt->name);
return;
}
}
write_int8(s, 0);
}
jl_function_t *f = (jl_function_t*)v;
jl_serialize_value(s, (jl_value_t*)f->linfo);
jl_serialize_value(s, f->env);
Expand Down Expand Up @@ -846,20 +858,22 @@ static void jl_serialize_value_(ios_t *s, jl_value_t *v)
}
}

static void jl_serialize_methtable_from_mod(ios_t *s, jl_module_t *m, jl_sym_t *name, jl_methtable_t *mt, int8_t iskw)
static void jl_serialize_methtable_from_mod(ios_t *s, jl_methtable_t *mt, int8_t iskw)
{
if (iskw) {
if (!mt->kwsorter)
return;
assert(jl_is_gf(mt->kwsorter));
assert(mt->module == jl_gf_mtable(mt->kwsorter)->module);
mt = jl_gf_mtable(mt->kwsorter);
assert(!mt->kwsorter);
}
assert(mt->module);
jl_methlist_t *ml = mt->defs;
while (ml != (void*)jl_nothing) {
if (module_in_worklist(ml->func->linfo->module)) {
jl_serialize_value(s, m);
jl_serialize_value(s, name);
jl_serialize_value(s, mt->module);
jl_serialize_value(s, mt->name);
write_int8(s, iskw);
jl_serialize_value(s, ml->sig);
jl_serialize_value(s, ml->func);
Expand All @@ -882,15 +896,13 @@ static void jl_serialize_lambdas_from_mod(ios_t *s, jl_module_t *m)
if (table[i] != HT_NOTFOUND) {
jl_binding_t *b = (jl_binding_t*)table[i];
if (b->owner == m && b->value && b->constp) {
if (jl_is_function(b->value)) {
if (jl_is_function(b->value) && jl_is_gf(b->value)) {
jl_function_t *gf = (jl_function_t*)b->value;
if (jl_is_gf(gf)) {
// TODO: verify this is not an alternative name for the gf
jl_methtable_t *mt = jl_gf_mtable(gf);
jl_serialize_methtable_from_mod(s, m, b->name, mt, 0);
jl_serialize_methtable_from_mod(s, m, b->name, mt, 1);
jl_methtable_t *mt = jl_gf_mtable(gf);
if (mt->name == b->name && mt->module == m) {
jl_serialize_methtable_from_mod(s, mt, 0);
jl_serialize_methtable_from_mod(s, mt, 1);
}
//TODO: look in datatype cache?
}
else if (jl_is_module(b->value)) {
jl_module_t *child = (jl_module_t*)b->value;
Expand Down Expand Up @@ -1194,6 +1206,18 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t
return (jl_value_t*)tv;
}
else if (vtag == (jl_value_t*)jl_function_type) {
if (mode == MODE_MODULE || mode == MODE_MODULE_POSTWORK) {
int ref_only = read_int8(s);
if (ref_only) {
int pos = backref_list.len;
arraylist_push(&backref_list, NULL);
jl_module_t *module = (jl_module_t*)jl_deserialize_value(s, NULL);
jl_sym_t *name = (jl_sym_t*)jl_deserialize_value(s, NULL);
jl_value_t *f = jl_get_global(module, name);
backref_list.items[pos] = f;
return f;
}
}
jl_function_t *f =
(jl_function_t*)newobj((jl_value_t*)jl_function_type, NWORDS(sizeof(jl_function_t)));
if (usetable)
Expand Down Expand Up @@ -1426,7 +1450,7 @@ void jl_deserialize_lambdas_from_mod(ios_t *s)
if (iskw) {
jl_methtable_t* mt = jl_gf_mtable(gf);
if (!mt->kwsorter) {
mt->kwsorter = jl_new_generic_function(jl_gf_name(gf));
mt->kwsorter = jl_new_generic_function(jl_gf_name(gf), mt->module);
jl_gc_wb(mt, mt->kwsorter);
}
gf = mt->kwsorter;
Expand Down
18 changes: 7 additions & 11 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ static jl_value_t *jl_apply_unspecialized(jl_function_t *meth, jl_value_t **args
}


static jl_methtable_t *new_method_table(jl_sym_t *name)
static jl_methtable_t *new_method_table(jl_sym_t *name, jl_module_t *module)
{
jl_methtable_t *mt = (jl_methtable_t*)jl_gc_allocobj(sizeof(jl_methtable_t));
jl_set_typeof(mt, jl_methtable_type);
mt->name = name;
mt->module = module;
mt->defs = (jl_methlist_t*)jl_nothing;
mt->cache = (jl_methlist_t*)jl_nothing;
mt->cache_arg1 = (jl_array_t*)jl_nothing;
Expand Down Expand Up @@ -1753,7 +1754,7 @@ jl_value_t *jl_gf_invoke(jl_function_t *gf, jl_tupletype_t *types,
JL_GC_PUSH3(&tpenv, &newsig, &tt);
tt = arg_type_tuple(args, nargs);
if (m->invokes == (void*)jl_nothing) {
m->invokes = new_method_table(mt->name);
m->invokes = new_method_table(mt->name, mt->module);
jl_gc_wb(m, m->invokes);
update_max_args(m->invokes, tt);
// this private method table has just this one definition
Expand Down Expand Up @@ -1794,18 +1795,13 @@ void print_func_loc(JL_STREAM *s, jl_lambda_info_t *li)
}
}

void jl_initialize_generic_function(jl_function_t *f, jl_sym_t *name)
{
f->fptr = jl_apply_generic;
f->env = (jl_value_t*)new_method_table(name);
jl_gc_wb(f, f->env);
}

jl_function_t *jl_new_generic_function(jl_sym_t *name)
jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module)
{
jl_function_t *f = jl_new_closure(jl_apply_generic, NULL, NULL);
JL_GC_PUSH1(&f);
jl_initialize_generic_function(f, name);
f->fptr = jl_apply_generic;
f->env = (jl_value_t*)new_method_table(name, module);
jl_gc_wb(f, f->env);
JL_GC_POP();
return f;
}
Expand Down
14 changes: 8 additions & 6 deletions src/jltypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3290,13 +3290,14 @@ void jl_init_types(void)

jl_methtable_type =
jl_new_datatype(jl_symbol("MethodTable"), jl_any_type, jl_emptysvec,
jl_svec(7, jl_symbol("name"), jl_symbol("defs"),
jl_svec(8, jl_symbol("name"), jl_symbol("defs"),
jl_symbol("cache"), jl_symbol("cache_arg1"),
jl_symbol("cache_targ"),
jl_symbol("max_args"), jl_symbol("kwsorter")),
jl_svec(7, jl_sym_type, jl_any_type, jl_any_type,
jl_any_type, jl_any_type, jl_long_type,
jl_any_type),
jl_symbol("cache_targ"), jl_symbol("max_args"),
jl_symbol("kwsorter"), jl_symbol("module")),
jl_svec(8, jl_sym_type, jl_any_type,
jl_any_type, jl_any_type,
jl_any_type, jl_long_type,
jl_any_type, jl_any_type),
0, 1, 6);

tv = jl_svec2(tvar("T"), tvar("N"));
Expand Down Expand Up @@ -3381,6 +3382,7 @@ void jl_init_types(void)
jl_svec(2, jl_module_type, jl_sym_type), 0, 0, 2);

jl_svecset(jl_typename_type->types, 1, jl_module_type);
jl_svecset(jl_methtable_type->types, 7, jl_module_type);

jl_lambda_info_type =
jl_new_datatype(jl_symbol("LambdaStaticData"),
Expand Down
3 changes: 2 additions & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ typedef struct _jl_methtable_t {
jl_array_t *cache_targ;
ptrint_t max_args; // max # of non-vararg arguments in a signature
jl_function_t *kwsorter; // keyword argument sorter function
jl_module_t *module; // used for incremental serialization to locate original binding
#ifdef JL_GF_PROFILE
int ncalls;
#endif
Expand Down Expand Up @@ -924,7 +925,7 @@ DLLEXPORT jl_sym_t *jl_gensym(void);
DLLEXPORT jl_sym_t *jl_tagged_gensym(const char *str, int32_t len);
DLLEXPORT jl_sym_t *jl_get_root_symbol(void);
jl_expr_t *jl_exprn(jl_sym_t *head, size_t n);
jl_function_t *jl_new_generic_function(jl_sym_t *name);
jl_function_t *jl_new_generic_function(jl_sym_t *name, jl_module_t *module);
void jl_add_method(jl_function_t *gf, jl_tupletype_t *types, jl_function_t *meth,
jl_svec_t *tvars, int8_t isstaged);
DLLEXPORT jl_value_t *jl_generic_function_def(jl_sym_t *name, jl_value_t **bp, jl_value_t *bp_owner,
Expand Down
1 change: 0 additions & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ jl_datatype_t *jl_inst_concrete_tupletype_v(jl_value_t **p, size_t np);
jl_datatype_t *jl_inst_concrete_tupletype(jl_svec_t *p);

void jl_set_datatype_super(jl_datatype_t *tt, jl_value_t *super);
void jl_initialize_generic_function(jl_function_t *f, jl_sym_t *name);
void jl_add_constructors(jl_datatype_t *t);

jl_value_t *jl_nth_slot_type(jl_tupletype_t *sig, size_t i);
Expand Down
13 changes: 9 additions & 4 deletions src/toplevel.c
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,8 @@ DLLEXPORT jl_value_t *jl_generic_function_def(jl_sym_t *name, jl_value_t **bp, j
if (bnd)
bnd->constp = 1;
if (*bp == NULL) {
gf = (jl_value_t*)jl_new_generic_function(name);
jl_module_t *module = (bnd ? bnd->owner : NULL);
gf = (jl_value_t*)jl_new_generic_function(name, module);
*bp = gf;
if (bp_owner) jl_gc_wb(bp_owner, gf);
}
Expand Down Expand Up @@ -709,6 +710,7 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_value_t
jl_svec_t *argdata, jl_function_t *f, jl_value_t *isstaged,
jl_value_t *call_func, int iskw)
{
jl_module_t *module = (bnd ? bnd->owner : NULL);
// argdata is svec({types...}, svec(typevars...))
jl_tupletype_t *argtypes = (jl_tupletype_t*)jl_svecref(argdata,0);
jl_svec_t *tvars = (jl_svec_t*)jl_svecref(argdata,1);
Expand Down Expand Up @@ -780,8 +782,11 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_value_t
}
}
if (iskw) {
bp = (jl_value_t**)&((jl_methtable_t*)((jl_function_t*)gf)->env)->kwsorter;
bp_owner = (jl_value_t*)((jl_function_t*)gf)->env;
jl_methtable_t *mt = jl_gf_mtable(gf);
assert(!module);
module = mt->module;
bp = (jl_value_t**)&mt->kwsorter;
bp_owner = (jl_value_t*)mt;
gf = *bp;
}
}
Expand Down Expand Up @@ -814,7 +819,7 @@ DLLEXPORT jl_value_t *jl_method_def(jl_sym_t *name, jl_value_t **bp, jl_value_t
bnd->constp = 1;
}
if (*bp == NULL) {
gf = (jl_value_t*)jl_new_generic_function(name);
gf = (jl_value_t*)jl_new_generic_function(name, module);
*bp = gf;
if (bp_owner) jl_gc_wb(bp_owner, gf);
}
Expand Down

0 comments on commit 22dfad5

Please sign in to comment.