summaryrefslogtreecommitdiff
path: root/Zend/zend.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend.c')
-rw-r--r--Zend/zend.c126
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