Skip to content

Commit 35e0911

Browse files
committed
remove ast from the Method, but make unspecialized also valid and owner of the uninferred ast
also rename li->unspecialized to li->unspecialized_ducttape, to make clear that this field is a temporary workaround until the interpreter is fully-functional
1 parent 9e81a75 commit 35e0911

14 files changed

+167
-227
lines changed

base/boot.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,16 @@
6060
#end
6161

6262
#type LambdaInfo
63-
# inferred_ast::Expr
63+
# ast::Union{Expr, Vector{UInt8}}
6464
# rettype::Any
6565
# sparam_vals::SimpleVector
6666
# specTypes::Any
67-
# unspecialized::LambdaInfo
67+
# unspecialized_ducttape::LambdaInfo
6868
# def::Method
6969
# pure::Bool
7070
#end
7171

7272
#type Method
73-
# ast::Expr
7473
# sig::Type
7574
# tvars::Expr
7675
# sparam_syms::SimpleVector
@@ -317,7 +316,7 @@ TypeVar(n::Symbol, lb::ANY, ub::ANY, b::Bool) =
317316
ccall(:jl_new_typevar_, Any, (Any, Any, Any, Any), n, lb::Type, ub::Type, b)::TypeVar
318317

319318
TypeConstructor(p::ANY, t::ANY) = ccall(:jl_new_type_constructor, Any, (Any, Any), p::SimpleVector, t::Type)
320-
LambdaInfo(ast::Method, sparam_vals::SimpleVector, specTypes::DataType) = ccall(:jl_new_lambda_info, Any, (Any, Any, Any), ast, sparam_vals, specTypes)
319+
LambdaInfo(ast::Method, sparam_vals::SimpleVector, specTypes::DataType) = ccall(:jl_spec_lambda_info, Any, (Any, Any, Any), ast.unspecialized, sparam_vals, specTypes)
321320

322321
Void() = nothing
323322

base/inference.jl

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type VarInfo
2929
mod::Module
3030
end
3131

32-
function VarInfo(linfo::LambdaInfo, ast=linfo.inferred_ast)
32+
function VarInfo(linfo::LambdaInfo, ast=linfo.def.unspecialized.ast)
3333
if !isa(ast,Expr)
3434
ast = ccall(:jl_uncompress_ast, Any, (Any,Any), linfo.def, ast)
3535
end
@@ -65,15 +65,15 @@ type EmptyCallStack
6565
end
6666

6767
type CallStack
68-
ast
68+
meth::Method
6969
types::Type
7070
recurred::Bool
7171
cycleid::Int
7272
result
7373
prev::Union{EmptyCallStack,CallStack}
7474
sv::VarInfo
7575

76-
CallStack(ast, types::ANY, prev) = new(ast, types, false, 0, Bottom, prev)
76+
CallStack(meth, types::ANY, prev) = new(meth, types, false, 0, Bottom, prev)
7777
end
7878

7979
inference_stack = EmptyCallStack()
@@ -741,7 +741,7 @@ function abstract_call_gf_by_type(f::ANY, argtype::ANY, e)
741741
limit = false
742742
# look at the stack to detect recursive calls with growing argument lists
743743
while sp !== EmptyCallStack()
744-
if linfo.def.ast === sp.ast && length(argtypes) > length(sp.types.parameters)
744+
if linfo.def === sp.meth && length(argtypes) > length(sp.types.parameters)
745745
limit = true; break
746746
end
747747
sp = sp.prev
@@ -1440,7 +1440,7 @@ function typeinf(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector, def::Met
14401440
end
14411441
# TODO: typeinf currently gets stuck without this
14421442
if def.name === :abstract_interpret || def.name === :tuple_elim_pass || def.name === :abstract_call_gf
1443-
return (def.ast, Any)
1443+
return (def.unspecialized.ast, Any)
14441444
end
14451445

14461446
(fulltree, result, rec) = typeinf_uncached(linfo, atypes, sparams, def, curtype, cop, true)
@@ -1485,7 +1485,6 @@ tupletype_tail(t::ANY, n) = Tuple{t.parameters[n:end]...}
14851485

14861486
# compute an inferred (optionally optimized) AST without global effects (i.e. updating the cache)
14871487
function typeinf_uncached(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector, def::Method, curtype, cop, optimize)
1488-
ast0 = def.ast
14891488
#if dbg
14901489
# print("typeinf ", def.name, " ", object_id(ast0), "\n")
14911490
#end
@@ -1501,7 +1500,7 @@ function typeinf_uncached(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector,
15011500

15021501
f = inference_stack
15031502
while !isa(f,EmptyCallStack)
1504-
if is(f.ast,ast0)
1503+
if is(f.meth, def)
15051504
# impose limit if we recur and the argument types grow beyond MAX_TYPE_DEPTH
15061505
td = type_depth(atypes)
15071506
if td > type_depth(f.types)
@@ -1540,7 +1539,7 @@ function typeinf_uncached(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector,
15401539
# check for recursion
15411540
f = inference_stack
15421541
while !isa(f,EmptyCallStack)
1543-
if (is(f.ast,ast0) || f.ast==ast0) && typeseq(f.types, atypes)
1542+
if (is(f.meth, def) || f.meth.unspecialized.ast == def.unspecialized.ast) && typeseq(f.types, atypes)
15441543
# return best guess so far
15451544
(f::CallStack).recurred = true
15461545
(f::CallStack).cycleid = CYCLE_ID
@@ -1567,7 +1566,7 @@ function typeinf_uncached(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector,
15671566
if cop
15681567
ast = ccall(:jl_prepare_ast, Any, (Any,), def)::Expr
15691568
else
1570-
ast = linfo.inferred_ast
1569+
ast = linfo.ast
15711570
end
15721571

15731572
sv = VarInfo(linfo, ast)
@@ -1605,7 +1604,7 @@ function typeinf_uncached(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector,
16051604
end
16061605

16071606
# our stack frame
1608-
frame = CallStack(ast0, atypes, inference_stack)
1607+
frame = CallStack(def, atypes, inference_stack)
16091608
frame.sv = sv
16101609
inference_stack = frame
16111610
frame.result = curtype
@@ -1810,7 +1809,7 @@ function typeinf_uncached(linfo::LambdaInfo, atypes::ANY, sparams::SimpleVector,
18101809
# for an example see test/libgit2.jl on 0.5-pre master
18111810
# around e.g. commit c072d1ce73345e153e4fddf656cda544013b1219
18121811
inference_stack = (inference_stack::CallStack).prev
1813-
return (ast0, Any, false)
1812+
return (def.unspecialized.ast, Any, false)
18141813
end
18151814
end
18161815
handler_at[l] = cur_hand
@@ -2339,7 +2338,7 @@ function inlineable(f::ANY, ft::ANY, e::Expr, atype::ANY, sv::VarInfo, enclosing
23392338
# # check call stack to see if this argument list is growing
23402339
# st = inference_stack
23412340
# while !isa(st, EmptyCallStack)
2342-
# if st.ast === linfo.def.ast && length(atypes) > length(st.types)
2341+
# if st.meth === linfo.def && length(atypes) > length(st.types)
23432342
# atypes = limit_tuple_type(atypes)
23442343
# meth = _methods(f, atypes, 1)
23452344
# if meth === false || length(meth) != 1

base/reflection.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,8 @@ done(mt::MethodTable, m::Method) = false
245245
done(mt::MethodTable, i::Void) = true
246246

247247
uncompressed_ast(l::LambdaInfo) =
248-
isa(l.inferred_ast,Expr) ? l.inferred_ast : ccall(:jl_uncompress_ast, Any, (Any,Any), l.def, l.inferred_ast)
249-
uncompressed_ast(l::Method) =
250-
isa(l.ast,Expr) ? l.ast : ccall(:jl_uncompress_ast, Any, (Any,Any), l, l.ast)
248+
isa(l.ast, Expr) ? l.ast : ccall(:jl_uncompress_ast, Any, (Any,Any), l.def, l.ast)
249+
uncompressed_ast(l::Method) = uncompressed_ast(l.unspecialized)
251250

252251
# Printing code representations in IR and assembly
253252
function _dump_function(f, t::ANY, native, wrapper, strip_ir_metadata, dump_module)

base/serialize.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ const TAGS = Any[
1919
#LongSymbol, LongTuple, LongExpr,
2020
Symbol, Tuple, Expr, # dummy entries, intentionally shadowed by earlier ones
2121
LineNumberNode, SymbolNode, LabelNode, GotoNode,
22-
QuoteNode, TopNode, TypeVar, Box, Method,
22+
QuoteNode, TopNode, TypeVar, Box, :reserved00,
2323
Module, #=UndefRefTag=#Symbol, Task, ASCIIString, UTF8String,
2424
UTF16String, UTF32String, Float16,
2525
SimpleVector, #=BackrefTag=#Symbol, :reserved11, :reserved12,
@@ -72,7 +72,6 @@ const BACKREF_TAG = Int32(sertag(SimpleVector)+1)
7272
const EXPR_TAG = sertag(Expr)
7373
const LONGEXPR_TAG = Int32(sertag(Expr)+3)
7474
const MODULE_TAG = sertag(Module)
75-
const METHODDATA_TAG = sertag(Method)
7675
const TASK_TAG = sertag(Task)
7776
const DATATYPE_TAG = sertag(DataType)
7877
const TYPENAME_TAG = sertag(TypeName)

src/alloc.c

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -280,16 +280,14 @@ JL_DLLEXPORT jl_method_info_t *jl_new_method_info(jl_value_t *ast, jl_svec_t *tv
280280
jl_method_info_t *li =
281281
(jl_method_info_t*)newobj((jl_value_t*)jl_method_info_type,
282282
NWORDS(sizeof(jl_method_info_t)));
283-
li->ast = ast;
283+
JL_GC_PUSH1(&li);
284284
li->sig = NULL;
285285
li->tvars = NULL;
286286
li->next = NULL;
287287
li->file = null_sym;
288288
li->line = 0;
289-
li->pure = 0;
290289
li->isstaged = 0;
291290
li->va = 0;
292-
li->called = 0xff;
293291
li->module = ctx;
294292
li->sparam_syms = tvars;
295293
li->tfunc = jl_nothing;
@@ -299,10 +297,11 @@ JL_DLLEXPORT jl_method_info_t *jl_new_method_info(jl_value_t *ast, jl_svec_t *tv
299297
li->invokes = (jl_methtable_t*)jl_nothing;
300298
li->next = (jl_method_info_t*)jl_nothing;
301299
li->unspecialized = NULL;
300+
uint8_t pure = 0, called = 0xff;
302301
if (ast != NULL && jl_is_expr(ast)) {
303302
jl_array_t *body = jl_lam_body((jl_expr_t*)ast)->args;
304303
if (has_meta(body, pure_sym))
305-
li->pure = 1;
304+
pure = 1;
306305
jl_value_t *body1 = skip_meta(body);
307306
if (jl_is_linenode(body1)) {
308307
li->file = jl_linenode_file(body1);
@@ -312,10 +311,10 @@ JL_DLLEXPORT jl_method_info_t *jl_new_method_info(jl_value_t *ast, jl_svec_t *tv
312311
li->file = (jl_sym_t*)jl_exprarg(body1, 1);
313312
li->line = jl_unbox_long(jl_exprarg(body1, 0));
314313
}
315-
jl_array_t *vis = jl_lam_vinfo((jl_expr_t*)li->ast);
316-
jl_array_t *args = jl_lam_args((jl_expr_t*)li->ast);
314+
jl_array_t *vis = jl_lam_vinfo((jl_expr_t*)ast);
315+
jl_array_t *args = jl_lam_args((jl_expr_t*)ast);
317316
size_t narg = jl_array_len(args);
318-
uint8_t called=0;
317+
called=0;
319318
int i, j=0;
320319
for(i=1; i < narg && i <= 8; i++) {
321320
jl_value_t *ai = jl_cellref(args,i);
@@ -328,38 +327,68 @@ JL_DLLEXPORT jl_method_info_t *jl_new_method_info(jl_value_t *ast, jl_svec_t *tv
328327
if (jl_unbox_long(jl_cellref(vj,2))&64)
329328
called |= (1<<(i-1));
330329
}
331-
li->called = called;
332330
}
331+
332+
jl_lambda_info_t *unspec = jl_spec_lambda_info(NULL, jl_emptysvec, (jl_tupletype_t*)jl_anytuple_type);
333+
unspec->ast = ast;
334+
unspec->pure = pure;
335+
unspec->called = called;
336+
unspec->def = li;
337+
li->unspecialized = unspec;
338+
jl_gc_wb(li, unspec);
339+
JL_GC_POP();
333340
return li;
334341
}
335342

336-
337-
JL_DLLEXPORT jl_lambda_info_t *jl_new_lambda_info(jl_method_info_t *ast, jl_svec_t *sparam_vals, jl_datatype_t *specTypes)
343+
// return a new lambda-info that has some extra static parameters merged in.
344+
JL_DLLEXPORT jl_lambda_info_t *jl_spec_lambda_info(jl_lambda_info_t *li, jl_svec_t *sp, jl_tupletype_t *types)
338345
{
339-
jl_lambda_info_t *li =
346+
assert((li && jl_svec_len(li->def->sparam_syms) == jl_svec_len(sp)) || sp == jl_emptysvec);
347+
jl_lambda_info_t *nli =
340348
(jl_lambda_info_t*)newobj((jl_value_t*)jl_lambda_info_type,
341349
NWORDS(sizeof(jl_lambda_info_t)));
342-
li->inferred_ast = ast->ast;
343-
li->rettype = (jl_value_t*)jl_any_type;
344-
li->pure = ast->pure;
345-
li->called = ast->called;
346-
li->sparam_vals = sparam_vals;
347-
li->fptr = NULL;
348-
li->jlcall_api = 0;
349-
li->functionObjects.functionObject = NULL;
350-
li->functionObjects.specFunctionObject = NULL;
351-
li->functionObjects.cFunctionList = NULL;
352-
li->functionID = 0;
353-
li->specFunctionID = 0;
354-
li->specTypes = specTypes;
355-
li->inferred = 0;
356-
li->inInference = 0;
357-
li->inCompile = 0;
358-
li->unspecialized = NULL;
359-
li->def = ast;
360-
return li;
350+
nli->sparam_vals = sp;
351+
nli->specTypes = types;
352+
353+
// clone the basic metadata
354+
nli->ast = li ? li->ast : NULL;
355+
nli->def = li ? li->def : NULL;
356+
nli->rettype = li ? li->rettype : (jl_value_t*)jl_any_type;
357+
nli->pure = li ? li->pure : 0;
358+
nli->called = li ? li->called : 0xff;
359+
360+
// some values never get cloned
361+
nli->inInference = 0;
362+
nli->inCompile = 0;
363+
nli->unspecialized_ducttape = NULL;
364+
nli->inferred = 0;
365+
if (jl_options.compile_enabled == JL_OPTIONS_COMPILE_OFF && li != NULL) {
366+
// copy fptr from the unspecialized method definition
367+
nli->fptr = li->fptr;
368+
nli->jlcall_api = li->jlcall_api;
369+
nli->functionObjects.functionObject = li->functionObjects.functionObject;
370+
nli->functionObjects.specFunctionObject = li->functionObjects.specFunctionObject;
371+
nli->functionID = li->functionID;
372+
nli->specFunctionID = li->functionID;
373+
if (nli->fptr == NULL) {
374+
jl_printf(JL_STDERR,"code missing for ");
375+
jl_static_show(JL_STDERR, (jl_value_t*)nli);
376+
jl_printf(JL_STDERR, " sysimg may not have been built with --compile=all\n");
377+
}
378+
}
379+
else {
380+
nli->fptr = NULL;
381+
nli->jlcall_api = 0;
382+
nli->functionObjects.functionObject = NULL;
383+
nli->functionObjects.specFunctionObject = NULL;
384+
nli->functionObjects.cFunctionList = NULL;
385+
nli->functionID = 0;
386+
nli->specFunctionID = 0;
387+
}
388+
return nli;
361389
}
362390

391+
363392
// symbols --------------------------------------------------------------------
364393

365394
JL_DEFINE_MUTEX(symbol_table)

src/ast.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ static jl_value_t *scm_to_julia_(fl_context_t *fl_ctx, value_t e, int eo)
484484
e = cdr_(e);
485485
}
486486
nli = jl_new_method_info((jl_value_t*)ex, tvars, jl_current_module);
487-
jl_preresolve_globals(nli->ast, nli);
487+
jl_preresolve_globals(nli->unspecialized->ast, nli);
488488
JL_GC_POP();
489489
return (jl_value_t*)nli;
490490
}
@@ -914,11 +914,9 @@ jl_array_t *jl_lam_args(jl_expr_t *l)
914914

915915
jl_sym_t *jl_lam_argname(jl_method_info_t *li, int i)
916916
{
917-
jl_expr_t *ast;
918-
if (jl_is_expr(li->ast))
919-
ast = (jl_expr_t*)li->ast;
920-
else
921-
ast = (jl_expr_t*)jl_uncompress_ast(li, li->ast);
917+
jl_expr_t *ast = (jl_expr_t*)li->unspecialized->ast;
918+
if (!jl_is_expr(ast))
919+
ast = (jl_expr_t*)jl_uncompress_ast(li, (jl_value_t*)ast);
922920
// NOTE (gc root): `ast` is not rooted here, but jl_lam_args and jl_cellref
923921
// do not allocate.
924922
return (jl_sym_t*)jl_cellref(jl_lam_args(ast),i);
@@ -1091,8 +1089,7 @@ static jl_value_t *dont_copy_ast(jl_value_t *expr)
10911089
// this tree can then be further mutated by optimization passes.
10921090
JL_DLLEXPORT jl_value_t *jl_prepare_ast(jl_method_info_t *li)
10931091
{
1094-
jl_value_t *ast = li->ast;
1095-
if (ast == NULL) return NULL;
1092+
jl_value_t *ast = li->unspecialized->ast;
10961093
JL_GC_PUSH1(&ast);
10971094
if (!jl_is_expr(ast)) {
10981095
ast = jl_uncompress_ast(li, ast);
@@ -1169,7 +1166,7 @@ static int jl_in_sym_svec(jl_svec_t *a, jl_sym_t *v)
11691166

11701167
int jl_local_in_linfo(jl_method_info_t *linfo, jl_sym_t *sym)
11711168
{
1172-
return jl_in_vinfo_array(jl_lam_vinfo((jl_expr_t*)linfo->ast), sym) ||
1169+
return jl_in_vinfo_array(jl_lam_vinfo((jl_expr_t*)linfo->unspecialized->ast), sym) ||
11731170
jl_in_sym_svec(linfo->sparam_syms, sym);
11741171
}
11751172

@@ -1185,7 +1182,7 @@ jl_value_t *jl_preresolve_globals(jl_value_t *expr, jl_method_info_t *lam)
11851182
}
11861183
else if (jl_is_method_info(expr)) {
11871184
jl_method_info_t *l = (jl_method_info_t*)expr;
1188-
(void)jl_preresolve_globals(l->ast, l);
1185+
(void)jl_preresolve_globals(l->unspecialized->ast, l);
11891186
}
11901187
else if (jl_is_expr(expr)) {
11911188
jl_expr_t *e = (jl_expr_t*)expr;

src/builtins.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,19 +1086,18 @@ jl_value_t *jl_mk_builtin_func(const char *name, jl_fptr_t fptr)
10861086
jl_value_t *f = jl_new_generic_function_with_supertype(sname, jl_core_module, jl_builtin_type, 0);
10871087
jl_method_info_t *li = jl_new_method_info(jl_nothing, jl_emptysvec, jl_core_module);
10881088
li->name = sname;
1089+
li->unspecialized->fptr = fptr;
10891090
// TODO jb/functions: what should li->ast be?
1090-
li->ast = (jl_value_t*)jl_exprn(lambda_sym,0); jl_gc_wb(li, li->ast);
1091-
jl_lambda_info_t *unspec = jl_new_lambda_info(li, jl_emptysvec, jl_anytuple_type);
1092-
li->unspecialized = unspec;
1093-
unspec->fptr = fptr;
1094-
jl_method_cache_insert(jl_gf_mtable(f), jl_anytuple_type, unspec);
1091+
li->unspecialized->ast = (jl_value_t*)jl_exprn(lambda_sym,0);
1092+
jl_gc_wb(li->unspecialized, li->unspecialized->ast);
1093+
jl_method_cache_insert(jl_gf_mtable(f), jl_anytuple_type, li->unspecialized);
10951094
return f;
10961095
}
10971096

10981097
jl_fptr_t jl_get_builtin_fptr(jl_value_t *b)
10991098
{
11001099
assert(jl_subtype(b, (jl_value_t*)jl_builtin_type, 1));
1101-
return ((jl_method_info_t*)jl_gf_mtable(b)->cache->func)->unspecialized->fptr;
1100+
return jl_gf_mtable(b)->cache->func->fptr;
11021101
}
11031102

11041103
static void add_builtin_func(const char *name, jl_fptr_t fptr)

src/codegen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4205,7 +4205,7 @@ static void emit_function(jl_lambda_info_t *lam, jl_llvm_functions_t *declaratio
42054205
assert(definitions && "Capturing definitions is always required");
42064206

42074207
// step 1. unpack AST and allocate codegen context for this function
4208-
jl_expr_t *ast = (jl_expr_t*)lam->inferred_ast;
4208+
jl_expr_t *ast = (jl_expr_t*)lam->ast;
42094209
JL_GC_PUSH1(&ast);
42104210
if (!jl_is_expr(ast)) {
42114211
ast = (jl_expr_t*)jl_uncompress_ast(lam->def, (jl_value_t*)ast);

0 commit comments

Comments
 (0)