X Tutup
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Include/objimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
/* Macros */
#ifdef WITH_PYMALLOC
#ifndef Py_LIMITED_API
PyAPI_FUNC(void) _PyObject_DebugMallocStats(FILE *out);
PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out);
#endif /* #ifndef Py_LIMITED_API */
#endif

Expand Down
4 changes: 0 additions & 4 deletions Include/pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@ PyAPI_FUNC(int) _PyMem_SetupAllocators(const char *opt);
/* Try to get the allocators name set by _PyMem_SetupAllocators(). */
PyAPI_FUNC(const char*) _PyMem_GetAllocatorsName(void);

#ifdef WITH_PYMALLOC
PyAPI_FUNC(int) _PyMem_PymallocEnabled(void);
#endif

/* Track an allocated memory block in the tracemalloc module.
Return 0 on success, return -1 on error (failed to allocate memory to store
the trace).
Expand Down
10 changes: 6 additions & 4 deletions Include/pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ typedef struct {
int import_time; /* -X importtime */
int show_ref_count; /* -X showrefcount */
int show_alloc_count; /* -X showalloccount */
int dump_refs; /* PYTHONDUMPREFS */
int malloc_stats; /* PYTHONMALLOCSTATS */
} _PyCoreConfig;

#define _PyCoreConfig_INIT (_PyCoreConfig){.use_hash_seed = -1}
Expand Down Expand Up @@ -111,7 +113,7 @@ typedef struct _is {
PyObject *after_forkers_child;
#endif
} PyInterpreterState;
#endif
#endif /* !Py_LIMITED_API */


/* State unique per thread */
Expand All @@ -133,7 +135,7 @@ typedef int (*Py_tracefunc)(PyObject *, struct _frame *, int, PyObject *);
#define PyTrace_C_EXCEPTION 5
#define PyTrace_C_RETURN 6
#define PyTrace_OPCODE 7
#endif
#endif /* Py_LIMITED_API */

#ifdef Py_LIMITED_API
typedef struct _ts PyThreadState;
Expand Down Expand Up @@ -238,7 +240,7 @@ typedef struct _ts {
/* XXX signal handlers should also be here */

} PyThreadState;
#endif
#endif /* !Py_LIMITED_API */


PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
Expand Down Expand Up @@ -363,7 +365,7 @@ PyAPI_FUNC(int) PyGILState_Check(void);
Return NULL before _PyGILState_Init() is called and after _PyGILState_Fini()
is called. */
PyAPI_FUNC(PyInterpreterState *) _PyGILState_GetInterpreterStateUnsafe(void);
#endif
#endif /* !Py_LIMITED_API */


/* The implementation of sys._current_frames() Returns a dict mapping
Expand Down
170 changes: 113 additions & 57 deletions Modules/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,8 +162,8 @@ pymain_get_env_var(const char *name)
static void
pymain_run_startup(PyCompilerFlags *cf)
{
char *startup = Py_GETENV("PYTHONSTARTUP");
if (startup == NULL || startup[0] == '\0') {
char *startup = pymain_get_env_var("PYTHONSTARTUP");
if (startup == NULL) {
return;
}

Expand Down Expand Up @@ -377,23 +377,28 @@ typedef struct {
wchar_t *command; /* -c argument */
wchar_t *module; /* -m argument */
_Py_OptList warning_options; /* -W options */
PyObject *extra_options; /* -X options */
int print_help; /* -h, -? options */
int print_version; /* -V option */
int bytes_warning; /* Py_BytesWarningFlag */
int debug; /* Py_DebugFlag */
int inspect; /* Py_InspectFlag */
int interactive; /* Py_InteractiveFlag */
int isolated; /* Py_IsolatedFlag */
int optimization_level; /* Py_OptimizeFlag */
int dont_write_bytecode; /* Py_DontWriteBytecodeFlag */
int no_user_site_directory; /* Py_NoUserSiteDirectory */
int no_site_import; /* Py_NoSiteFlag */
int use_unbuffered_io; /* Py_UnbufferedStdioFlag */
int verbosity; /* Py_VerboseFlag */
int quiet_flag; /* Py_QuietFlag */
int bytes_warning; /* Py_BytesWarningFlag, -b */
int debug; /* Py_DebugFlag, -b, PYTHONDEBUG */
int inspect; /* Py_InspectFlag, -i, PYTHONINSPECT */
int interactive; /* Py_InteractiveFlag, -i */
int isolated; /* Py_IsolatedFlag, -I */
int optimization_level; /* Py_OptimizeFlag, -O, PYTHONOPTIMIZE */
int dont_write_bytecode; /* Py_DontWriteBytecodeFlag, -B, PYTHONDONTWRITEBYTECODE */
int no_user_site_directory; /* Py_NoUserSiteDirectory, -I, -s, PYTHONNOUSERSITE */
int no_site_import; /* Py_NoSiteFlag, -S */
int use_unbuffered_io; /* Py_UnbufferedStdioFlag, -u, PYTHONUNBUFFERED */
int verbosity; /* Py_VerboseFlag, -v, PYTHONVERBOSE */
int quiet_flag; /* Py_QuietFlag, -q */
int skip_first_line; /* -x option */
_Py_OptList xoptions; /* -X options */
#ifdef MS_WINDOWS
int legacy_windows_fs_encoding; /* Py_LegacyWindowsFSEncodingFlag,
PYTHONLEGACYWINDOWSFSENCODING */
int legacy_windows_stdio; /* Py_LegacyWindowsStdioFlag,
PYTHONLEGACYWINDOWSSTDIO */
#endif
} _Py_CommandLineDetails;

/* Structure used by Py_Main() to pass data to subfunctions */
Expand Down Expand Up @@ -695,19 +700,6 @@ pymain_parse_cmdline_impl(_PyMain *pymain)
}


static void
maybe_set_flag(int *flag, int value)
{
/* Helper to set flag variables from command line options
* - uses the higher of the two values if they're both set
* - otherwise leaves the flag unset
*/
if (*flag < value) {
*flag = value;
}
}


static int
pymain_add_xoptions(_PyMain *pymain)
{
Expand Down Expand Up @@ -790,9 +782,8 @@ pymain_warnings_envvar(_PyMain *pymain)
PyMem_RawFree(buf);
}
#else
char *p;

if ((p = Py_GETENV("PYTHONWARNINGS")) && *p != '\0') {
char *p = pymain_get_env_var("PYTHONWARNINGS");
if (p != NULL) {
char *buf, *oldloc;

/* settle for strtok here as there's no one standard
Expand Down Expand Up @@ -885,7 +876,6 @@ config_get_program_name(_PyMainInterpreterConfig *config)
}

#ifdef __APPLE__
char *p;
/* On MacOS X, when the Python interpreter is embedded in an
application bundle, it gets executed by a bootstrapping script
that does os.execve() with an argv[0] that's different from the
Expand All @@ -895,7 +885,8 @@ config_get_program_name(_PyMainInterpreterConfig *config)
so the actual executable path is passed in an environment variable.
See Lib/plat-mac/bundlebuiler.py for details about the bootstrap
script. */
if ((p = Py_GETENV("PYTHONEXECUTABLE")) && *p != '\0') {
char *p = pymain_get_env_var("PYTHONEXECUTABLE");
if (p != NULL) {
size_t len;
wchar_t* program_name = Py_DecodeLocale(p, &len);
if (program_name == NULL) {
Expand Down Expand Up @@ -1015,25 +1006,76 @@ pymain_set_argv(_PyMain *pymain)
}


static void
pymain_get_flag(int flag, int *value)
{
if (flag) {
*value = flag;
}
}

static void
pymain_set_flag(int *flag, int value)
{
/* Helper to set flag variables from command line options
* - uses the higher of the two values if they're both set
* - otherwise leaves the flag unset
*/
if (*flag < value) {
*flag = value;
}
}


/* Get Py_xxx global configuration variables */
static void
pymain_get_global_config(_PyMain *pymain)
{
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
pymain_get_flag(Py_BytesWarningFlag, &cmdline->bytes_warning);
pymain_get_flag(Py_DebugFlag, &cmdline->debug);
pymain_get_flag(Py_InspectFlag, &cmdline->inspect);
pymain_get_flag(Py_InteractiveFlag, &cmdline->interactive);
pymain_get_flag(Py_IsolatedFlag, &cmdline->isolated);
pymain_get_flag(Py_OptimizeFlag, &cmdline->optimization_level);
pymain_get_flag(Py_DontWriteBytecodeFlag, &cmdline->dont_write_bytecode);
pymain_get_flag(Py_NoUserSiteDirectory, &cmdline->no_user_site_directory);
pymain_get_flag(Py_NoSiteFlag, &cmdline->no_site_import);
pymain_get_flag(Py_UnbufferedStdioFlag, &cmdline->use_unbuffered_io);
pymain_get_flag(Py_VerboseFlag, &cmdline->verbosity);
pymain_get_flag(Py_QuietFlag, &cmdline->quiet_flag);
#ifdef MS_WINDOWS
pymain_get_flag(Py_LegacyWindowsFSEncodingFlag, &cmdline->legacy_windows_fs_encoding);
pymain_get_flag(Py_LegacyWindowsStdioFlag, &cmdline->legacy_windows_stdio);
#endif

pymain_get_flag(Py_IgnoreEnvironmentFlag, &pymain->core_config.ignore_environment);
}


/* Set Py_XXX global configuration variables */
static void
pymain_set_global_config(_PyMain *pymain)
{
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
maybe_set_flag(&Py_BytesWarningFlag, cmdline->bytes_warning);
maybe_set_flag(&Py_DebugFlag, cmdline->debug);
maybe_set_flag(&Py_InspectFlag, cmdline->inspect);
maybe_set_flag(&Py_InteractiveFlag, cmdline->interactive);
maybe_set_flag(&Py_IsolatedFlag, cmdline->isolated);
maybe_set_flag(&Py_OptimizeFlag, cmdline->optimization_level);
maybe_set_flag(&Py_DontWriteBytecodeFlag, cmdline->dont_write_bytecode);
maybe_set_flag(&Py_NoUserSiteDirectory, cmdline->no_user_site_directory);
maybe_set_flag(&Py_NoSiteFlag, cmdline->no_site_import);
maybe_set_flag(&Py_UnbufferedStdioFlag, cmdline->use_unbuffered_io);
maybe_set_flag(&Py_VerboseFlag, cmdline->verbosity);
maybe_set_flag(&Py_QuietFlag, cmdline->quiet_flag);

maybe_set_flag(&Py_IgnoreEnvironmentFlag, pymain->core_config.ignore_environment);
pymain_set_flag(&Py_BytesWarningFlag, cmdline->bytes_warning);
pymain_set_flag(&Py_DebugFlag, cmdline->debug);
pymain_set_flag(&Py_InspectFlag, cmdline->inspect);
pymain_set_flag(&Py_InteractiveFlag, cmdline->interactive);
pymain_set_flag(&Py_IsolatedFlag, cmdline->isolated);
pymain_set_flag(&Py_OptimizeFlag, cmdline->optimization_level);
pymain_set_flag(&Py_DontWriteBytecodeFlag, cmdline->dont_write_bytecode);
pymain_set_flag(&Py_NoUserSiteDirectory, cmdline->no_user_site_directory);
pymain_set_flag(&Py_NoSiteFlag, cmdline->no_site_import);
pymain_set_flag(&Py_UnbufferedStdioFlag, cmdline->use_unbuffered_io);
pymain_set_flag(&Py_VerboseFlag, cmdline->verbosity);
pymain_set_flag(&Py_QuietFlag, cmdline->quiet_flag);
#ifdef MS_WINDOWS
pymain_set_flag(&Py_LegacyWindowsFSEncodingFlag, cmdline->legacy_windows_fs_encoding);
pymain_set_flag(&Py_LegacyWindowsStdioFlag, cmdline->legacy_windows_stdio);
#endif

pymain_set_flag(&Py_IgnoreEnvironmentFlag, pymain->core_config.ignore_environment);
}


Expand Down Expand Up @@ -1330,24 +1372,25 @@ pymain_set_flag_from_env(int *flag, const char *name)
static void
pymain_set_flags_from_env(_PyMain *pymain)
{
pymain_set_flag_from_env(&Py_DebugFlag,
_Py_CommandLineDetails *cmdline = &pymain->cmdline;
pymain_set_flag_from_env(&cmdline->debug,
"PYTHONDEBUG");
pymain_set_flag_from_env(&Py_VerboseFlag,
pymain_set_flag_from_env(&cmdline->verbosity,
"PYTHONVERBOSE");
pymain_set_flag_from_env(&Py_OptimizeFlag,
pymain_set_flag_from_env(&cmdline->optimization_level,
"PYTHONOPTIMIZE");
pymain_set_flag_from_env(&Py_InspectFlag,
pymain_set_flag_from_env(&cmdline->inspect,
"PYTHONINSPECT");
pymain_set_flag_from_env(&Py_DontWriteBytecodeFlag,
pymain_set_flag_from_env(&cmdline->dont_write_bytecode,
"PYTHONDONTWRITEBYTECODE");
pymain_set_flag_from_env(&Py_NoUserSiteDirectory,
pymain_set_flag_from_env(&cmdline->no_user_site_directory,
"PYTHONNOUSERSITE");
pymain_set_flag_from_env(&Py_UnbufferedStdioFlag,
pymain_set_flag_from_env(&cmdline->use_unbuffered_io,
"PYTHONUNBUFFERED");
#ifdef MS_WINDOWS
pymain_set_flag_from_env(&Py_LegacyWindowsFSEncodingFlag,
pymain_set_flag_from_env(&cmdline->legacy_windows_fs_encoding,
"PYTHONLEGACYWINDOWSFSENCODING");
pymain_set_flag_from_env(&Py_LegacyWindowsStdioFlag,
pymain_set_flag_from_env(&cmdline->legacy_windows_stdio,
"PYTHONLEGACYWINDOWSSTDIO");
#endif
}
Expand Down Expand Up @@ -1485,7 +1528,7 @@ pymain_parse_envvars(_PyMain *pymain)
return -1;
}

core_config->allocator = Py_GETENV("PYTHONMALLOC");
core_config->allocator = pymain_get_env_var("PYTHONMALLOC");

/* -X options */
if (pymain_get_xoption(pymain, L"showrefcount")) {
Expand Down Expand Up @@ -1514,6 +1557,14 @@ pymain_parse_envvars(_PyMain *pymain)
core_config->faulthandler = 1;
core_config->allocator = "debug";
}
if (pymain_get_env_var("PYTHONDUMPREFS")) {
pymain->core_config.dump_refs = 1;
}
if (pymain_get_env_var("PYTHONMALLOCSTATS")) {
pymain->core_config.malloc_stats = 1;
}


return 0;
}

Expand All @@ -1535,6 +1586,7 @@ pymain_parse_cmdline_envvars_impl(_PyMain *pymain)
return 1;
}

/* Set Py_IgnoreEnvironmentFlag needed by Py_GETENV() */
pymain_set_global_config(pymain);

if (pymain_parse_envvars(pymain) < 0) {
Expand Down Expand Up @@ -1568,6 +1620,8 @@ pymain_parse_cmdline_envvars(_PyMain *pymain)
static int
pymain_init_python(_PyMain *pymain)
{
pymain_set_global_config(pymain);

pymain_init_stdio(pymain);

pymain->err = _Py_InitializeCore(&pymain->core_config);
Expand Down Expand Up @@ -1641,6 +1695,8 @@ pymain_impl(_PyMain *pymain)
return -1;
}

pymain_get_global_config(pymain);

res = pymain_parse_cmdline_envvars(pymain);
if (res < 0) {
return -1;
Expand Down
12 changes: 10 additions & 2 deletions Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ _PyMem_DebugEnabled(void)
return (_PyObject.malloc == _PyMem_DebugMalloc);
}

int
static int
_PyMem_PymallocEnabled(void)
{
if (_PyMem_DebugEnabled()) {
Expand Down Expand Up @@ -2467,10 +2467,17 @@ pool_is_in_list(const poolp target, poolp list)
/* Print summary info to "out" about the state of pymalloc's structures.
* In Py_DEBUG mode, also perform some expensive internal consistency
* checks.
*
* Return 0 if the memory debug hooks are not installed or no statistics was
* writen into out, return 1 otherwise.
*/
void
int
_PyObject_DebugMallocStats(FILE *out)
{
if (!_PyMem_PymallocEnabled()) {
return 0;
}

uint i;
const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
/* # of pools, allocated blocks, and free blocks per class index */
Expand Down Expand Up @@ -2603,6 +2610,7 @@ _PyObject_DebugMallocStats(FILE *out)
total += printone(out, "# bytes lost to quantization", quantization);
total += printone(out, "# bytes lost to arena alignment", arena_alignment);
(void)printone(out, "Total", total);
return 1;
}

#endif /* #ifdef WITH_PYMALLOC */
Loading
X Tutup