From: Dmitry Stogov Date: Mon, 21 Apr 2014 18:36:01 +0000 (+0400) Subject: Convert zval_get_string() into "fast path" macro and "slow path" function X-Git-Tag: POST_PHPNG_MERGE~412^2~81^2~7 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4ed452c1b5b81f99212594ec7f57475a16372d45;p=php Convert zval_get_string() into "fast path" macro and "slow path" function --- diff --git a/Zend/zend.c b/Zend/zend.c index 4d14c8a887..a722531283 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -317,7 +317,7 @@ ZEND_API int zend_print_zval(zval *expr, int indent TSRMLS_DC) /* {{{ */ ZEND_API int zend_print_zval_ex(zend_write_func_t write_func, zval *expr, int indent TSRMLS_DC) /* {{{ */ { - zend_string *str = zval_get_string(expr TSRMLS_CC); + zend_string *str = zval_get_string(expr); int len = str->len; if (len != 0) { diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 9f58ce8541..9d48dab9f2 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -90,7 +90,7 @@ ZEND_METHOD(Closure, bind) } else if (Z_TYPE_P(scope_arg) == IS_NULL) { ce = NULL; } else { - zend_string *class_name = zval_get_string(scope_arg TSRMLS_CC); + zend_string *class_name = zval_get_string(scope_arg); if ((class_name->len == sizeof("static") - 1) && (memcmp("static", class_name->val, sizeof("static") - 1) == 0)) { ce = closure->func.common.scope; diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 3b596bb6c0..0824d8d98f 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -893,8 +893,9 @@ ZEND_API double zval_get_double(zval *op TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC) /* {{{ */ +ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC) /* {{{ */ { +try_again: switch (Z_TYPE_P(op)) { case IS_NULL: return STR_EMPTY_ALLOC(); @@ -907,18 +908,18 @@ ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC) /* {{{ */ return STR_EMPTY_ALLOC(); } case IS_RESOURCE: { - char *str; - int len = zend_spprintf(&str, 0, "Resource id #%ld", Z_RES_HANDLE_P(op)); - zend_string *retval = STR_INIT(str, len, 0); - efree(str); - return retval; + char buf[sizeof("Resource id #") + MAX_LENGTH_OF_LONG]; + int len; + + len = snprintf(buf, sizeof(buf), "Resource id #%ld", Z_RES_HANDLE_P(op)); + return STR_INIT(buf, len, 0); } case IS_LONG: { - char *str; - int len = zend_spprintf(&str, 0, "%ld", Z_LVAL_P(op)); - zend_string *retval = STR_INIT(str, len, 0); - efree(str); - return retval; + char buf[MAX_LENGTH_OF_LONG + 1]; + int len; + + len = snprintf(buf, sizeof(buf), "%ld", Z_LVAL_P(op)); + return STR_INIT(buf, len, 0); } case IS_DOUBLE: { char *str; @@ -942,7 +943,7 @@ ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC) /* {{{ */ } else if (Z_OBJ_HT_P(op)->get) { zval *z = Z_OBJ_HT_P(op)->get(op, &tmp TSRMLS_CC); if (Z_TYPE_P(z) != IS_OBJECT) { - zend_string *str = zval_get_string(z TSRMLS_CC); + zend_string *str = zval_get_string(z); zval_ptr_dtor(z); return str; } @@ -952,7 +953,8 @@ ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC) /* {{{ */ return STR_EMPTY_ALLOC(); } case IS_REFERENCE: - return zval_get_string(Z_REFVAL_P(op)); + op = Z_REFVAL_P(op); + goto try_again; default: //??? original code returns bool(0) return STR_EMPTY_ALLOC(); @@ -1557,8 +1559,8 @@ ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{ ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */ { - zend_string *str1 = zval_get_string(op1 TSRMLS_CC), - *str2 = zval_get_string(op2 TSRMLS_CC); + zend_string *str1 = zval_get_string(op1); + zend_string *str2 = zval_get_string(op2); if (case_insensitive) { ZVAL_LONG(result, zend_binary_strcasecmp_l(str1->val, str1->len, str2->val, str1->len)); @@ -1587,8 +1589,8 @@ ZEND_API int string_case_compare_function(zval *result, zval *op1, zval *op2 TSR #if HAVE_STRCOLL ZEND_API int string_locale_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */ { - zend_string *str1 = zval_get_string(op1 TSRMLS_CC), - *str2 = zval_get_string(op2 TSRMLS_CC); + zend_string *str1 = zval_get_string(op1); + zend_string *str2 = zval_get_string(op2); ZVAL_LONG(result, strcoll(str1->val, str2->val)); diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 9df4a68933..f026ae1dbc 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -339,7 +339,10 @@ ZEND_API void multi_convert_to_string_ex(int argc, ...); ZEND_API long zval_get_long(zval *op TSRMLS_DC); ZEND_API double zval_get_double(zval *op TSRMLS_DC); -ZEND_API zend_string *zval_get_string(zval *op TSRMLS_DC); +ZEND_API zend_string *_zval_get_string_func(zval *op TSRMLS_DC); + +#define zval_get_string(op) ((Z_TYPE_P(op) == IS_STRING) ? \ + STR_COPY(Z_STR_P(op)) : _zval_get_string_func((op) TSRMLS_CC)) ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2); ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2); diff --git a/ext/dom/attr.c b/ext/dom/attr.c index 63be8762d1..b0489ef122 100644 --- a/ext/dom/attr.c +++ b/ext/dom/attr.c @@ -171,7 +171,7 @@ int dom_attr_value_write(dom_object *obj, zval *newval TSRMLS_DC) node_list_unlink(attrp->children TSRMLS_CC); } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); xmlNodeSetContentLen((xmlNodePtr) attrp, str->val, str->len + 1); diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c index b1b5d76d26..2ef6352f20 100644 --- a/ext/dom/characterdata.c +++ b/ext/dom/characterdata.c @@ -106,7 +106,7 @@ int dom_characterdata_data_write(dom_object *obj, zval *newval TSRMLS_DC) return FAILURE; } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); xmlNodeSetContentLen(nodep, str->val, str->len + 1); diff --git a/ext/dom/document.c b/ext/dom/document.c index 35d8348a2d..b1c1dc2737 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -338,7 +338,7 @@ int dom_document_encoding_write(dom_object *obj, zval *newval TSRMLS_DC) return FAILURE; } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); handler = xmlFindCharEncodingHandler(Z_STRVAL_P(newval)); @@ -436,7 +436,7 @@ int dom_document_version_write(dom_object *obj, zval *newval TSRMLS_DC) xmlFree((xmlChar *) docp->version ); } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); docp->version = xmlStrdup((const xmlChar *) str->val); @@ -664,7 +664,7 @@ int dom_document_document_uri_write(dom_object *obj, zval *newval TSRMLS_DC) xmlFree((xmlChar *) docp->URL); } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); docp->URL = xmlStrdup((const xmlChar *) str->val); diff --git a/ext/dom/node.c b/ext/dom/node.c index 57669b5069..25c8daee6f 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -343,7 +343,7 @@ int dom_node_node_value_write(dom_object *obj, zval *newval TSRMLS_DC) case XML_CDATA_SECTION_NODE: case XML_PI_NODE: { - zend_string *str = zval_get_string(newval TSRMLS_CC); + zend_string *str = zval_get_string(newval); xmlNodeSetContentLen(nodep, str->val, str->len + 1); STR_RELEASE(str); break; @@ -720,7 +720,7 @@ int dom_node_prefix_write(dom_object *obj, zval *newval TSRMLS_DC) nsnode = xmlDocGetRootElement(nodep->doc); } } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); prefix = str->val; if (nsnode && nodep->ns != NULL && !xmlStrEqual(nodep->ns->prefix, (xmlChar *)prefix)) { strURI = (char *) nodep->ns->href; diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 99d99e236f..9f971ee0ac 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -313,7 +313,7 @@ static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_r static zval *dom_get_property_ptr_ptr(zval *object, zval *member, int type, zend_uint cache_slot TSRMLS_DC) /* {{{ */ { dom_object *obj = Z_DOMOBJ_P(object); - zend_string *member_str = zval_get_string(member TSRMLS_CC); + zend_string *member_str = zval_get_string(member); zval *retval = NULL; if (!obj->prop_handler || !zend_hash_exists(obj->prop_handler, member_str)) { @@ -330,7 +330,7 @@ static zval *dom_get_property_ptr_ptr(zval *object, zval *member, int type, zend zval *dom_read_property(zval *object, zval *member, int type, zend_uint cache_slot, zval *rv TSRMLS_DC) { dom_object *obj = Z_DOMOBJ_P(object); - zend_string *member_str = zval_get_string(member TSRMLS_CC); + zend_string *member_str = zval_get_string(member); zval *retval; dom_prop_handler *hnd = NULL; @@ -361,7 +361,7 @@ zval *dom_read_property(zval *object, zval *member, int type, zend_uint cache_sl void dom_write_property(zval *object, zval *member, zval *value, zend_uint cache_slot TSRMLS_DC) { dom_object *obj = Z_DOMOBJ_P(object); - zend_string *member_str = zval_get_string(member TSRMLS_CC); + zend_string *member_str = zval_get_string(member); dom_prop_handler *hnd = NULL; if (obj->prop_handler != NULL) { @@ -382,7 +382,7 @@ void dom_write_property(zval *object, zval *member, zval *value, zend_uint cache static int dom_property_exists(zval *object, zval *member, int check_empty, zend_uint cache_slot TSRMLS_DC) { dom_object *obj = Z_DOMOBJ_P(object); - zend_string *member_str = zval_get_string(member TSRMLS_CC); + zend_string *member_str = zval_get_string(member); dom_prop_handler *hnd = NULL; int retval = 0; diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c index aef9e92b64..36b159cc6e 100644 --- a/ext/dom/processinginstruction.c +++ b/ext/dom/processinginstruction.c @@ -145,7 +145,7 @@ int dom_processinginstruction_data_write(dom_object *obj, zval *newval TSRMLS_DC return FAILURE; } - str = zval_get_string(newval TSRMLS_CC); + str = zval_get_string(newval); xmlNodeSetContentLen(nodep, str->val, str->len + 1); diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 08bb8603a5..3290a3a5e7 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -522,7 +522,7 @@ PHP_FUNCTION(dom_xpath_register_php_functions) intern = Z_XPATHOBJ_P(id); zend_hash_internal_pointer_reset(Z_ARRVAL_P(array_value)); while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(array_value)))) { - zend_string *str = zval_get_string(entry TSRMLS_CC); + zend_string *str = zval_get_string(entry); ZVAL_LONG(&new_string,1); zend_hash_update(intern->registered_phpfunctions, str, &new_string); zend_hash_move_forward(Z_ARRVAL_P(array_value)); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index b78311868a..4940457333 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -656,7 +656,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in static void _const_string(string *str, char *name, zval *value, char *indent TSRMLS_DC) { char *type = zend_zval_type_name(value); - zend_string *value_str = zval_get_string(value TSRMLS_CC); + zend_string *value_str = zval_get_string(value); string_printf(str, "%s Constant [ %s %s ] { %s }\n", indent, type, name, value_str->val); diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index b08b06fac5..2942daaad3 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -559,7 +559,7 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) switch (format[inpos]) { case 's': { - zend_string *str = zval_get_string(&tmp TSRMLS_CC); + zend_string *str = zval_get_string(&tmp); php_sprintf_appendstring(&result, &outpos, str->val, width, precision, padding, diff --git a/ext/standard/string.c b/ext/standard/string.c index fe6d30f18a..a960cd1a5c 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -4956,8 +4956,8 @@ static void php_strnatcmp(INTERNAL_FUNCTION_PARAMETERS, int fold_case) PHPAPI int string_natural_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC) /* {{{ */ { - zend_string *str1 = zval_get_string(op1 TSRMLS_CC), - *str2 = zval_get_string(op2 TSRMLS_CC); + zend_string *str1 = zval_get_string(op1); + zend_string *str2 = zval_get_string(op2); ZVAL_LONG(result, strnatcmp_ex(str1->val, str1->len, str2->val, str2->len, case_insensitive));