Commit 25420fe2 authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-32030: Add more options to _PyCoreConfig (#4485)

Py_Main() now handles two more -X options:

* -X showrefcount: new _PyCoreConfig.show_ref_count field
* -X showalloccount: new _PyCoreConfig.show_alloc_count field
parent 09f3a8a1
...@@ -728,7 +728,6 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); ...@@ -728,7 +728,6 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
/* Py_REF_DEBUG also controls the display of refcounts and memory block /* Py_REF_DEBUG also controls the display of refcounts and memory block
* allocations at the interactive prompt and at interpreter shutdown * allocations at the interactive prompt and at interpreter shutdown
*/ */
PyAPI_FUNC(PyObject *) _PyDebug_XOptionShowRefCount(void);
PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void); PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void);
#else #else
#define _Py_INC_REFTOTAL #define _Py_INC_REFTOTAL
......
...@@ -25,15 +25,17 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int); ...@@ -25,15 +25,17 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
typedef struct { typedef struct {
int ignore_environment; int ignore_environment; /* -E */
int use_hash_seed; int use_hash_seed; /* PYTHONHASHSEED=x */
unsigned long hash_seed; unsigned long hash_seed;
int _disable_importlib; /* Needed by freeze_importlib */ int _disable_importlib; /* Needed by freeze_importlib */
char *allocator; const char *allocator; /* Memory allocator: _PyMem_SetupAllocators() */
int faulthandler;
int tracemalloc; /* Number of saved frames, 0=don't trace */
int importtime; /* -X importtime */
int dev_mode; /* -X dev */ int dev_mode; /* -X dev */
int faulthandler; /* -X faulthandler */
int tracemalloc; /* -X tracemalloc=N */
int import_time; /* -X importtime */
int show_ref_count; /* -X showrefcount */
int show_alloc_count; /* -X showalloccount */
} _PyCoreConfig; } _PyCoreConfig;
#define _PyCoreConfig_INIT \ #define _PyCoreConfig_INIT \
...@@ -42,10 +44,12 @@ typedef struct { ...@@ -42,10 +44,12 @@ typedef struct {
.hash_seed = 0, \ .hash_seed = 0, \
._disable_importlib = 0, \ ._disable_importlib = 0, \
.allocator = NULL, \ .allocator = NULL, \
.dev_mode = 0, \
.faulthandler = 0, \ .faulthandler = 0, \
.tracemalloc = 0, \ .tracemalloc = 0, \
.importtime = 0, \ .import_time = 0, \
.dev_mode = 0} .show_ref_count = 0, \
.show_alloc_count = 0}
/* Placeholders while working on the new configuration API /* Placeholders while working on the new configuration API
* *
......
...@@ -1384,6 +1384,14 @@ pymain_parse_envvars(_PyMain *pymain) ...@@ -1384,6 +1384,14 @@ pymain_parse_envvars(_PyMain *pymain)
} }
core_config->allocator = Py_GETENV("PYTHONMALLOC"); core_config->allocator = Py_GETENV("PYTHONMALLOC");
/* -X options */
if (pymain_get_xoption(pymain, L"showrefcount")) {
core_config->show_ref_count = 1;
}
if (pymain_get_xoption(pymain, L"showalloccount")) {
core_config->show_alloc_count = 1;
}
/* More complex options: env var and/or -X option */ /* More complex options: env var and/or -X option */
if (pymain_get_env_var("PYTHONFAULTHANDLER") if (pymain_get_env_var("PYTHONFAULTHANDLER")
|| pymain_get_xoption(pymain, L"faulthandler")) { || pymain_get_xoption(pymain, L"faulthandler")) {
...@@ -1391,7 +1399,7 @@ pymain_parse_envvars(_PyMain *pymain) ...@@ -1391,7 +1399,7 @@ pymain_parse_envvars(_PyMain *pymain)
} }
if (pymain_get_env_var("PYTHONPROFILEIMPORTTIME") if (pymain_get_env_var("PYTHONPROFILEIMPORTTIME")
|| pymain_get_xoption(pymain, L"importtime")) { || pymain_get_xoption(pymain, L"importtime")) {
core_config->importtime = 1; core_config->import_time = 1;
} }
if (pymain_init_tracemalloc(pymain) < 0) { if (pymain_init_tracemalloc(pymain) < 0) {
return -1; return -1;
......
...@@ -85,15 +85,10 @@ static size_t count_reuse = 0; ...@@ -85,15 +85,10 @@ static size_t count_reuse = 0;
static void static void
show_alloc(void) show_alloc(void)
{ {
PyObject *xoptions, *value; PyInterpreterState *interp = PyThreadState_GET()->interp;
_Py_IDENTIFIER(showalloccount); if (!inter->core_config.show_alloc_count) {
xoptions = PySys_GetXOptions();
if (xoptions == NULL)
return;
value = _PyDict_GetItemId(xoptions, &PyId_showalloccount);
if (value != Py_True)
return; return;
}
fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n", fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n",
count_alloc); count_alloc);
......
...@@ -29,17 +29,6 @@ _Py_GetRefTotal(void) ...@@ -29,17 +29,6 @@ _Py_GetRefTotal(void)
return total; return total;
} }
PyObject *
_PyDebug_XOptionShowRefCount(void)
{
PyObject *xoptions = PySys_GetXOptions();
if (xoptions == NULL)
return NULL;
_Py_IDENTIFIER(showrefcount);
return _PyDict_GetItemId(xoptions, &PyId_showrefcount);
}
void void
_PyDebug_PrintTotalRefs(void) { _PyDebug_PrintTotalRefs(void) {
fprintf(stderr, fprintf(stderr,
...@@ -106,16 +95,10 @@ extern Py_ssize_t null_strings, one_strings; ...@@ -106,16 +95,10 @@ extern Py_ssize_t null_strings, one_strings;
void void
dump_counts(FILE* f) dump_counts(FILE* f)
{ {
PyTypeObject *tp; PyInterpreterState *interp = PyThreadState_GET()->interp;
PyObject *xoptions, *value; if (!inter->core_config.show_alloc_count) {
_Py_IDENTIFIER(showalloccount);
xoptions = PySys_GetXOptions();
if (xoptions == NULL)
return;
value = _PyDict_GetItemId(xoptions, &PyId_showalloccount);
if (value != Py_True)
return; return;
}
for (tp = type_list; tp; tp = tp->tp_next) for (tp = type_list; tp; tp = tp->tp_next)
fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, " fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, "
......
...@@ -44,15 +44,10 @@ static Py_ssize_t count_tracked = 0; ...@@ -44,15 +44,10 @@ static Py_ssize_t count_tracked = 0;
static void static void
show_track(void) show_track(void)
{ {
PyObject *xoptions, *value; PyInterpreterState *interp = PyThreadState_GET()->interp;
_Py_IDENTIFIER(showalloccount); if (!inter->core_config.show_alloc_count) {
xoptions = PySys_GetXOptions();
if (xoptions == NULL)
return;
value = _PyDict_GetItemId(xoptions, &PyId_showalloccount);
if (value != Py_True)
return; return;
}
fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n", fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n",
count_tracked + count_untracked); count_tracked + count_untracked);
......
...@@ -1674,8 +1674,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, ...@@ -1674,8 +1674,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
} }
} }
else { else {
/* 1 -- true, 0 -- false, -1 -- not initialized */ int import_time = interp->core_config.import_time;
int importtime = interp->core_config.importtime;
static int import_level; static int import_level;
static _PyTime_t accumulated; static _PyTime_t accumulated;
...@@ -1686,7 +1685,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, ...@@ -1686,7 +1685,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
* Anyway, importlib._find_and_load is much slower than * Anyway, importlib._find_and_load is much slower than
* _PyDict_GetItemIdWithError(). * _PyDict_GetItemIdWithError().
*/ */
if (importtime) { if (import_time) {
static int header = 1; static int header = 1;
if (header) { if (header) {
fputs("import time: self [us] | cumulative | imported package\n", fputs("import time: self [us] | cumulative | imported package\n",
...@@ -1712,7 +1711,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals, ...@@ -1712,7 +1711,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name), PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
mod != NULL); mod != NULL);
if (importtime) { if (import_time) {
_PyTime_t cum = _PyTime_GetPerfCounter() - t1; _PyTime_t cum = _PyTime_GetPerfCounter() - t1;
import_level--; import_level--;
......
...@@ -1101,10 +1101,6 @@ Py_FinalizeEx(void) ...@@ -1101,10 +1101,6 @@ Py_FinalizeEx(void)
/* nothing */; /* nothing */;
#endif #endif
#ifdef Py_REF_DEBUG
PyObject *showrefcount = _PyDebug_XOptionShowRefCount();
#endif
/* Destroy all modules */ /* Destroy all modules */
PyImport_Cleanup(); PyImport_Cleanup();
...@@ -1153,8 +1149,9 @@ Py_FinalizeEx(void) ...@@ -1153,8 +1149,9 @@ Py_FinalizeEx(void)
_PyHash_Fini(); _PyHash_Fini();
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
if (showrefcount == Py_True) if (interp->core_config.show_ref_count) {
_PyDebug_PrintTotalRefs(); _PyDebug_PrintTotalRefs();
}
#endif #endif
#ifdef Py_TRACE_REFS #ifdef Py_TRACE_REFS
......
...@@ -91,6 +91,9 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * ...@@ -91,6 +91,9 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
int ret, err; int ret, err;
PyCompilerFlags local_flags; PyCompilerFlags local_flags;
int nomem_count = 0; int nomem_count = 0;
#ifdef Py_REF_DEBUG
int show_ref_count = PyThreadState_GET()->interp->core_config.show_ref_count;
#endif
filename = PyUnicode_DecodeFSDefault(filename_str); filename = PyUnicode_DecodeFSDefault(filename_str);
if (filename == NULL) { if (filename == NULL) {
...@@ -134,8 +137,9 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags * ...@@ -134,8 +137,9 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
nomem_count = 0; nomem_count = 0;
} }
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
if (_PyDebug_XOptionShowRefCount() == Py_True) if (show_ref_count) {
_PyDebug_PrintTotalRefs(); _PyDebug_PrintTotalRefs();
}
#endif #endif
} while (ret != E_EOF); } while (ret != E_EOF);
Py_DECREF(filename); Py_DECREF(filename);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment