diff --git a/Doc/howto/instrumentation.rst b/Doc/howto/instrumentation.rst index 7fca9aac7b3..2ac939c5307 100644 --- a/Doc/howto/instrumentation.rst +++ b/Doc/howto/instrumentation.rst @@ -312,6 +312,17 @@ Available static markers Fires when the Python interpreter finishes a garbage collection cycle. ``arg0`` is the number of collected objects. +.. c:function:: import__find__load__start(str modulename) + + Fires before :mod:`importlib` attempts to find and load the module. + ``arg0`` is the module name. + +.. c:function:: import__find__load__done(str modulename, int found) + + Fires after :mod:`importlib`'s find_and_load function is called. + ``arg0`` is the module name, ``arg1`` indicates if module was + successfully loaded. + SystemTap Tapsets ----------------- diff --git a/Include/pydtrace.d b/Include/pydtrace.d index 883605566d5..a6a5e7ec224 100644 --- a/Include/pydtrace.d +++ b/Include/pydtrace.d @@ -10,6 +10,8 @@ provider python { probe line(const char *, const char *, int); probe gc__start(int); probe gc__done(long); + probe import__find__load__start(const char *); + probe import__find__load__done(const char *, int); }; #pragma D attributes Evolving/Evolving/Common provider python provider diff --git a/Include/pydtrace.h b/Include/pydtrace.h index c43a253d3cc..037961d429c 100644 --- a/Include/pydtrace.h +++ b/Include/pydtrace.h @@ -34,6 +34,8 @@ static inline void PyDTrace_INSTANCE_NEW_START(int arg0) {} static inline void PyDTrace_INSTANCE_NEW_DONE(int arg0) {} static inline void PyDTrace_INSTANCE_DELETE_START(int arg0) {} static inline void PyDTrace_INSTANCE_DELETE_DONE(int arg0) {} +static inline void PyDTrace_IMPORT_FIND_LOAD_START(const char *arg0) {} +static inline void PyDTrace_IMPORT_FIND_LOAD_DONE(const char *arg0, int arg1) {} static inline int PyDTrace_LINE_ENABLED(void) { return 0; } static inline int PyDTrace_FUNCTION_ENTRY_ENABLED(void) { return 0; } @@ -44,6 +46,8 @@ static inline int PyDTrace_INSTANCE_NEW_START_ENABLED(void) { return 0; } static inline int PyDTrace_INSTANCE_NEW_DONE_ENABLED(void) { return 0; } static inline int PyDTrace_INSTANCE_DELETE_START_ENABLED(void) { return 0; } static inline int PyDTrace_INSTANCE_DELETE_DONE_ENABLED(void) { return 0; } +static inline int PyDTrace_IMPORT_FIND_LOAD_START_ENABLED(void) { return 0; } +static inline int PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED(void) { return 0; } #endif /* !WITH_DTRACE */ diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-09-25-12-35-48.bpo-31574.5yX5r5.rst b/Misc/NEWS.d/next/Core and Builtins/2017-09-25-12-35-48.bpo-31574.5yX5r5.rst new file mode 100644 index 00000000000..e5c8ae28542 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-09-25-12-35-48.bpo-31574.5yX5r5.rst @@ -0,0 +1 @@ +Importlib was instrumented with two dtrace probes to profile import timing. diff --git a/Python/import.c b/Python/import.c index 5e841ca782d..e50ea4d03cc 100644 --- a/Python/import.c +++ b/Python/import.c @@ -12,6 +12,7 @@ #include "frameobject.h" #include "osdefs.h" #include "importdl.h" +#include "pydtrace.h" #ifdef HAVE_FCNTL_H #include @@ -1667,9 +1668,18 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, } else { Py_XDECREF(mod); + + if (PyDTrace_IMPORT_FIND_LOAD_START_ENABLED()) + PyDTrace_IMPORT_FIND_LOAD_START(PyUnicode_AsUTF8(abs_name)); + mod = _PyObject_CallMethodIdObjArgs(interp->importlib, &PyId__find_and_load, abs_name, interp->import_func, NULL); + + if (PyDTrace_IMPORT_FIND_LOAD_DONE_ENABLED()) + PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), + mod != NULL); + if (mod == NULL) { goto error; }