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