mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
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
This commit is contained in:
parent
09f3a8a124
commit
25420fe290
9 changed files with 41 additions and 57 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
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 {
|
||||||
.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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
}
|
}
|
||||||
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;
|
||||||
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)
|
||||||
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;
|
||||||
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;
|
||||||
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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,
|
||||||
* 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,
|
||||||
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)
|
||||||
/* 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)
|
||||||
_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 *
|
||||||
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 *
|
||||||
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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue