From: Dmitry Stogov Date: Tue, 14 Nov 2017 21:53:51 +0000 (+0300) Subject: Embeded zend_list into st_mysqlnd_error_info, to avoid extra allocation/deallocation. X-Git-Tag: php-7.3.0alpha1~1029 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=69462bdf4c9dcfef7056be5e075a7545724004b3;p=php Embeded zend_list into st_mysqlnd_error_info, to avoid extra allocation/deallocation. --- diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 2c9915111d..67ae750e8b 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -1870,6 +1870,9 @@ PHP_FUNCTION(mysqli_prepare) memcpy(sqlstate, mysql->mysql->net.sqlstate, SQLSTATE_LENGTH+1); #else MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info; + mysql->mysql->data->error_info->error_list.head = NULL; + mysql->mysql->data->error_info->error_list.tail = NULL; + mysql->mysql->data->error_info->error_list.count = 0; #endif mysqli_stmt_close(stmt->stmt, FALSE); stmt->stmt = NULL; @@ -1880,6 +1883,7 @@ PHP_FUNCTION(mysqli_prepare) memcpy(mysql->mysql->net.last_error, last_error, MYSQL_ERRMSG_SIZE); memcpy(mysql->mysql->net.sqlstate, sqlstate, SQLSTATE_LENGTH+1); #else + zend_llist_clean(&mysql->mysql->data->error_info->error_list); *mysql->mysql->data->error_info = error_info; #endif } diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 9384b9355a..1ec85cf88f 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -422,13 +422,13 @@ PHP_FUNCTION(mysqli_error_list) } MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID); #if defined(MYSQLI_USE_MYSQLND) - if (mysql->mysql->data->error_info->error_list) { + if (1) { MYSQLND_ERROR_LIST_ELEMENT * message; zend_llist_position pos; array_init(return_value); - for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos); + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&mysql->mysql->data->error_info->error_list, &pos); message; - message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(&mysql->mysql->data->error_info->error_list, &pos)) { zval single_error; array_init(&single_error); @@ -468,13 +468,13 @@ PHP_FUNCTION(mysqli_stmt_error_list) } MYSQLI_FETCH_RESOURCE_STMT(stmt, mysql_stmt, MYSQLI_STATUS_INITIALIZED); #if defined(MYSQLI_USE_MYSQLND) - if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info->error_list) { + if (stmt->stmt && stmt->stmt->data && stmt->stmt->data->error_info) { MYSQLND_ERROR_LIST_ELEMENT * message; zend_llist_position pos; array_init(return_value); - for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos); + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&stmt->stmt->data->error_info->error_list, &pos); message; - message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(&stmt->stmt->data->error_info->error_list, &pos)) { zval single_error; array_init(&single_error); @@ -536,6 +536,9 @@ PHP_FUNCTION(mysqli_multi_query) s_errno = mysql_errno(mysql->mysql); #else MYSQLND_ERROR_INFO error_info = *mysql->mysql->data->error_info; + mysql->mysql->data->error_info->error_list.head = NULL; + mysql->mysql->data->error_info->error_list.tail = NULL; + mysql->mysql->data->error_info->error_list.count = 0; #endif MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql); MYSQLI_DISABLE_MQ; @@ -546,6 +549,7 @@ PHP_FUNCTION(mysqli_multi_query) strcpy(mysql->mysql->net.sqlstate, s_sqlstate); mysql->mysql->net.last_errno = s_errno; #else + zend_llist_clean(&mysql->mysql->data->error_info->error_list); *mysql->mysql->data->error_info = error_info; #endif RETURN_FALSE; diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index 0b3858d1c3..c4aeadf082 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -187,12 +187,12 @@ static zval *link_error_list_read(mysqli_object *obj, zval *retval) if (mysql) { array_init(retval); #if defined(MYSQLI_USE_MYSQLND) - if (mysql->mysql->data->error_info->error_list) { + if (1) { MYSQLND_ERROR_LIST_ELEMENT * message; zend_llist_position pos; - for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(mysql->mysql->data->error_info->error_list, &pos); + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&mysql->mysql->data->error_info->error_list, &pos); message; - message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(mysql->mysql->data->error_info->error_list, &pos)) + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(&mysql->mysql->data->error_info->error_list, &pos)) { zval single_error; array_init(&single_error); @@ -379,12 +379,12 @@ static zval *stmt_error_list_read(mysqli_object *obj, zval *retval) if (stmt && stmt->stmt) { array_init(retval); #if defined(MYSQLI_USE_MYSQLND) - if (stmt->stmt->data && stmt->stmt->data->error_info->error_list) { + if (stmt->stmt->data && stmt->stmt->data->error_info) { MYSQLND_ERROR_LIST_ELEMENT * message; zend_llist_position pos; - for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(stmt->stmt->data->error_info->error_list, &pos); + for (message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_first_ex(&stmt->stmt->data->error_info->error_list, &pos); message; - message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(stmt->stmt->data->error_info->error_list, &pos)) + message = (MYSQLND_ERROR_LIST_ELEMENT *) zend_llist_get_next_ex(&stmt->stmt->data->error_info->error_list, &pos)) { zval single_error; array_init(&single_error); diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt index b5ba9a5a05..9999d84395 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt @@ -207,8 +207,8 @@ if (!$IS_MYSQLND) // mysqlnd only option // m - trace memory allocations $trace = try_control_string($link, 't:O,' . $trace_file . ':m', $trace_file, 120); - if (!preg_match("@^[|\s]*>\_mysqlnd_pefree@ismU", $trace, $matches) && - !preg_match("@^[|\s]*>\_mysqlnd_pemalloc@ismU", $trace, $matches)) { + if (!preg_match("@^[|\s]*>\_mysqlnd_p?efree@ismU", $trace, $matches) && + !preg_match("@^[|\s]*>\_mysqlnd_p?emalloc@ismU", $trace, $matches)) { printf("[125] Memory dump does neither contain _mysqlnd_pefree nor _mysqlnd_pemalloc calls - check manually.\n"); var_dump($trace); } diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt index 2886694440..603bb9bc32 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -90,9 +90,11 @@ if (!$IS_MYSQLND) if (isset($functions_trace[$name])) $found++; - if ($found < (count($memory_funcs) - 3)) + if ($found < 2) { printf("[016] Only %d memory functions have been found, expecting at least %d.\n", - $found, count($memory_funcs) - 3); + $found, 2); + var_dump($trace); + } $trace = try_control_string($link, 't:O,' . $trace_file, $trace_file, 20); if (!strstr($trace, 'SELECT * FROM test') && !strstr($trace, 'mysql_real_query')) @@ -112,9 +114,11 @@ if (!$IS_MYSQLND) if (isset($functions_trace[$name])) $found++; - if ($found > 2) + if ($found > 2) { printf("[026] More than %d memory functions have been recorded, that's strange.\n", $found); + var_dump($trace); + } mysqli_close($link); @unlink($trace_file); diff --git a/ext/mysqlnd/mysqlnd_connection.c b/ext/mysqlnd/mysqlnd_connection.c index 960b9f10b6..75a7e02926 100644 --- a/ext/mysqlnd/mysqlnd_connection.c +++ b/ext/mysqlnd/mysqlnd_connection.c @@ -103,9 +103,7 @@ MYSQLND_METHOD(mysqlnd_error_info, reset)(MYSQLND_ERROR_INFO * const info) info->error_no = 0; info->error[0] = '\0'; memset(&info->sqlstate, 0, sizeof(info->sqlstate)); - if (info->error_list) { - zend_llist_clean(info->error_list); - } + zend_llist_clean(&info->error_list); DBG_VOID_RETURN; } @@ -121,19 +119,18 @@ MYSQLND_METHOD(mysqlnd_error_info, set_client_error)(MYSQLND_ERROR_INFO * const { DBG_ENTER("mysqlnd_error_info::set_client_error"); if (err_no) { + MYSQLND_ERROR_LIST_ELEMENT error_for_the_list = {0}; + info->error_no = err_no; strlcpy(info->sqlstate, sqlstate, sizeof(info->sqlstate)); strlcpy(info->error, error, sizeof(info->error)); - if (info->error_list) { - MYSQLND_ERROR_LIST_ELEMENT error_for_the_list = {0}; - - error_for_the_list.error_no = err_no; - strlcpy(error_for_the_list.sqlstate, sqlstate, sizeof(error_for_the_list.sqlstate)); - error_for_the_list.error = mnd_pestrdup(error, TRUE); - if (error_for_the_list.error) { - DBG_INF_FMT("adding error [%s] to the list", error_for_the_list.error); - zend_llist_add_element(info->error_list, &error_for_the_list); - } + + error_for_the_list.error_no = err_no; + strlcpy(error_for_the_list.sqlstate, sqlstate, sizeof(error_for_the_list.sqlstate)); + error_for_the_list.error = mnd_pestrdup(error, TRUE); + if (error_for_the_list.error) { + DBG_INF_FMT("adding error [%s] to the list", error_for_the_list.error); + zend_llist_add_element(&info->error_list, &error_for_the_list); } } else { info->m->reset(info); @@ -158,12 +155,9 @@ mysqlnd_error_info_init(MYSQLND_ERROR_INFO * const info, const zend_bool persist info->m = mysqlnd_error_info_get_methods(); info->m->reset(info); - info->error_list = mnd_pecalloc(1, sizeof(zend_llist), persistent); - if (info->error_list) { - zend_llist_init(info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, persistent); - } + zend_llist_init(&info->error_list, sizeof(MYSQLND_ERROR_LIST_ELEMENT), (llist_dtor_func_t) mysqlnd_error_list_pdtor, persistent); info->persistent = persistent; - DBG_RETURN(info->error_list? PASS:FAIL); + DBG_RETURN(PASS); } /* }}} */ @@ -174,11 +168,6 @@ mysqlnd_error_info_free_contents(MYSQLND_ERROR_INFO * const info) { DBG_ENTER("mysqlnd_error_info_free_contents"); info->m->reset(info); - if (info->error_list) { - mnd_pefree(info->error_list, info->persistent); - info->error_list = NULL; - } - DBG_VOID_RETURN; } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index b41f125f6a..a34e434b89 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -2092,11 +2092,7 @@ MYSQLND_METHOD(mysqlnd_stmt, free_stmt_result)(MYSQLND_STMT * const s) stmt->result->m.free_result_internal(stmt->result); stmt->result = NULL; } - if (stmt->error_info->error_list) { - zend_llist_clean(stmt->error_info->error_list); - mnd_efree(stmt->error_info->error_list); - stmt->error_info->error_list = NULL; - } + zend_llist_clean(&stmt->error_info->error_list); DBG_VOID_RETURN; } diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index 60ef369999..86e7d787d5 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -152,7 +152,7 @@ struct st_mysqlnd_error_info char error[MYSQLND_ERRMSG_SIZE+1]; char sqlstate[MYSQLND_SQLSTATE_LENGTH + 1]; unsigned int error_no; - zend_llist * error_list; + zend_llist error_list; zend_bool persistent; MYSQLND_CLASS_METHODS_TYPE(mysqlnd_error_info) *m;