Skip to content

Commit

Permalink
storing ASTs serialized to save memory
Browse files Browse the repository at this point in the history
part of issue #261
significantly cuts the number of live objects, making GC much faster
  • Loading branch information
JeffBezanson committed Dec 14, 2011
1 parent 3ec1c02 commit 0df50fd
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 50 deletions.
44 changes: 31 additions & 13 deletions j/inference.j
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,10 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
tf = def.tfunc
while !is(tf,())
if typeseq(tf[1],atypes)
if isa(tf[2],Tuple)
# compressed tree format
return (tf[2], tf[2][3])
end
# if the frame above this one recurred, rerun type inf
# here instead of returning, and update the cache, until the new
# inferred type equals the cached type (fixed point)
Expand Down Expand Up @@ -885,11 +889,12 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
#print("typeinf ", linfo.name, " ", atypes, "\n")

if redo
elseif cop
sparams = append(sparams, linfo.sparams)
ast = ccall(:jl_prepare_ast, Any, (Any,Any), linfo.ast, sparams)::Expr
else
ast = linfo.ast
if cop
sparams = append(sparams, linfo.sparams)
ast = ccall(:jl_prepare_ast, Any, (Any,Any), ast, sparams)::Expr
end
end

assert(is(ast.head,:lambda), "inference.j:745")
Expand Down Expand Up @@ -1059,14 +1064,19 @@ function typeinf(linfo::LambdaStaticData,atypes::Tuple,sparams::Tuple, def, cop)
fulltree = type_annotate(ast, s, sv,
rec ? RecPending{frame.result} : frame.result,
vars)
if !redo
def.tfunc = (atypes, fulltree, def.tfunc)
end
if !rec
fulltree.args[3] = inlining_pass(fulltree.args[3], s[1])
tuple_elim_pass(fulltree)
linfo.inferred = true
end
if !redo
vals = {}
treedata = ccall(:jl_compress_ast, Any, (Any, Any), fulltree, vals)
compressed = (treedata, vals, frame.result)
fulltree = compressed
#compressed = fulltree
def.tfunc = (atypes, compressed, def.tfunc)
end
inference_stack = (inference_stack::CallStack).prev
return (fulltree, frame.result)
end
Expand Down Expand Up @@ -1295,17 +1305,21 @@ function inlineable(f, e::Expr, vars)
return NF
end
end
for vi = meth[3].ast.args[2].args[2]
(ast, ty) = typeinf(meth[3], meth[1], meth[2], meth[3])
if is(ast,())
return NF
end
if isa(ast,Tuple)
ast = ccall(:jl_uncompress_ast, Any, (Any,), ast)
end
ast = ast::Expr
for vi = ast.args[2].args[2]
if (vi[3]&1)!=0
# captures variables (TODO)
return NF
end
end
(ast, ty) = typeinf(meth[3], meth[1], meth[2], meth[3])
if is(ast,())
return NF
end
body = without_linenums(ast.args[3].args)
body = without_linenums(ast.args[3].args)::Array{Any,1}
# see if body is only "return <expr>"
if length(body) != 1
return NF
Expand Down Expand Up @@ -1543,7 +1557,11 @@ end
function finfer(f, types)
x = getmethods(f,types)[1]
typeinf(x[3], x[1], x[2])[1]
(tree, ty) = typeinf(x[3], x[1], x[2])
if isa(tree,Tuple)
return ccall(:jl_uncompress_ast, Any, (Any,), tree)
end
tree
end
tfunc(f,t) = (getmethods(f,t)[1][3]).tfunc
Expand Down
12 changes: 10 additions & 2 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ static Function *to_function(jl_lambda_info_t *li)
JL_SIGATOMIC_BEGIN();
Function *f = Function::Create(jl_func_sig, Function::ExternalLinkage,
li->name->name, jl_Module);
assert(jl_is_expr(li->ast));
assert(!li->inInference);
li->functionObject = (void*)f;
BasicBlock *old = nested_compile ? builder.GetInsertBlock() : NULL;
Expand Down Expand Up @@ -356,11 +355,14 @@ static void make_gcroot(Value *v, jl_codectx_t *ctx)

// --- lambda ---

extern "C" jl_value_t *jl_uncompress_ast(jl_tuple_t *data);

static Value *emit_lambda_closure(jl_value_t *expr, jl_codectx_t *ctx)
{
assert(jl_is_lambda_info(expr));
size_t i;
jl_array_t *capt = jl_lam_capt((jl_expr_t*)((jl_lambda_info_t*)expr)->ast);
jl_value_t *ast = ((jl_lambda_info_t*)expr)->ast;
jl_array_t *capt = jl_lam_capt((jl_expr_t*)ast);
if (capt->length == 0) {
// no captured vars; lift
jl_value_t *fun = jl_new_closure_internal((jl_lambda_info_t*)expr,
Expand Down Expand Up @@ -1327,6 +1329,11 @@ extern "C" jl_tuple_t *jl_tuple_tvars_to_symbols(jl_tuple_t *t);
static void emit_function(jl_lambda_info_t *lam, Function *f)
{
jl_expr_t *ast = (jl_expr_t*)lam->ast;
if (jl_is_tuple(ast)) {
ast = (jl_expr_t*)jl_uncompress_ast((jl_tuple_t*)ast);
}
assert(jl_is_expr(ast));
jl_gc_preserve((jl_value_t*)ast);
//jl_print((jl_value_t*)ast);
//ios_printf(ios_stdout, "\n");
BasicBlock *b0 = BasicBlock::Create(jl_LLVMContext, "top", f);
Expand Down Expand Up @@ -1700,6 +1707,7 @@ static void emit_function(jl_lambda_info_t *lam, Function *f)
//used_roots += ctx.maxDepth;
//JL_GC_POP();
jl_gc_unpreserve();
jl_gc_unpreserve();
}

// --- initialization ---
Expand Down
Loading

0 comments on commit 0df50fd

Please sign in to comment.