Skip to content

Commit

Permalink
make jl_apply accept function and arguments contiguously, so the ar…
Browse files Browse the repository at this point in the history
…gument list

doesn't need to be copied as often

[ci skip]
  • Loading branch information
JeffBezanson committed Jan 28, 2016
1 parent b79196d commit 7a85e3b
Show file tree
Hide file tree
Showing 16 changed files with 82 additions and 89 deletions.
2 changes: 1 addition & 1 deletion base/threadingconstructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function _threadsfor(iter,lbody)
$(esc(lbody))
end
end
ccall(:jl_threading_run, Void, (Any, Any), $fun, ())
ccall(:jl_threading_run, Void, (Any,), svec($fun))
end
end

Expand Down
26 changes: 15 additions & 11 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,9 +422,6 @@ JL_CALLABLE(jl_f__apply)
return (jl_value_t*)t;
}
}
if (jl_is_svec(args[1])) {
return jl_apply(f, jl_svec_data(args[1]), jl_svec_len(args[1]));
}
}
size_t n=0, i, j;
for(i=1; i < nargs; i++) {
Expand All @@ -446,15 +443,21 @@ JL_CALLABLE(jl_f__apply)
JL_TYPECHK(apply, tuple, jl_typeof(args[i]));
}
}
jl_value_t *argarr = jl_apply(jl_append_any_func, &args[1], nargs-1);
jl_array_t *argarr = NULL;
JL_GC_PUSH2(&argarr, &f);
args[0] = jl_append_any_func;
argarr = (jl_array_t*)jl_apply(args, nargs);
assert(jl_typeis(argarr, jl_array_any_type));
JL_GC_PUSH1(&argarr);
jl_value_t *result = jl_apply(f, jl_cell_data(argarr), jl_array_len(argarr));
jl_array_grow_beg(argarr, 1);
jl_cellset(argarr, 0, f);
args[0] = f;
jl_value_t *result = jl_apply(jl_cell_data(argarr), jl_array_len(argarr));
JL_GC_POP();
return result;
}
}
jl_value_t **newargs;
n++;
int onstack = (n < jl_page_size/sizeof(jl_value_t*));
JL_GC_PUSHARGS(newargs, onstack ? n : 1);
jl_svec_t *arg_heap = NULL;
Expand All @@ -468,7 +471,8 @@ JL_CALLABLE(jl_f__apply)
// `jl_cellref` will not be young if `arg_heap` becomes old
// since they are allocated before `arg_heap`. Otherwise,
// we need to add write barrier for !onstack
n = 0;
newargs[0] = f;
n = 1;
for(i=1; i < nargs; i++) {
jl_value_t *ai = args[i];
if (jl_is_svec(ai)) {
Expand Down Expand Up @@ -509,7 +513,7 @@ JL_CALLABLE(jl_f__apply)
}
}
}
jl_value_t *result = jl_apply(f, newargs, n);
jl_value_t *result = jl_apply(newargs, n);
JL_GC_POP();
return result;
}
Expand Down Expand Up @@ -919,8 +923,8 @@ JL_DLLEXPORT void jl_show(jl_value_t *stream, jl_value_t *v)
jl_symbol_name(((jl_datatype_t*)jl_typeof(v))->name->name));
return;
}
jl_value_t *args[2] = {stream,v};
jl_apply(jl_show_gf, args, 2);
jl_value_t *args[3] = {jl_show_gf,stream,v};
jl_apply(args, 3);
}
}

Expand Down Expand Up @@ -1521,7 +1525,7 @@ JL_DLLEXPORT size_t jl_static_show_func_sig(JL_STREAM *s, jl_value_t *type)
return jl_static_show(s, type);
size_t n = 0;
if (jl_nparams(ftype)==0 || ftype == ((jl_datatype_t*)ftype)->name->primary) {
n += jl_printf(s, "%s", jl_symbol_name(((jl_datatype_t*)ftype)->name->name));
n += jl_printf(s, "%s", jl_symbol_name(((jl_datatype_t*)ftype)->name->mt->name));
}
else {
n += jl_printf(s, "(::");
Expand Down
6 changes: 5 additions & 1 deletion src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1774,7 +1774,10 @@ jl_value_t *jl_static_eval(jl_value_t *ex, void *ctx_, jl_module_t *mod,
}
jl_value_t *result;
JL_TRY {
result = jl_apply(f, v, n);
if (f == jl_builtin_tuple)
result = jl_f_tuple(NULL, v, n);
else
result = jl_f_apply_type(NULL, v, n);
}
JL_CATCH {
result = NULL;
Expand Down Expand Up @@ -4769,6 +4772,7 @@ static void emit_function(jl_lambda_info_t *lam, jl_llvm_functions_t *declaratio
}

// step 11. check arg count
// TODO jb/functions: this code can probably be deleted
if (jl_is_va_tuple(ctx.linfo->specTypes)) {
assert(argCount != NULL);
assert(!specsig);
Expand Down
6 changes: 4 additions & 2 deletions src/dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -1016,7 +1016,8 @@ static void jl_serialize_dependency_list(ios_t *s)
static jl_value_t *unique_func = NULL;
if (!unique_func)
unique_func = jl_get_global(jl_base_module, jl_symbol("unique"));
jl_array_t *udeps = deps && unique_func ? (jl_array_t *) jl_apply((jl_function_t*)unique_func, (jl_value_t**)&deps, 1) : NULL;
jl_value_t *uniqargs[2] = {unique_func,(jl_value_t*)deps};
jl_array_t *udeps = deps && unique_func ? (jl_array_t*)jl_apply(uniqargs, 2) : NULL;

JL_GC_PUSH1(&udeps);
if (udeps) {
Expand Down Expand Up @@ -1619,8 +1620,9 @@ static int jl_deserialize_verify_mod_list(ios_t *s)
static jl_value_t *require_func = NULL;
if (!require_func)
require_func = jl_get_global(jl_base_module, jl_symbol("require"));
jl_value_t *reqargs[2] = {require_func, (jl_value_t*)sym};
JL_TRY {
jl_apply((jl_function_t*)require_func, (jl_value_t**)&sym, 1);
jl_apply(reqargs, 2);
}
JL_CATCH {
ios_close(s);
Expand Down
4 changes: 2 additions & 2 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,9 @@ static void schedule_finalization(void *o, void *f)

static void run_finalizer(jl_value_t *o, jl_value_t *ff)
{
jl_function_t *f = (jl_function_t*)ff;
jl_value_t *args[2] = {ff,o};
JL_TRY {
jl_do_call(f, (jl_value_t**)&o, 1);
jl_apply(args, 2);
}
JL_CATCH {
jl_printf(JL_STDERR, "error in running finalizer: ");
Expand Down
22 changes: 12 additions & 10 deletions src/gf.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ static int cache_match_by_type(jl_value_t **types, size_t n, jl_tupletype_t *sig
return 1;
}

static inline int cache_match(jl_value_t **args, size_t n, jl_tupletype_t *sig,
static inline int cache_match(jl_value_t **args, size_t n, jl_value_t **sig,
int va, size_t lensig)
{
// NOTE: This function is a huge performance hot spot!!
for(size_t i=0; i < n; i++) {
jl_value_t *decl = jl_field_type(sig, i);
jl_value_t *decl = sig[i];
if (i == lensig-1) {
if (va) {
jl_value_t *t = jl_tparam0(decl);
Expand Down Expand Up @@ -261,7 +261,7 @@ static jl_lambda_info_t *jl_method_table_assoc_exact(jl_methtable_t *mt, jl_valu
while (ml != (void*)jl_nothing) {
size_t lensig = jl_datatype_nfields(ml->sig);
if (lensig == n || (ml->va && lensig <= n+1)) {
if (cache_match(args, n, ml->sig, ml->va, lensig)) {
if (cache_match(args, n, jl_svec_data(ml->sig->parameters), ml->va, lensig)) {
return ml->func;
}
// if we hit a guard entry (ml->func == NULL), do a more
Expand Down Expand Up @@ -372,18 +372,19 @@ void jl_type_infer(jl_lambda_info_t *li, jl_tupletype_t *argtypes, jl_lambda_inf
// called
assert(li->inInference == 0);
li->inInference = 1;
jl_value_t *fargs[4];
fargs[0] = (jl_value_t*)li;
fargs[1] = (jl_value_t*)argtypes;
fargs[2] = (jl_value_t*)jl_emptysvec;
fargs[3] = (jl_value_t*)def;
jl_value_t *fargs[5];
fargs[0] = (jl_value_t*)jl_typeinf_func;
fargs[1] = (jl_value_t*)li;
fargs[2] = (jl_value_t*)argtypes;
fargs[3] = (jl_value_t*)jl_emptysvec;
fargs[4] = (jl_value_t*)def;
#ifdef TRACE_INFERENCE
jl_printf(JL_STDERR,"inference on ");
jl_static_show_func_sig(JL_STDERR, (jl_value_t*)argtypes);
jl_printf(JL_STDERR, "\n");
#endif
#ifdef ENABLE_INFERENCE
jl_value_t *newast = jl_apply(jl_typeinf_func, fargs, 4);
jl_value_t *newast = jl_apply(fargs, 5);
jl_value_t *defast = def->ast;
li->ast = jl_fieldref(newast, 0);
jl_gc_wb(li, li->ast);
Expand Down Expand Up @@ -502,9 +503,10 @@ static jl_lambda_info_t *cache_method(jl_methtable_t *mt, jl_tupletype_t *type,
else {
set_to_any = 1;
if (nintr > 0) {
need_guard_entries = 1;
if (decl_i == (jl_value_t*)jl_function_type)
cache_as_orig = 1;
else
need_guard_entries = 1;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ JL_DLLEXPORT void jl_atexit_hook(int exitcode)
jl_value_t *f = jl_get_global(jl_base_module, jl_symbol("_atexit"));
if (f != NULL) {
JL_TRY {
jl_apply((jl_function_t*)f, NULL, 0);
jl_apply(&f, 1);
}
JL_CATCH {
jl_printf(JL_STDERR, "\natexit hook threw an error: ");
Expand Down
2 changes: 1 addition & 1 deletion src/interpreter.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static jl_value_t *do_call(jl_value_t **args, size_t nargs,
jl_value_t **locals, size_t nl, size_t ngensym)
{
jl_value_t **argv;
JL_GC_PUSHARGS(argv, nargs+1);
JL_GC_PUSHARGS(argv, nargs);
size_t i;
for(i=0; i < nargs; i++)
argv[i] = eval(args[i], locals, nl, ngensym);
Expand Down
7 changes: 4 additions & 3 deletions src/jl_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extern "C" {
extern jl_module_t *jl_old_base_module;
static jl_value_t *close_cb = NULL;

static void jl_uv_call_close_callback(void *val)
static void jl_uv_call_close_callback(jl_value_t *val)
{
jl_value_t *cb;
if (!jl_old_base_module) {
Expand All @@ -62,7 +62,8 @@ static void jl_uv_call_close_callback(void *val)
cb = jl_get_global(jl_base_relative_to(((jl_datatype_t*)jl_typeof(val))->name->module), jl_symbol("_uv_hook_close"));
}
assert(cb);
jl_apply((jl_function_t*)cb, (jl_value_t**)&val, 1);
jl_value_t *args[2] = {cb,val};
jl_apply(args, 2);
}

JL_DLLEXPORT void jl_uv_closeHandle(uv_handle_t *handle)
Expand All @@ -78,7 +79,7 @@ JL_DLLEXPORT void jl_uv_closeHandle(uv_handle_t *handle)
JL_STDERR = (JL_STREAM*)STDERR_FILENO;
// also let the client app do its own cleanup
if (handle->type != UV_FILE && handle->data)
jl_uv_call_close_callback(handle->data);
jl_uv_call_close_callback((jl_value_t*)handle->data);
free(handle);
}

Expand Down
38 changes: 15 additions & 23 deletions src/jlapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,28 +110,16 @@ JL_DLLEXPORT const char *jl_bytestring_ptr(jl_value_t *s)
return jl_string_data(s);
}

JL_DLLEXPORT jl_value_t *jl_do_call(jl_function_t *f, jl_value_t **args, int32_t nargs)
{
jl_value_t **argv;
JL_GC_PUSHARGS(argv, nargs+1);
argv[0] = (jl_value_t*)f;
for(int i=1; i<nargs+1; i++)
argv[i] = args[i-1];
jl_value_t *v = jl_apply_generic(argv, nargs+1);
JL_GC_POP();
return v;
}

JL_DLLEXPORT jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs)
{
jl_value_t *v;
JL_TRY {
jl_value_t **argv;
JL_GC_PUSHARGS(argv, nargs+1);
argv[0] = (jl_value_t*) f;
argv[0] = (jl_value_t*)f;
for(int i=1; i<nargs+1; i++)
argv[i] = args[i-1];
v = jl_apply_generic(argv, nargs+1);
v = jl_apply(argv, nargs+1);
JL_GC_POP();
jl_exception_clear();
}
Expand All @@ -146,7 +134,7 @@ JL_DLLEXPORT jl_value_t *jl_call0(jl_function_t *f)
jl_value_t *v;
JL_TRY {
JL_GC_PUSH1(&f);
v = jl_apply(f, NULL, 0);
v = jl_apply(&f, 1);
JL_GC_POP();
jl_exception_clear();
}
Expand All @@ -160,8 +148,10 @@ JL_DLLEXPORT jl_value_t *jl_call1(jl_function_t *f, jl_value_t *a)
{
jl_value_t *v;
JL_TRY {
JL_GC_PUSH2(&f,&a);
v = jl_apply(f, &a, 1);
jl_value_t **argv;
JL_GC_PUSHARGS(argv, 2);
argv[0] = f; argv[1] = a;
v = jl_apply(argv, 2);
JL_GC_POP();
jl_exception_clear();
}
Expand All @@ -175,9 +165,10 @@ JL_DLLEXPORT jl_value_t *jl_call2(jl_function_t *f, jl_value_t *a, jl_value_t *b
{
jl_value_t *v;
JL_TRY {
JL_GC_PUSH3(&f,&a,&b);
jl_value_t *args[2] = {a,b};
v = jl_apply(f, args, 2);
jl_value_t **argv;
JL_GC_PUSHARGS(argv, 3);
argv[0] = f; argv[1] = a; argv[2] = b;
v = jl_apply(argv, 3);
JL_GC_POP();
jl_exception_clear();
}
Expand All @@ -192,9 +183,10 @@ JL_DLLEXPORT jl_value_t *jl_call3(jl_function_t *f, jl_value_t *a,
{
jl_value_t *v;
JL_TRY {
JL_GC_PUSH4(&f,&a,&b,&c);
jl_value_t *args[3] = {a,b,c};
v = jl_apply(f, args, 3);
jl_value_t **argv;
JL_GC_PUSHARGS(argv, 4);
argv[0] = f; argv[1] = a; argv[2] = b; argv[3] = c;
v = jl_apply(argv, 4);
JL_GC_POP();
jl_exception_clear();
}
Expand Down
9 changes: 2 additions & 7 deletions src/julia.h
Original file line number Diff line number Diff line change
Expand Up @@ -1372,17 +1372,12 @@ STATIC_INLINE int jl_vinfo_usedundef(jl_array_t *vi)
JL_DLLEXPORT jl_value_t *jl_apply_generic(jl_value_t **args, uint32_t nargs);

STATIC_INLINE
jl_value_t *jl_apply(jl_value_t *f, jl_value_t **args, uint32_t nargs)
jl_value_t *jl_apply(jl_value_t **args, uint32_t nargs)
{
// TODO maybe deprecate this API
jl_value_t **a = (jl_value_t**)alloca((nargs+1)*sizeof(jl_value_t*));
a[0] = f;
memcpy(&a[1], args, nargs*sizeof(jl_value_t*));
return jl_apply_generic(a, nargs+1);
return jl_apply_generic(args, nargs);
}

JL_DLLEXPORT jl_value_t *jl_call(jl_function_t *f, jl_value_t **args, int32_t nargs);
JL_DLLEXPORT jl_value_t *jl_do_call(jl_function_t *f, jl_value_t **args, int32_t nargs);
JL_DLLEXPORT jl_value_t *jl_call0(jl_function_t *f);
JL_DLLEXPORT jl_value_t *jl_call1(jl_function_t *f, jl_value_t *a);
JL_DLLEXPORT jl_value_t *jl_call2(jl_function_t *f, jl_value_t *a, jl_value_t *b);
Expand Down
2 changes: 1 addition & 1 deletion src/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,7 +622,7 @@ JL_DLLEXPORT void jl_module_run_initializer(jl_module_t *m)
if (f == NULL)
return;
JL_TRY {
jl_apply(f, NULL, 0);
jl_apply(&f, 1);
}
JL_CATCH {
if (jl_initerror_type == NULL) {
Expand Down
5 changes: 3 additions & 2 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,8 @@ static void JL_NORETURN finish_task(jl_task_t *t, jl_value_t *resultval)
jl_symbol("task_done_hook"));
}
if (task_done_hook_func != NULL) {
jl_apply(task_done_hook_func, (jl_value_t**)&t, 1);
jl_value_t *args[2] = {task_done_hook_func, (jl_value_t*)t};
jl_apply(args, 2);
}
abort();
}
Expand All @@ -243,7 +244,7 @@ static void NOINLINE JL_NORETURN start_task(void)
}
else {
JL_TRY {
res = jl_do_call(t->start, NULL, 0);
res = jl_apply(&t->start, 1);
}
JL_CATCH {
res = jl_exception_in_transit;
Expand Down
Loading

0 comments on commit 7a85e3b

Please sign in to comment.