diff --git a/.gitignore b/.gitignore index a4e7f0ac40d5b..073f4f0a1e9c0 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ *.so *.dylib *.dSYM +*.h.gen *.jl.cov *.jl.*.cov *.jl.mem diff --git a/base/reflection.jl b/base/reflection.jl index 46f268feb9e0c..8b7bfaa784291 100644 --- a/base/reflection.jl +++ b/base/reflection.jl @@ -1111,6 +1111,19 @@ function which(m::Module, s::Symbol) return binding_module(m, s) end +""" + which(tt::TupleType) +""" +function which(tt::Type{T}) where T<:Tuple + m = ccall(:jl_gf_invoke_lookup, Any, (Any, UInt), tt, typemax(UInt)) + if m === nothing + error("no unique matching method found for the specified signature") + end + return m.func::Method +end + + + # function reflection """ nameof(f::Function) -> Symbol diff --git a/src/Makefile b/src/Makefile index 40070d353758c..9eb28ffbf8e43 100644 --- a/src/Makefile +++ b/src/Makefile @@ -79,9 +79,12 @@ SRCS += anticodegen LLVM_LIBS := support endif +uprobes.h.gen : uprobes.d + dtrace -h -s uprobes.d -o uprobes.h.gen + # headers are used for dependency tracking, while public headers will be part of the dist UV_HEADERS := -HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h tls.h locks.h atomics.h julia_internal.h options.h timing.h) +HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h uprobes.h.gen julia_assert.h julia_threads.h tls.h locks.h atomics.h julia_internal.h options.h timing.h) PUBLIC_HEADERS := $(BUILDDIR)/julia_version.h $(wildcard $(SRCDIR)/support/*.h) $(addprefix $(SRCDIR)/,julia.h julia_assert.h julia_threads.h tls.h locks.h atomics.h julia_gcext.h) ifeq ($(USE_SYSTEM_LIBUV),0) UV_HEADERS += uv.h diff --git a/src/gf.c b/src/gf.c index c01da4554ef1e..5abe2aa4dd540 100644 --- a/src/gf.c +++ b/src/gf.c @@ -17,6 +17,13 @@ #endif #include "julia_assert.h" +#ifdef ENABLE_TRACING_PROBES +// Dtrace Timings +#include "uprobes.h.gen" +#endif +void DTRACE__COMPILE_START(void); +void DTRACE__COMPILE_END(jl_method_instance_t *mi); + // The compilation signature is not used to cache the method if the number of overlapping methods is greater than this #define MAX_UNSPECIALIZED_CONFLICTS 32 @@ -1792,9 +1799,46 @@ jl_code_instance_t *jl_compile_method_internal(jl_method_instance_t *mi, size_t } } - jl_generate_fptr(codeinst); + { + // Instrument the time spent in this block for this method instance + DTRACE__COMPILE_START(); + jl_generate_fptr(codeinst); + DTRACE__COMPILE_END(mi); + } return codeinst; } +void DTRACE__COMPILE_START(void) +{ +#ifdef ENABLE_TRACING_PROBES + if (JULIA_COMPILE_START_ENABLED()) { + JULIA_COMPILE_START(); + } +#endif +} +void DTRACE__COMPILE_END(jl_method_instance_t *mi) +{ +#ifdef ENABLE_TRACING_PROBES + if (JULIA_COMPILE_START_ENABLED()) { + if (jl_is_method(mi->def.method)) { + ios_t str_; + ios_mem(&str_, 10000); + JL_STREAM* str = (JL_STREAM*)&str_; + + //jl_printf(str, "%s.%s, ", jl_symbol_name(mi->def.method->module->name), jl_symbol_name(mi->def.method->name)); + + //jl_static_show_func_sig(str, mi->specTypes); + jl_static_show(str, mi->specTypes); + + str_.buf[str_.size] = 0; + JULIA_COMPILE_END(str_.buf); + + ios_close(&str_); + } else { + JULIA_COMPILE_END("top-level scope"); + } + } +#endif +} JL_DLLEXPORT jl_value_t *jl_fptr_const_return(jl_code_instance_t *m, jl_value_t **args, uint32_t nargs) { diff --git a/src/options.h b/src/options.h index 37b1a38401009..3f2393a0b0f9d 100644 --- a/src/options.h +++ b/src/options.h @@ -63,7 +63,7 @@ // be considered untrusted, but can be helpful during development // #define SEGV_EXCEPTION -// profiling options +// profiling options ---------------------------------------------------------- // GC_FINAL_STATS prints total GC stats at exit // #define GC_FINAL_STATS @@ -78,7 +78,10 @@ // #define OBJPROFILE // Automatic Instrumenting Profiler -//#define ENABLE_TIMINGS +// #define ENABLE_TIMINGS + +// Automatic Instrumenting Profiler +#define ENABLE_TRACING_PROBES // method dispatch profiling -------------------------------------------------- diff --git a/src/uprobes.d b/src/uprobes.d new file mode 100644 index 0000000000000..dd5b24176e1cd --- /dev/null +++ b/src/uprobes.d @@ -0,0 +1,4 @@ +provider julia { + probe compile__start(); + probe compile__end(char*); +};