dmitry                                   Thu, 08 Jul 2010 14:05:11 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=301081

Log:
- use interned strings for auto globals
- $GLOBALS became a JIT autoglobal, so it's initialized only if used (this may 
affect opcode caches)

Changed paths:
    U   php/php-src/trunk/NEWS
    U   php/php-src/trunk/Zend/micro_bench.php
    U   php/php-src/trunk/Zend/zend.c
    U   php/php-src/trunk/Zend/zend_compile.c
    U   php/php-src/trunk/Zend/zend_compile.h
    U   php/php-src/trunk/Zend/zend_execute_API.c
    U   php/php-src/trunk/ext/session/session.c
    U   php/php-src/trunk/main/php_variables.c

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/NEWS	2010-07-08 14:05:11 UTC (rev 301081)
@@ -19,6 +19,8 @@
     instruction without previous ZEND_FETCH_CLASS.
   . eliminated unnecessary iterations during request startup/shutdown
   . zend_stack initialization is delayed before the actual usage
+  . $GLOBALS became a JIT autoglobal, so it's initialized only if used
+    (this may affect opcode caches)
 - Added concept of interned strings. All strings constants known at compile
   time are allocated in a single copy and never changed. (Dmitry)
 - Added an optimization which saves memory and emalloc/efree calls for empty

Modified: php/php-src/trunk/Zend/micro_bench.php
===================================================================
--- php/php-src/trunk/Zend/micro_bench.php	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/Zend/micro_bench.php	2010-07-08 14:05:11 UTC (rev 301081)
@@ -174,6 +174,20 @@
 	}
 }

+function read_auto_global($n) {
+	for ($i = 0; $i < $n; ++$i) {
+		$x = $_GET;
+	}
+}
+
+$g_var = 0;
+
+function read_global_var($n) {
+	for ($i = 0; $i < $n; ++$i) {
+		$x = $GLOBALS['g_var'];
+	}
+}
+
 /*****/

 function empty_loop($n) {
@@ -282,4 +296,8 @@
 $t = end_test($t, 'new Foo()', $overhead);
 read_const(N);
 $t = end_test($t, '$x = TEST', $overhead);
+read_auto_global(N);
+$t = end_test($t, '$x = $_GET', $overhead);
+read_global_var(N);
+$t = end_test($t, '$x = $GLOBALS[\'v\']', $overhead);
 total($t0, "Total");

Modified: php/php-src/trunk/Zend/zend.c
===================================================================
--- php/php-src/trunk/Zend/zend.c	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/Zend/zend.c	2010-07-08 14:05:11 UTC (rev 301081)
@@ -593,6 +593,20 @@

 void zend_init_opcodes_handlers(void);

+static zend_bool php_auto_globals_create_globals(char *name, uint name_len TSRMLS_DC) /* {{{ */
+{
+	zval *globals;
+
+	ALLOC_ZVAL(globals);
+	Z_SET_REFCOUNT_P(globals, 1);
+	Z_SET_ISREF_P(globals);
+	Z_TYPE_P(globals) = IS_ARRAY;
+	Z_ARRVAL_P(globals) = &EG(symbol_table);
+	zend_hash_update(&EG(symbol_table), name, name_len + 1, &globals, sizeof(zval *), NULL);
+	return 0;
+}
+/* }}} */
+
 int zend_startup(zend_utility_functions *utility_functions, char **extensions TSRMLS_DC) /* {{{ */
 {
 #ifdef ZTS
@@ -660,7 +674,7 @@

 	zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
 	zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
-	zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, (dtor_func_t) zend_auto_global_dtor, 1, 0);
+	zend_hash_init_ex(GLOBAL_AUTO_GLOBALS_TABLE, 8, NULL, NULL, 1, 0);
 	zend_hash_init_ex(GLOBAL_CONSTANTS_TABLE, 20, NULL, ZEND_CONSTANT_DTOR, 1, 0);

 	zend_hash_init_ex(&module_registry, 50, NULL, ZEND_MODULE_DTOR, 1, 0);
@@ -701,7 +715,7 @@
 	zend_interned_strings_init(TSRMLS_C);
 	zend_startup_builtin_functions(TSRMLS_C);
 	zend_register_standard_constants(TSRMLS_C);
-	zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, NULL TSRMLS_CC);
+	zend_register_auto_global("GLOBALS", sizeof("GLOBALS") - 1, 1, php_auto_globals_create_globals TSRMLS_CC);

 #ifndef ZTS
 	zend_init_rsrc_plist(TSRMLS_C);

Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/Zend/zend_compile.c	2010-07-08 14:05:11 UTC (rev 301081)
@@ -163,27 +163,6 @@
 /* }}} */


-int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
-{
-	auto_global->armed = (auto_global->auto_global_callback ? 1 : 0);
-	return 0;
-}
-/* }}} */
-
-
-ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC) /* {{{ */
-{
-	zend_auto_global *auto_global;
-
-	if (zend_hash_find(CG(auto_globals), varname, varname_length+1, (void **) &auto_global)==FAILURE) {
-		return FAILURE;
-	}
-	auto_global->armed = 0;
-	return SUCCESS;
-}
-/* }}} */
-
-
 static void init_compiler_declarables(TSRMLS_D) /* {{{ */
 {
 	Z_TYPE(CG(declarables).ticks) = IS_LONG;
@@ -211,7 +190,6 @@
 	CG(has_bracketed_namespaces) = 0;
 	CG(current_import) = NULL;
 	init_compiler_declarables(TSRMLS_C);
-	zend_hash_apply(CG(auto_globals), (apply_func_t) zend_auto_global_arm TSRMLS_CC);
 	zend_stack_init(&CG(labels_stack));
 	CG(labels) = NULL;

@@ -6069,12 +6047,6 @@
 }
 /* }}} */

-void zend_auto_global_dtor(zend_auto_global *auto_global) /* {{{ */
-{
-	free(auto_global->name);
-}
-/* }}} */
-
 zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) /* {{{ */
 {
 	zend_auto_global *auto_global;
@@ -6089,18 +6061,38 @@
 }
 /* }}} */

-int zend_register_auto_global(const char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC) /* {{{ */
+int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC) /* {{{ */
 {
 	zend_auto_global auto_global;

-	auto_global.name = zend_strndup(name, name_len);
+	auto_global.name = zend_new_interned_string(name, name_len + 1, 0);
 	auto_global.name_len = name_len;
 	auto_global.auto_global_callback = auto_global_callback;
+	auto_global.jit = jit;

 	return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), NULL);
 }
 /* }}} */

+static int zend_auto_global_init(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */
+{
+    if (auto_global->jit) {
+		auto_global->armed = 1;
+    } else if (auto_global->auto_global_callback) {
+    	auto_global->armed = auto_global->auto_global_callback(auto_global->name, auto_global->name_len TSRMLS_CC);
+	} else {
+		auto_global->armed = 0;
+	}
+	return 0;
+}
+/* }}} */
+
+ZEND_API void zend_activate_auto_globals(TSRMLS_D) /* {{{ */
+{
+	zend_hash_apply(CG(auto_globals), (apply_func_t) zend_auto_global_init TSRMLS_CC);
+}
+/* }}} */
+
 int zendlex(znode *zendlval TSRMLS_DC) /* {{{ */
 {
 	int retval;

Modified: php/php-src/trunk/Zend/zend_compile.h
===================================================================
--- php/php-src/trunk/Zend/zend_compile.h	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/Zend/zend_compile.h	2010-07-08 14:05:11 UTC (rev 301081)
@@ -651,13 +651,13 @@
 	char *name;
 	uint name_len;
 	zend_auto_global_callback auto_global_callback;
+	zend_bool jit;
 	zend_bool armed;
 } zend_auto_global;

-void zend_auto_global_dtor(zend_auto_global *auto_global);
-ZEND_API int zend_register_auto_global(const char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC);
+ZEND_API int zend_register_auto_global(const char *name, uint name_len, zend_bool jit, zend_auto_global_callback auto_global_callback TSRMLS_DC);
+ZEND_API void zend_activate_auto_globals(TSRMLS_D);
 ZEND_API zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC);
-ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC);
 ZEND_API size_t zend_dirname(char *path, size_t len);

 int zendlex(znode *zendlval TSRMLS_DC);

Modified: php/php-src/trunk/Zend/zend_execute_API.c
===================================================================
--- php/php-src/trunk/Zend/zend_execute_API.c	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/Zend/zend_execute_API.c	2010-07-08 14:05:11 UTC (rev 301081)
@@ -159,16 +159,6 @@
 	zend_vm_stack_push((void *) NULL TSRMLS_CC);

 	zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0);
-	{
-		zval *globals;
-
-		ALLOC_ZVAL(globals);
-		Z_SET_REFCOUNT_P(globals, 1);
-		Z_SET_ISREF_P(globals);
-		Z_TYPE_P(globals) = IS_ARRAY;
-		Z_ARRVAL_P(globals) = &EG(symbol_table);
-		zend_hash_update(&EG(symbol_table), "GLOBALS", sizeof("GLOBALS"), &globals, sizeof(zval *), NULL);
-	}
 	EG(active_symbol_table) = &EG(symbol_table);

 	zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC);

Modified: php/php-src/trunk/ext/session/session.c
===================================================================
--- php/php-src/trunk/ext/session/session.c	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/ext/session/session.c	2010-07-08 14:05:11 UTC (rev 301081)
@@ -1993,7 +1993,7 @@

 static PHP_MINIT_FUNCTION(session) /* {{{ */
 {
-	zend_register_auto_global("_SESSION", sizeof("_SESSION")-1, NULL TSRMLS_CC);
+	zend_register_auto_global("_SESSION", sizeof("_SESSION")-1, 0, NULL TSRMLS_CC);

 	PS(module_number) = module_number; /* if we really need this var we need to init it in zts mode as well! */


Modified: php/php-src/trunk/main/php_variables.c
===================================================================
--- php/php-src/trunk/main/php_variables.c	2010-07-08 13:59:53 UTC (rev 301080)
+++ php/php-src/trunk/main/php_variables.c	2010-07-08 14:05:11 UTC (rev 301081)
@@ -643,98 +643,106 @@
  */
 int php_hash_environment(TSRMLS_D)
 {
-	char *p;
-	unsigned char _gpc_flags[5] = {0, 0, 0, 0, 0};
-	struct auto_global_record {
-		char *name;
-		uint name_len;
-		zend_bool jit_initialization;
-	} auto_global_records[] = {
-		{ "_POST", sizeof("_POST"), 0 },
-		{ "_GET", sizeof("_GET"), 0 },
-		{ "_COOKIE", sizeof("_COOKIE"), 0 },
-		{ "_SERVER", sizeof("_SERVER"), 1 },
-		{ "_ENV", sizeof("_ENV"), 1 },
-		{ "_FILES", sizeof("_FILES"), 0 },
-	};
-	size_t num_track_vars = sizeof(auto_global_records)/sizeof(struct auto_global_record);
-	size_t i;
-
-	/* jit_initialization = 0; */
-	for (i=0; i<num_track_vars; i++) {
-		PG(http_globals)[i] = NULL;
+	memset(PG(http_globals), 0, sizeof(PG(http_globals)));
+	zend_activate_auto_globals(TSRMLS_C);
+	if (PG(register_argc_argv)) {
+		php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
 	}
+	return SUCCESS;
+}
+/* }}} */

-	for (p=PG(variables_order); p && *p; p++) {
-		switch(*p) {
-			case 'p':
-			case 'P':
-				if (!_gpc_flags[0] && !SG(headers_sent) && SG(request_info).request_method && !strcasecmp(SG(request_info).request_method, "POST")) {
-					sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC);	/* POST Data */
-					_gpc_flags[0] = 1;
-				}
-				break;
-			case 'c':
-			case 'C':
-				if (!_gpc_flags[1]) {
-					sapi_module.treat_data(PARSE_COOKIE, NULL, NULL TSRMLS_CC);	/* Cookie Data */
-					_gpc_flags[1] = 1;
-				}
-				break;
-			case 'g':
-			case 'G':
-				if (!_gpc_flags[2]) {
-					sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC);	/* GET Data */
-					_gpc_flags[2] = 1;
-				}
-				break;
-			case 'e':
-			case 'E':
-				if (!PG(auto_globals_jit) && !_gpc_flags[3]) {
-					zend_auto_global_disable_jit("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
-					php_auto_globals_create_env("_ENV", sizeof("_ENV")-1 TSRMLS_CC);
-					_gpc_flags[3] = 1;
-				}
-				break;
-			case 's':
-			case 'S':
-				if (!PG(auto_globals_jit) && !_gpc_flags[4]) {
-					zend_auto_global_disable_jit("_SERVER", sizeof("_SERVER")-1 TSRMLS_CC);
-					php_register_server_variables(TSRMLS_C);
-					_gpc_flags[4] = 1;
-				}
-				break;
+static zend_bool php_auto_globals_create_get(char *name, uint name_len TSRMLS_DC)
+{
+	zval *vars;
+
+	if (PG(variables_order) && (strchr(PG(variables_order),'G') || strchr(PG(variables_order),'g'))) {
+		sapi_module.treat_data(PARSE_GET, NULL, NULL TSRMLS_CC);
+		vars = PG(http_globals)[TRACK_VARS_GET];
+	} else {
+		ALLOC_ZVAL(vars);
+		array_init(vars);
+		INIT_PZVAL(vars);
+		if (PG(http_globals)[TRACK_VARS_GET]) {
+			zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_GET]);
 		}
+		PG(http_globals)[TRACK_VARS_GET] = vars;
 	}

-	/* argv/argc support */
-	if (PG(register_argc_argv)) {
-		php_build_argv(SG(request_info).query_string, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC);
+	zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
+	Z_ADDREF_P(vars);
+
+	return 0; /* don't rearm */
+}
+
+static zend_bool php_auto_globals_create_post(char *name, uint name_len TSRMLS_DC)
+{
+	zval *vars;
+
+	if (PG(variables_order) &&
+	    (strchr(PG(variables_order),'P') || strchr(PG(variables_order),'p')) &&
+		!SG(headers_sent) &&
+		SG(request_info).request_method &&
+		!strcasecmp(SG(request_info).request_method, "POST")) {
+		sapi_module.treat_data(PARSE_POST, NULL, NULL TSRMLS_CC);
+		vars = PG(http_globals)[TRACK_VARS_POST];
+	} else {
+		ALLOC_ZVAL(vars);
+		array_init(vars);
+		INIT_PZVAL(vars);
+		if (PG(http_globals)[TRACK_VARS_POST]) {
+			zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_POST]);
+		}
+		PG(http_globals)[TRACK_VARS_POST] = vars;
 	}

-	for (i=0; i<num_track_vars; i++) {
-		if (PG(auto_globals_jit) && auto_global_records[i].jit_initialization) {
-			continue;
+	zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
+	Z_ADDREF_P(vars);
+
+	return 0; /* don't rearm */
+}
+
+static zend_bool php_auto_globals_create_cookie(char *name, uint name_len TSRMLS_DC)
+{
+	zval *vars;
+
+	if (PG(variables_order) && (strchr(PG(variables_order),'C') || strchr(PG(variables_order),'c'))) {
+		sapi_module.treat_data(PARSE_COOKIE, NULL, NULL TSRMLS_CC);
+		vars = PG(http_globals)[TRACK_VARS_COOKIE];
+	} else {
+		ALLOC_ZVAL(vars);
+		array_init(vars);
+		INIT_PZVAL(vars);
+		if (PG(http_globals)[TRACK_VARS_COOKIE]) {
+			zval_ptr_dtor(&PG(http_globals)[TRACK_VARS_COOKIE]);
 		}
-		if (!PG(http_globals)[i]) {
-			ALLOC_ZVAL(PG(http_globals)[i]);
-			array_init(PG(http_globals)[i]);
-			INIT_PZVAL(PG(http_globals)[i]);
-		}
-
-		Z_ADDREF_P(PG(http_globals)[i]);
-		zend_hash_update(&EG(symbol_table), auto_global_records[i].name, auto_global_records[i].name_len, &PG(http_globals)[i], sizeof(zval *), NULL);
+		PG(http_globals)[TRACK_VARS_COOKIE] = vars;
 	}

-	/* Create _REQUEST */
-	if (!PG(auto_globals_jit)) {
-		zend_auto_global_disable_jit("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
-		php_auto_globals_create_request("_REQUEST", sizeof("_REQUEST")-1 TSRMLS_CC);
+	zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
+	Z_ADDREF_P(vars);
+
+	return 0; /* don't rearm */
+}
+
+static zend_bool php_auto_globals_create_files(char *name, uint name_len TSRMLS_DC)
+{
+	zval *vars;
+
+	if (PG(http_globals)[TRACK_VARS_FILES]) {
+		vars = PG(http_globals)[TRACK_VARS_FILES];
+	} else {
+		ALLOC_ZVAL(vars);
+		array_init(vars);
+		INIT_PZVAL(vars);
+		PG(http_globals)[TRACK_VARS_FILES] = vars;
 	}

-	return SUCCESS;
+	zend_hash_update(&EG(symbol_table), name, name_len + 1, &vars, sizeof(zval *), NULL);
+	Z_ADDREF_P(vars);
+
+	return 0; /* don't rearm */
 }
-/* }}} */

 static zend_bool php_auto_globals_create_server(char *name, uint name_len TSRMLS_DC)
 {
@@ -837,19 +845,19 @@
 		}
 	}

-	zend_hash_update(&EG(symbol_table), "_REQUEST", sizeof("_REQUEST"), &form_variables, sizeof(zval *), NULL);
+	zend_hash_update(&EG(symbol_table), name, name_len + 1, &form_variables, sizeof(zval *), NULL);
 	return 0;
 }

 void php_startup_auto_globals(TSRMLS_D)
 {
-	zend_register_auto_global("_GET", sizeof("_GET")-1, NULL TSRMLS_CC);
-	zend_register_auto_global("_POST", sizeof("_POST")-1, NULL TSRMLS_CC);
-	zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, NULL TSRMLS_CC);
-	zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, php_auto_globals_create_server TSRMLS_CC);
-	zend_register_auto_global("_ENV", sizeof("_ENV")-1, php_auto_globals_create_env TSRMLS_CC);
-	zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, php_auto_globals_create_request TSRMLS_CC);
-	zend_register_auto_global("_FILES", sizeof("_FILES")-1, NULL TSRMLS_CC);
+	zend_register_auto_global("_GET", sizeof("_GET")-1, 0, php_auto_globals_create_get TSRMLS_CC);
+	zend_register_auto_global("_POST", sizeof("_POST")-1, 0, php_auto_globals_create_post TSRMLS_CC);
+	zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, 0, php_auto_globals_create_cookie TSRMLS_CC);
+	zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, PG(auto_globals_jit), php_auto_globals_create_server TSRMLS_CC);
+	zend_register_auto_global("_ENV", sizeof("_ENV")-1, PG(auto_globals_jit), php_auto_globals_create_env TSRMLS_CC);
+	zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, PG(auto_globals_jit), php_auto_globals_create_request TSRMLS_CC);
+	zend_register_auto_global("_FILES", sizeof("_FILES")-1, 0, php_auto_globals_create_files TSRMLS_CC);
 }

 /*
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to