diff options
Diffstat (limited to 'Zend/zend.c')
-rw-r--r-- | Zend/zend.c | 126 |
1 files changed, 106 insertions, 20 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 6836e5af0c..1e4d2a0f42 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -33,6 +33,8 @@ #include "zend_smart_string.h" #include "zend_cpuinfo.h" +static size_t global_map_ptr_last = 0; + #ifdef ZTS ZEND_API int compiler_globals_id; ZEND_API int executor_globals_id; @@ -41,7 +43,6 @@ static HashTable *global_class_table = NULL; static HashTable *global_constants_table = NULL; static HashTable *global_auto_globals_table = NULL; static HashTable *global_persistent_list = NULL; -static zend_uintptr_t global_last_static_member = 0; ZEND_TSRMLS_CACHE_DEFINE() # define GLOBAL_FUNCTION_TABLE global_function_table # define GLOBAL_CLASS_TABLE global_class_table @@ -626,13 +627,22 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{ zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0); zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor); - compiler_globals->last_static_member = global_last_static_member; - if (compiler_globals->last_static_member) { - compiler_globals->static_members_table = calloc(compiler_globals->last_static_member + 1, sizeof(zval*)); - } else { - compiler_globals->static_members_table = NULL; - } compiler_globals->script_encoding_list = NULL; + +#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET + /* Map region is going to be created and resized at run-time. */ + compiler_globals->map_ptr_base = NULL; + compiler_globals->map_ptr_size = 0; + compiler_globals->map_ptr_last = global_map_ptr_last; + if (compiler_globals->map_ptr_last) { + /* Allocate map_ptr table */ + compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096); + compiler_globals->map_ptr_base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1); + memset(compiler_globals->map_ptr_base, 0, compiler_globals->map_ptr_last * sizeof(void*)); + } +#else +# error "Unknown ZEND_MAP_PTR_KIND" +#endif } /* }}} */ @@ -650,13 +660,14 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{ zend_hash_destroy(compiler_globals->auto_globals); free(compiler_globals->auto_globals); } - if (compiler_globals->static_members_table) { - free(compiler_globals->static_members_table); - } if (compiler_globals->script_encoding_list) { pefree((char*)compiler_globals->script_encoding_list, 1); } - compiler_globals->last_static_member = 0; + if (compiler_globals->map_ptr_base) { + free(compiler_globals->map_ptr_base); + compiler_globals->map_ptr_base = NULL; + compiler_globals->map_ptr_size = 0; + } } /* }}} */ @@ -879,6 +890,22 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) / #ifdef ZEND_WIN32 zend_get_windows_version_info(&EG(windows_version_info)); #endif +# if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR + /* Create a map region, used for indirect pointers from shared to + * process memory. It's allocatred once and never resized. + * All processes must map it into the same address space. + */ + CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ??? + CG(map_ptr_last) = 0; + CG(map_ptr_base) = pemalloc(CG(map_ptr_size) * sizeof(void*), 1); +# elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET + /* Map region is going to be created and resized at run-time. */ + CG(map_ptr_base) = NULL; + CG(map_ptr_size) = 0; + CG(map_ptr_last) = 0; +# else +# error "Unknown ZEND_MAP_PTR_KIND" +# endif #endif EG(error_reporting) = E_ALL & ~E_NOTICE; @@ -931,7 +958,7 @@ int zend_post_startup(void) /* {{{ */ *GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table; *GLOBAL_CLASS_TABLE = *compiler_globals->class_table; *GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants; - global_last_static_member = compiler_globals->last_static_member; + global_map_ptr_last = compiler_globals->map_ptr_last; short_tags_default = CG(short_tags); compiler_options_default = CG(compiler_options); @@ -950,6 +977,8 @@ int zend_post_startup(void) /* {{{ */ executor_globals_ctor(executor_globals); global_persistent_list = &EG(persistent_list); zend_copy_ini_directives(); +#else + global_map_ptr_last = CG(map_ptr_last); #endif if (zend_post_startup_cb) { @@ -996,6 +1025,12 @@ void zend_shutdown(void) /* {{{ */ GLOBAL_CLASS_TABLE = NULL; GLOBAL_AUTO_GLOBALS_TABLE = NULL; GLOBAL_CONSTANTS_TABLE = NULL; +#else + if (CG(map_ptr_base)) { + free(CG(map_ptr_base)); + CG(map_ptr_base) = NULL; + CG(map_ptr_size) = 0; + } #endif zend_destroy_rsrc_list_dtors(); } @@ -1077,17 +1112,12 @@ ZEND_API void zend_activate(void) /* {{{ */ init_compiler(); init_executor(); startup_scanner(); + if (CG(map_ptr_last)) { + memset(CG(map_ptr_base), 0, CG(map_ptr_last) * sizeof(void*)); + } } /* }}} */ -#ifdef ZTS -void zend_reset_internal_classes(void) /* {{{ */ -{ - CG(last_static_member) = global_last_static_member; -} -/* }}} */ -#endif - void zend_call_destructors(void) /* {{{ */ { zend_try { @@ -1619,6 +1649,62 @@ void free_estring(char **str_p) /* {{{ */ } /* }}} */ +ZEND_API void zend_map_ptr_reset(void) +{ + CG(map_ptr_last) = global_map_ptr_last; +} + +ZEND_API void *zend_map_ptr_new(void) +{ + void **ptr; + + if (CG(map_ptr_last) >= CG(map_ptr_size)) { +#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR + // TODO: error ??? + ZEND_ASSERT(0); +#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET + /* Grow map_ptr table */ + CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096); + CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1); +#else +# error "Unknown ZEND_MAP_PTR_KIND" +#endif + } + ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last); + *ptr = NULL; + CG(map_ptr_last)++; +#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR + return ptr; +#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET + return ZEND_MAP_PTR_PTR2OFFSET(ptr); +#else +# error "Unknown ZEND_MAP_PTR_KIND" +#endif +} + +ZEND_API void zend_map_ptr_extend(size_t last) +{ + if (last > CG(map_ptr_last)) { + void **ptr; + + if (last >= CG(map_ptr_size)) { +#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR + /* This may never happen */ + ZEND_ASSERT(0); +#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET + /* Grow map_ptr table */ + CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096); + CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1); +#else +# error "Unknown ZEND_MAP_PTR_KIND" +#endif + } + ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last); + memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*)); + CG(map_ptr_last) = last; + } +} + /* * Local variables: * tab-width: 4 |