Skip to content

Commit 25420fe

Browse files
authored
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
1 parent 09f3a8a commit 25420fe

File tree

9 files changed

+41
-57
lines changed

9 files changed

+41
-57
lines changed

Include/object.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -728,7 +728,6 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
728728
/* Py_REF_DEBUG also controls the display of refcounts and memory block
729729
* allocations at the interactive prompt and at interpreter shutdown
730730
*/
731-
PyAPI_FUNC(PyObject *) _PyDebug_XOptionShowRefCount(void);
732731
PyAPI_FUNC(void) _PyDebug_PrintTotalRefs(void);
733732
#else
734733
#define _Py_INC_REFTOTAL

Include/pystate.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,17 @@ typedef PyObject* (*_PyFrameEvalFunction)(struct _frame *, int);
2525

2626

2727
typedef struct {
28-
int ignore_environment;
29-
int use_hash_seed;
28+
int ignore_environment; /* -E */
29+
int use_hash_seed; /* PYTHONHASHSEED=x */
3030
unsigned long hash_seed;
3131
int _disable_importlib; /* Needed by freeze_importlib */
32-
char *allocator;
33-
int faulthandler;
34-
int tracemalloc; /* Number of saved frames, 0=don't trace */
35-
int importtime; /* -X importtime */
32+
const char *allocator; /* Memory allocator: _PyMem_SetupAllocators() */
3633
int dev_mode; /* -X dev */
34+
int faulthandler; /* -X faulthandler */
35+
int tracemalloc; /* -X tracemalloc=N */
36+
int import_time; /* -X importtime */
37+
int show_ref_count; /* -X showrefcount */
38+
int show_alloc_count; /* -X showalloccount */
3739
} _PyCoreConfig;
3840

3941
#define _PyCoreConfig_INIT \
@@ -42,10 +44,12 @@ typedef struct {
4244
.hash_seed = 0, \
4345
._disable_importlib = 0, \
4446
.allocator = NULL, \
47+
.dev_mode = 0, \
4548
.faulthandler = 0, \
4649
.tracemalloc = 0, \
47-
.importtime = 0, \
48-
.dev_mode = 0}
50+
.import_time = 0, \
51+
.show_ref_count = 0, \
52+
.show_alloc_count = 0}
4953

5054
/* Placeholders while working on the new configuration API
5155
*

Modules/main.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1384,14 +1384,22 @@ pymain_parse_envvars(_PyMain *pymain)
13841384
}
13851385
core_config->allocator = Py_GETENV("PYTHONMALLOC");
13861386

1387+
/* -X options */
1388+
if (pymain_get_xoption(pymain, L"showrefcount")) {
1389+
core_config->show_ref_count = 1;
1390+
}
1391+
if (pymain_get_xoption(pymain, L"showalloccount")) {
1392+
core_config->show_alloc_count = 1;
1393+
}
1394+
13871395
/* More complex options: env var and/or -X option */
13881396
if (pymain_get_env_var("PYTHONFAULTHANDLER")
13891397
|| pymain_get_xoption(pymain, L"faulthandler")) {
13901398
core_config->faulthandler = 1;
13911399
}
13921400
if (pymain_get_env_var("PYTHONPROFILEIMPORTTIME")
13931401
|| pymain_get_xoption(pymain, L"importtime")) {
1394-
core_config->importtime = 1;
1402+
core_config->import_time = 1;
13951403
}
13961404
if (pymain_init_tracemalloc(pymain) < 0) {
13971405
return -1;

Objects/listobject.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,10 @@ static size_t count_reuse = 0;
8585
static void
8686
show_alloc(void)
8787
{
88-
PyObject *xoptions, *value;
89-
_Py_IDENTIFIER(showalloccount);
90-
91-
xoptions = PySys_GetXOptions();
92-
if (xoptions == NULL)
93-
return;
94-
value = _PyDict_GetItemId(xoptions, &PyId_showalloccount);
95-
if (value != Py_True)
88+
PyInterpreterState *interp = PyThreadState_GET()->interp;
89+
if (!inter->core_config.show_alloc_count) {
9690
return;
91+
}
9792

9893
fprintf(stderr, "List allocations: %" PY_FORMAT_SIZE_T "d\n",
9994
count_alloc);

Objects/object.c

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,6 @@ _Py_GetRefTotal(void)
2929
return total;
3030
}
3131

32-
PyObject *
33-
_PyDebug_XOptionShowRefCount(void)
34-
{
35-
PyObject *xoptions = PySys_GetXOptions();
36-
if (xoptions == NULL)
37-
return NULL;
38-
39-
_Py_IDENTIFIER(showrefcount);
40-
return _PyDict_GetItemId(xoptions, &PyId_showrefcount);
41-
}
42-
4332
void
4433
_PyDebug_PrintTotalRefs(void) {
4534
fprintf(stderr,
@@ -106,16 +95,10 @@ extern Py_ssize_t null_strings, one_strings;
10695
void
10796
dump_counts(FILE* f)
10897
{
109-
PyTypeObject *tp;
110-
PyObject *xoptions, *value;
111-
_Py_IDENTIFIER(showalloccount);
112-
113-
xoptions = PySys_GetXOptions();
114-
if (xoptions == NULL)
115-
return;
116-
value = _PyDict_GetItemId(xoptions, &PyId_showalloccount);
117-
if (value != Py_True)
98+
PyInterpreterState *interp = PyThreadState_GET()->interp;
99+
if (!inter->core_config.show_alloc_count) {
118100
return;
101+
}
119102

120103
for (tp = type_list; tp; tp = tp->tp_next)
121104
fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, "

Objects/tupleobject.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,10 @@ static Py_ssize_t count_tracked = 0;
4444
static void
4545
show_track(void)
4646
{
47-
PyObject *xoptions, *value;
48-
_Py_IDENTIFIER(showalloccount);
49-
50-
xoptions = PySys_GetXOptions();
51-
if (xoptions == NULL)
52-
return;
53-
value = _PyDict_GetItemId(xoptions, &PyId_showalloccount);
54-
if (value != Py_True)
47+
PyInterpreterState *interp = PyThreadState_GET()->interp;
48+
if (!inter->core_config.show_alloc_count) {
5549
return;
50+
}
5651

5752
fprintf(stderr, "Tuples created: %" PY_FORMAT_SIZE_T "d\n",
5853
count_tracked + count_untracked);

Python/import.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1674,8 +1674,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16741674
}
16751675
}
16761676
else {
1677-
/* 1 -- true, 0 -- false, -1 -- not initialized */
1678-
int importtime = interp->core_config.importtime;
1677+
int import_time = interp->core_config.import_time;
16791678
static int import_level;
16801679
static _PyTime_t accumulated;
16811680

@@ -1686,7 +1685,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
16861685
* Anyway, importlib._find_and_load is much slower than
16871686
* _PyDict_GetItemIdWithError().
16881687
*/
1689-
if (importtime) {
1688+
if (import_time) {
16901689
static int header = 1;
16911690
if (header) {
16921691
fputs("import time: self [us] | cumulative | imported package\n",
@@ -1712,7 +1711,7 @@ PyImport_ImportModuleLevelObject(PyObject *name, PyObject *globals,
17121711
PyDTrace_IMPORT_FIND_LOAD_DONE(PyUnicode_AsUTF8(abs_name),
17131712
mod != NULL);
17141713

1715-
if (importtime) {
1714+
if (import_time) {
17161715
_PyTime_t cum = _PyTime_GetPerfCounter() - t1;
17171716

17181717
import_level--;

Python/pylifecycle.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,10 +1101,6 @@ Py_FinalizeEx(void)
11011101
/* nothing */;
11021102
#endif
11031103

1104-
#ifdef Py_REF_DEBUG
1105-
PyObject *showrefcount = _PyDebug_XOptionShowRefCount();
1106-
#endif
1107-
11081104
/* Destroy all modules */
11091105
PyImport_Cleanup();
11101106

@@ -1153,8 +1149,9 @@ Py_FinalizeEx(void)
11531149
_PyHash_Fini();
11541150

11551151
#ifdef Py_REF_DEBUG
1156-
if (showrefcount == Py_True)
1157-
_PyDebug_PrintTotalRefs();
1152+
if (interp->core_config.show_ref_count) {
1153+
_PyDebug_PrintTotalRefs();
1154+
}
11581155
#endif
11591156

11601157
#ifdef Py_TRACE_REFS

Python/pythonrun.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
9191
int ret, err;
9292
PyCompilerFlags local_flags;
9393
int nomem_count = 0;
94+
#ifdef Py_REF_DEBUG
95+
int show_ref_count = PyThreadState_GET()->interp->core_config.show_ref_count;
96+
#endif
9497

9598
filename = PyUnicode_DecodeFSDefault(filename_str);
9699
if (filename == NULL) {
@@ -134,8 +137,9 @@ PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *
134137
nomem_count = 0;
135138
}
136139
#ifdef Py_REF_DEBUG
137-
if (_PyDebug_XOptionShowRefCount() == Py_True)
140+
if (show_ref_count) {
138141
_PyDebug_PrintTotalRefs();
142+
}
139143
#endif
140144
} while (ret != E_EOF);
141145
Py_DECREF(filename);

0 commit comments

Comments
 (0)