mirror of
				https://github.com/python/cpython.git
				synced 2025-10-25 18:54:53 +00:00 
			
		
		
		
	bpo-36763: Add PyMemAllocatorName (GH-13387)
* Add PyMemAllocatorName enum * _PyPreConfig.allocator type becomes PyMemAllocatorName, instead of char* * Remove _PyPreConfig_Clear() * Add _PyMem_GetAllocatorName() * Rename _PyMem_GetAllocatorsName() to _PyMem_GetCurrentAllocatorName() * Remove _PyPreConfig_SetAllocator(): just call _PyMem_SetupAllocators() directly, we don't have do reallocate the configuration with the new allocator anymore! * _PyPreConfig_Write() parameter becomes const, as it should be in the first place!
This commit is contained in:
		
							parent
							
								
									80ed353329
								
							
						
					
					
						commit
						b16b4e4592
					
				
					 12 changed files with 119 additions and 112 deletions
				
			
		|  | @ -2021,26 +2021,22 @@ core_read_precmdline(_PyCoreConfig *config, _PyPreCmdline *precmdline) | |||
|     _PyPreConfig preconfig = _PyPreConfig_INIT; | ||||
|     if (_PyPreConfig_Copy(&preconfig, &_PyRuntime.preconfig) < 0) { | ||||
|         err = _Py_INIT_NO_MEMORY(); | ||||
|         goto done; | ||||
|         return err; | ||||
|     } | ||||
| 
 | ||||
|     _PyCoreConfig_GetCoreConfig(&preconfig, config); | ||||
| 
 | ||||
|     err = _PyPreCmdline_Read(precmdline, &preconfig); | ||||
|     if (_Py_INIT_FAILED(err)) { | ||||
|         goto done; | ||||
|         return err; | ||||
|     } | ||||
| 
 | ||||
|     if (_PyPreCmdline_SetCoreConfig(precmdline, config) < 0) { | ||||
|         err = _Py_INIT_NO_MEMORY(); | ||||
|         goto done; | ||||
|         return err; | ||||
|     } | ||||
| 
 | ||||
|     err = _Py_INIT_OK(); | ||||
| 
 | ||||
| done: | ||||
|     _PyPreConfig_Clear(&preconfig); | ||||
|     return err; | ||||
|     return _Py_INIT_OK(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -260,19 +260,9 @@ _PyPreCmdline_Read(_PyPreCmdline *cmdline, | |||
| 
 | ||||
| /* --- _PyPreConfig ----------------------------------------------- */ | ||||
| 
 | ||||
| void | ||||
| _PyPreConfig_Clear(_PyPreConfig *config) | ||||
| { | ||||
|     PyMem_RawFree(config->allocator); | ||||
|     config->allocator = NULL; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int | ||||
| _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) | ||||
| { | ||||
|     _PyPreConfig_Clear(config); | ||||
| 
 | ||||
| #define COPY_ATTR(ATTR) config->ATTR = config2->ATTR | ||||
| #define COPY_STR_ATTR(ATTR) \ | ||||
|     do { \ | ||||
|  | @ -293,7 +283,7 @@ _PyPreConfig_Copy(_PyPreConfig *config, const _PyPreConfig *config2) | |||
|     COPY_ATTR(legacy_windows_fs_encoding); | ||||
| #endif | ||||
|     COPY_ATTR(utf8_mode); | ||||
|     COPY_STR_ATTR(allocator); | ||||
|     COPY_ATTR(allocator); | ||||
| 
 | ||||
| #undef COPY_ATTR | ||||
| #undef COPY_STR_ATTR | ||||
|  | @ -341,7 +331,7 @@ _PyPreConfig_AsDict(const _PyPreConfig *config) | |||
|     SET_ITEM_INT(legacy_windows_fs_encoding); | ||||
| #endif | ||||
|     SET_ITEM_INT(dev_mode); | ||||
|     SET_ITEM_STR(allocator); | ||||
|     SET_ITEM_INT(allocator); | ||||
|     return dict; | ||||
| 
 | ||||
| fail: | ||||
|  | @ -616,25 +606,21 @@ preconfig_init_coerce_c_locale(_PyPreConfig *config) | |||
| static _PyInitError | ||||
| preconfig_init_allocator(_PyPreConfig *config) | ||||
| { | ||||
|     if (config->allocator == NULL) { | ||||
|     if (config->allocator == PYMEM_ALLOCATOR_NOT_SET) { | ||||
|         /* bpo-34247. The PYTHONMALLOC environment variable has the priority
 | ||||
|            over PYTHONDEV env var and "-X dev" command line option. | ||||
|            For example, PYTHONMALLOC=malloc PYTHONDEVMODE=1 sets the memory | ||||
|            allocators to "malloc" (and not to "debug"). */ | ||||
|         const char *allocator = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); | ||||
|         if (allocator) { | ||||
|             config->allocator = _PyMem_RawStrdup(allocator); | ||||
|             if (config->allocator == NULL) { | ||||
|                 return _Py_INIT_NO_MEMORY(); | ||||
|         const char *envvar = _Py_GetEnv(config->use_environment, "PYTHONMALLOC"); | ||||
|         if (envvar) { | ||||
|             if (_PyMem_GetAllocatorName(envvar, &config->allocator) < 0) { | ||||
|                 return _Py_INIT_ERR("PYTHONMALLOC: unknown allocator"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (config->dev_mode && config->allocator == NULL) { | ||||
|         config->allocator = _PyMem_RawStrdup("debug"); | ||||
|         if (config->allocator == NULL) { | ||||
|             return _Py_INIT_NO_MEMORY(); | ||||
|         } | ||||
|     if (config->dev_mode && config->allocator == PYMEM_ALLOCATOR_NOT_SET) { | ||||
|         config->allocator = PYMEM_ALLOCATOR_DEBUG; | ||||
|     } | ||||
|     return _Py_INIT_OK(); | ||||
| } | ||||
|  | @ -815,7 +801,6 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) | |||
|         setlocale(LC_CTYPE, init_ctype_locale); | ||||
|         PyMem_RawFree(init_ctype_locale); | ||||
|     } | ||||
|     _PyPreConfig_Clear(&save_config); | ||||
|     Py_UTF8Mode = init_utf8_mode ; | ||||
| #ifdef MS_WINDOWS | ||||
|     Py_LegacyWindowsFSEncodingFlag = init_legacy_encoding; | ||||
|  | @ -825,40 +810,6 @@ _PyPreConfig_Read(_PyPreConfig *config, const _PyArgv *args) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| static _PyInitError | ||||
| _PyPreConfig_SetAllocator(_PyPreConfig *config) | ||||
| { | ||||
|     assert(!_PyRuntime.core_initialized); | ||||
| 
 | ||||
|     PyMemAllocatorEx old_alloc; | ||||
|     PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | ||||
| 
 | ||||
|     if (_PyMem_SetupAllocators(config->allocator) < 0) { | ||||
|         return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator"); | ||||
|     } | ||||
| 
 | ||||
|     /* Copy the pre-configuration with the new allocator */ | ||||
|     _PyPreConfig config2 = _PyPreConfig_INIT; | ||||
|     if (_PyPreConfig_Copy(&config2, config) < 0) { | ||||
|         _PyPreConfig_Clear(&config2); | ||||
|         PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | ||||
|         return _Py_INIT_NO_MEMORY(); | ||||
|     } | ||||
| 
 | ||||
|     /* Free the old config and replace config with config2. Since config now
 | ||||
|        owns the data, don't free config2. */ | ||||
|     PyMemAllocatorEx new_alloc; | ||||
|     PyMem_GetAllocator(PYMEM_DOMAIN_RAW, &new_alloc); | ||||
|     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | ||||
|     _PyPreConfig_Clear(config); | ||||
|     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &new_alloc); | ||||
| 
 | ||||
|     *config = config2; | ||||
| 
 | ||||
|     return _Py_INIT_OK(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Write the pre-configuration:
 | ||||
| 
 | ||||
|    - set the memory allocators | ||||
|  | @ -872,7 +823,7 @@ _PyPreConfig_SetAllocator(_PyPreConfig *config) | |||
|    Do nothing if called after Py_Initialize(): ignore the new | ||||
|    pre-configuration. */ | ||||
| _PyInitError | ||||
| _PyPreConfig_Write(_PyPreConfig *config) | ||||
| _PyPreConfig_Write(const _PyPreConfig *config) | ||||
| { | ||||
|     if (_PyRuntime.core_initialized) { | ||||
|         /* bpo-34008: Calling this functions after Py_Initialize() ignores
 | ||||
|  | @ -880,10 +831,9 @@ _PyPreConfig_Write(_PyPreConfig *config) | |||
|         return _Py_INIT_OK(); | ||||
|     } | ||||
| 
 | ||||
|     if (config->allocator != NULL) { | ||||
|         _PyInitError err = _PyPreConfig_SetAllocator(config); | ||||
|         if (_Py_INIT_FAILED(err)) { | ||||
|             return err; | ||||
|     if (config->allocator != PYMEM_ALLOCATOR_NOT_SET) { | ||||
|         if (_PyMem_SetupAllocators(config->allocator) < 0) { | ||||
|             return _Py_INIT_ERR("Unknown PYTHONMALLOC allocator"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -706,26 +706,22 @@ _Py_PreInitializeFromPyArgv(const _PyPreConfig *src_config, const _PyArgv *args) | |||
|     if (src_config) { | ||||
|         if (_PyPreConfig_Copy(&config, src_config) < 0) { | ||||
|             err = _Py_INIT_NO_MEMORY(); | ||||
|             goto done; | ||||
|             return err; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     err = _PyPreConfig_Read(&config, args); | ||||
|     if (_Py_INIT_FAILED(err)) { | ||||
|         goto done; | ||||
|         return err; | ||||
|     } | ||||
| 
 | ||||
|     err = _PyPreConfig_Write(&config); | ||||
|     if (_Py_INIT_FAILED(err)) { | ||||
|         goto done; | ||||
|         return err; | ||||
|     } | ||||
| 
 | ||||
|     runtime->pre_initialized = 1; | ||||
|     err = _Py_INIT_OK(); | ||||
| 
 | ||||
| done: | ||||
|     _PyPreConfig_Clear(&config); | ||||
|     return err; | ||||
|     return _Py_INIT_OK(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -106,8 +106,6 @@ _PyRuntimeState_Fini(_PyRuntimeState *runtime) | |||
|         runtime->xidregistry.mutex = NULL; | ||||
|     } | ||||
| 
 | ||||
|     _PyPreConfig_Clear(&runtime->preconfig); | ||||
| 
 | ||||
|     PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner