dmitry                                   Tue, 27 Apr 2010 12:09:13 +0000

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

Log:
- Reimplemented ZEND_INIT_FCALL_BY_NAME and ZEND_INIT_NS_FCALL_BY_NAME to use 
literals instead of additional operands
- Optimized access to global constants

Changed paths:
    U   php/php-src/trunk/Zend/zend_compile.c
    U   php/php-src/trunk/Zend/zend_constants.c
    U   php/php-src/trunk/Zend/zend_constants.h
    U   php/php-src/trunk/Zend/zend_vm_def.h
    U   php/php-src/trunk/Zend/zend_vm_execute.h

Modified: php/php-src/trunk/Zend/zend_compile.c
===================================================================
--- php/php-src/trunk/Zend/zend_compile.c	2010-04-27 11:02:51 UTC (rev 298650)
+++ php/php-src/trunk/Zend/zend_compile.c	2010-04-27 12:09:13 UTC (rev 298651)
@@ -388,7 +388,38 @@
 }
 /* }}} */

+int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
+{
+	int ret;
+	char *lc_name, *ns_separator;
+	int lc_len;
+	zval c;
+	int lc_literal;

+	if (op_array->last_literal > 0 &&
+	    &op_array->literals[op_array->last_literal - 1].constant == zv) {
+		/* we already have function name as last literal (do nothing) */
+		ret = op_array->last_literal - 1;
+	} else {
+		ret = zend_add_literal(op_array, zv);
+	}
+
+	lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
+	ZVAL_STRINGL(&c, lc_name, Z_STRLEN_P(zv), 0);
+	lc_literal = zend_add_literal(CG(active_op_array), &c);
+	CALCULATE_LITERAL_HASH(lc_literal);
+
+	ns_separator = zend_memrchr(Z_STRVAL_P(zv), '\\', Z_STRLEN_P(zv)) + 1;
+	lc_len = Z_STRLEN_P(zv) - (ns_separator - Z_STRVAL_P(zv));
+	lc_name = zend_str_tolower_dup(ns_separator, lc_len);
+	ZVAL_STRINGL(&c, lc_name, lc_len, 0);
+	lc_literal = zend_add_literal(CG(active_op_array), &c);
+	CALCULATE_LITERAL_HASH(lc_literal);
+
+	return ret;
+}
+/* }}} */
+
 int zend_add_class_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC) /* {{{ */
 {
 	int ret;
@@ -1853,13 +1884,13 @@
 		zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 		opline->opcode = ZEND_INIT_FCALL_BY_NAME;
 		SET_NODE(opline->op2, left_bracket);
-		if (opline->op2_type == IS_CONST) {
-			opline->op1_type = IS_CONST;
-			LITERAL_STRINGL(opline->op1, zend_str_tolower_dup(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))), Z_STRLEN(CONSTANT(opline->op2.constant)), 0);
-			CALCULATE_LITERAL_HASH(opline->op1.constant);
-		} else {
-			SET_UNUSED(opline->op1);
-		}
+		SET_UNUSED(opline->op1);
+		if (left_bracket->op_type == IS_CONST) {
+			opline->op2_type = IS_CONST;
+			opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &left_bracket->u.constant TSRMLS_CC);
+ 		} else {
+			SET_NODE(opline->op2, left_bracket);
+ 		}
 	}

 	zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
@@ -1883,7 +1914,7 @@
 void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */
 {
 	unsigned char *ptr = NULL;
-	zend_op *opline, *opline2;
+	zend_op *opline;

 	opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 	if (ns_call) {
@@ -1892,34 +1923,18 @@
 		/* In run-time PHP will check for function with full name and
 		   internal function with short name */
 		opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
-		SET_NODE(opline->op2, function_name);
-		opline->op1_type = IS_CONST;
-		LITERAL_STRINGL(opline->op1, zend_str_tolower_dup(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))), Z_STRLEN(CONSTANT(opline->op2.constant)), 0);
-		CALCULATE_LITERAL_HASH(opline->op1.constant);
-		slash = zend_memrchr(Z_STRVAL(CONSTANT(opline->op1.constant)), '\\', Z_STRLEN(CONSTANT(opline->op1.constant)));
-		prefix_len = slash-Z_STRVAL(CONSTANT(opline->op1.constant))+1;
-		name_len = Z_STRLEN(CONSTANT(opline->op1.constant))-prefix_len;
-		opline2 = get_next_op(CG(active_op_array) TSRMLS_CC);
-		opline2->opcode = ZEND_OP_DATA;
-		SET_UNUSED(opline2->op1);
-		if(!slash) {
-			zend_error(E_CORE_ERROR, "Namespaced name %s should contain slash", Z_STRVAL(CONSTANT(opline->op1.constant)));
-		}
-		/* this is the length of namespace prefix */
-		opline2->op1.num = prefix_len;
-		/* this is the hash of the non-prefixed part, lowercased */
-		opline2->extended_value = zend_hash_func(slash+1, name_len+1);
-		SET_UNUSED(opline2->op2);
+		SET_UNUSED(opline->op1);
+		opline->op2_type = IS_CONST;
+		opline->op2.constant = zend_add_ns_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
 	} else {
 		opline->opcode = ZEND_INIT_FCALL_BY_NAME;
-		SET_NODE(opline->op2, function_name);
-		if (opline->op2_type == IS_CONST) {
-			opline->op1_type = IS_CONST;
-			LITERAL_STRINGL(opline->op1, zend_str_tolower_dup(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))), Z_STRLEN(CONSTANT(opline->op2.constant)), 0);
-			CALCULATE_LITERAL_HASH(opline->op1.constant);
-		} else {
-			SET_UNUSED(opline->op1);
-		}
+		SET_UNUSED(opline->op1);
+		if (function_name->op_type == IS_CONST) {
+			opline->op2_type = IS_CONST;
+			opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
+ 		} else {
+			SET_NODE(opline->op2, function_name);
+ 		}
 	}

 	zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));

Modified: php/php-src/trunk/Zend/zend_constants.c
===================================================================
--- php/php-src/trunk/Zend/zend_constants.c	2010-04-27 11:02:51 UTC (rev 298650)
+++ php/php-src/trunk/Zend/zend_constants.c	2010-04-27 12:09:13 UTC (rev 298651)
@@ -413,7 +413,7 @@
 	return zend_get_constant(name, name_len, result TSRMLS_CC);
 }

-int zend_quick_get_constant(const zend_literal *key, zval *result, ulong flags TSRMLS_DC)
+zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC)
 {
 	zend_constant *c;

@@ -430,22 +430,19 @@

 						key--;
 						if (!zend_get_halt_offset_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
-							return 0;
+							return NULL;
 						}
 					}
 				}
 			} else {
 				key--;
 				if (!zend_get_halt_offset_constant(Z_STRVAL(key->constant), Z_STRLEN(key->constant), &c TSRMLS_CC)) {
-					return 0;
+					return NULL;
 				}
 			}
 		}
 	}
-
-	INIT_PZVAL_COPY(result, &c->value);
-	zval_copy_ctor(result);
-	return 1;
+	return c;
 }

 ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC)

Modified: php/php-src/trunk/Zend/zend_constants.h
===================================================================
--- php/php-src/trunk/Zend/zend_constants.h	2010-04-27 11:02:51 UTC (rev 298650)
+++ php/php-src/trunk/Zend/zend_constants.h	2010-04-27 12:09:13 UTC (rev 298651)
@@ -69,7 +69,7 @@
 ZEND_API int zend_register_constant(zend_constant *c TSRMLS_DC);
 void zend_copy_constants(HashTable *target, HashTable *sourc);
 void copy_zend_constant(zend_constant *c);
-int zend_quick_get_constant(const zend_literal *key, zval *result, ulong flags TSRMLS_DC);
+zend_constant *zend_quick_get_constant(const zend_literal *key, ulong flags TSRMLS_DC);
 END_EXTERN_C()

 #define ZEND_CONSTANT_DTOR (void (*)(void *)) free_zend_constant

Modified: php/php-src/trunk/Zend/zend_vm_def.h
===================================================================
--- php/php-src/trunk/Zend/zend_vm_def.h	2010-04-27 11:02:51 UTC (rev 298650)
+++ php/php-src/trunk/Zend/zend_vm_def.h	2010-04-27 12:09:13 UTC (rev 298651)
@@ -2320,7 +2320,7 @@
 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

 	if (OP2_TYPE == IS_CONST) {
-		function_name = opline->op1.zv;
+		function_name = (zval*)(opline->op2.literal+1);
 		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@@ -2373,19 +2373,20 @@
 ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
 {
 	USE_OPLINE
-
-	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
-
-	if (zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv)+1, Z_HASH_P(opline->op1.zv), (void **) &EX(fbc))==FAILURE) {
-		char *short_name = Z_STRVAL_P(opline->op1.zv) + (opline+1)->op1.num;
-		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), short_name, Z_STRLEN_P(opline->op1.zv) - (opline+1)->op1.num+1, (opline+1)->extended_value, (void **) &EX(fbc))==FAILURE)) {
+	zend_literal *func_name;
+
+ 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+
+	func_name = opline->op2.literal + 1;
+	if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
+		func_name++;
+		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		}
 	}

 	EX(object) = NULL;
-	ZEND_VM_INC_OPCODE();
 	ZEND_VM_NEXT_OPCODE();
 }

@@ -3335,8 +3336,10 @@

 	SAVE_OPLINE();
 	if (OP1_TYPE == IS_UNUSED) {
-		/* namespaced constant */
-		if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) {
+		zend_constant *c;
+		zval *retval;
+
+		if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
 			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
 				char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
 				if(!actual) {
@@ -3347,10 +3350,15 @@
 				/* non-qualified constant - allow text substitution */
 				zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
 				ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
+				CHECK_EXCEPTION();
+				ZEND_VM_NEXT_OPCODE();
 			} else {
 				zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
 			}
 		}
+		retval = &EX_T(opline->result.var).tmp_var;
+		INIT_PZVAL_COPY(retval, &c->value);
+		zval_copy_ctor(retval);
 		CHECK_EXCEPTION();
 		ZEND_VM_NEXT_OPCODE();
 	} else {

Modified: php/php-src/trunk/Zend/zend_vm_execute.h
===================================================================
--- php/php-src/trunk/Zend/zend_vm_execute.h	2010-04-27 11:02:51 UTC (rev 298650)
+++ php/php-src/trunk/Zend/zend_vm_execute.h	2010-04-27 12:09:13 UTC (rev 298651)
@@ -871,7 +871,7 @@
 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

 	if (IS_CONST == IS_CONST) {
-		function_name = opline->op1.zv;
+		function_name = (zval*)(opline->op2.literal+1);
 		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@@ -924,19 +924,20 @@
 static int ZEND_FASTCALL  ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
 	USE_OPLINE
+	zend_literal *func_name;

-	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

-	if (zend_hash_quick_find(EG(function_table), Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv)+1, Z_HASH_P(opline->op1.zv), (void **) &EX(fbc))==FAILURE) {
-		char *short_name = Z_STRVAL_P(opline->op1.zv) + (opline+1)->op1.num;
-		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), short_name, Z_STRLEN_P(opline->op1.zv) - (opline+1)->op1.num+1, (opline+1)->extended_value, (void **) &EX(fbc))==FAILURE)) {
+	func_name = opline->op2.literal + 1;
+	if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
+		func_name++;
+		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
 		}
 	}

 	EX(object) = NULL;
-	ZEND_VM_INC_OPCODE();
 	ZEND_VM_NEXT_OPCODE();
 }

@@ -1084,7 +1085,7 @@
 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

 	if (IS_TMP_VAR == IS_CONST) {
-		function_name = opline->op1.zv;
+		function_name = (zval*)(opline->op2.literal+1);
 		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@@ -1197,7 +1198,7 @@
 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

 	if (IS_VAR == IS_CONST) {
-		function_name = opline->op1.zv;
+		function_name = (zval*)(opline->op2.literal+1);
 		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@@ -1338,7 +1339,7 @@
 	zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));

 	if (IS_CV == IS_CONST) {
-		function_name = opline->op1.zv;
+		function_name = (zval*)(opline->op2.literal+1);
 		if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
 			SAVE_OPLINE();
 			zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
@@ -3009,8 +3010,10 @@

 	SAVE_OPLINE();
 	if (IS_CONST == IS_UNUSED) {
-		/* namespaced constant */
-		if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) {
+		zend_constant *c;
+		zval *retval;
+
+		if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
 			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
 				char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
 				if(!actual) {
@@ -3021,10 +3024,15 @@
 				/* non-qualified constant - allow text substitution */
 				zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
 				ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
+				CHECK_EXCEPTION();
+				ZEND_VM_NEXT_OPCODE();
 			} else {
 				zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
 			}
 		}
+		retval = &EX_T(opline->result.var).tmp_var;
+		INIT_PZVAL_COPY(retval, &c->value);
+		zval_copy_ctor(retval);
 		CHECK_EXCEPTION();
 		ZEND_VM_NEXT_OPCODE();
 	} else {
@@ -11530,8 +11538,10 @@

 	SAVE_OPLINE();
 	if (IS_VAR == IS_UNUSED) {
-		/* namespaced constant */
-		if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) {
+		zend_constant *c;
+		zval *retval;
+
+		if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
 			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
 				char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
 				if(!actual) {
@@ -11542,10 +11552,15 @@
 				/* non-qualified constant - allow text substitution */
 				zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
 				ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
+				CHECK_EXCEPTION();
+				ZEND_VM_NEXT_OPCODE();
 			} else {
 				zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
 			}
 		}
+		retval = &EX_T(opline->result.var).tmp_var;
+		INIT_PZVAL_COPY(retval, &c->value);
+		zval_copy_ctor(retval);
 		CHECK_EXCEPTION();
 		ZEND_VM_NEXT_OPCODE();
 	} else {
@@ -19416,8 +19431,10 @@

 	SAVE_OPLINE();
 	if (IS_UNUSED == IS_UNUSED) {
-		/* namespaced constant */
-		if (!zend_quick_get_constant(opline->op2.literal + 1, &EX_T(opline->result.var).tmp_var, opline->extended_value TSRMLS_CC)) {
+		zend_constant *c;
+		zval *retval;
+
+		if ((c = zend_quick_get_constant(opline->op2.literal + 1, opline->extended_value TSRMLS_CC)) == NULL) {
 			if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
 				char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
 				if(!actual) {
@@ -19428,10 +19445,15 @@
 				/* non-qualified constant - allow text substitution */
 				zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual);
 				ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, actual, Z_STRLEN_P(opline->op2.zv)-(actual - Z_STRVAL_P(opline->op2.zv)), 1);
+				CHECK_EXCEPTION();
+				ZEND_VM_NEXT_OPCODE();
 			} else {
 				zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
 			}
 		}
+		retval = &EX_T(opline->result.var).tmp_var;
+		INIT_PZVAL_COPY(retval, &c->value);
+		zval_copy_ctor(retval);
 		CHECK_EXCEPTION();
 		ZEND_VM_NEXT_OPCODE();
 	} else {
-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to