Reduce impact of stream file path check in filestat

Fix for #76857 introduced slight perf regression so this is an attempt
to fix it. The idea is to re-use stream path check from ZendAccelerator
that should be quicker than strstr.

Signed-off-by: Jakub Zelenka <bukka@php.net>
This commit is contained in:
Jakub Zelenka 2023-09-23 17:33:40 +01:00
parent 4400eb270f
commit 5e8c992c78
No known key found for this signature in database
GPG Key ID: 1C0779DC5C0A9DE4
3 changed files with 20 additions and 19 deletions

View File

@ -187,19 +187,6 @@ static time_t zend_accel_get_time(void)
# define zend_accel_get_time() time(NULL)
#endif
static inline bool is_stream_path(const char *filename)
{
const char *p;
for (p = filename;
(*p >= 'a' && *p <= 'z') ||
(*p >= 'A' && *p <= 'Z') ||
(*p >= '0' && *p <= '9') ||
*p == '+' || *p == '-' || *p == '.';
p++);
return ((p != filename) && (p[0] == ':') && (p[1] == '/') && (p[2] == '/'));
}
static inline bool is_cacheable_stream_path(const char *filename)
{
return memcmp(filename, "file://", sizeof("file://") - 1) == 0 ||
@ -1060,7 +1047,7 @@ accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_
if (file_handle->opened_path) {
char *file_path = ZSTR_VAL(file_handle->opened_path);
if (is_stream_path(file_path)) {
if (php_is_stream_path(file_path)) {
if (zend_get_stream_timestamp(file_path, &statbuf) == SUCCESS) {
break;
}
@ -1208,7 +1195,7 @@ zend_string *accel_make_persistent_key(zend_string *str)
/* CWD and include_path don't matter for absolute file names and streams */
if (IS_ABSOLUTE_PATH(path, path_length)) {
/* pass */
} else if (UNEXPECTED(is_stream_path(path))) {
} else if (UNEXPECTED(php_is_stream_path(path))) {
if (!is_cacheable_stream_path(path)) {
return NULL;
}
@ -1891,7 +1878,7 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
zend_op_array *op_array = NULL;
bool from_memory; /* if the script we've got is stored in SHM */
if (is_stream_path(ZSTR_VAL(file_handle->filename)) &&
if (php_is_stream_path(ZSTR_VAL(file_handle->filename)) &&
!is_cacheable_stream_path(ZSTR_VAL(file_handle->filename))) {
return accelerator_orig_compile_file(file_handle, type);
}
@ -2036,7 +2023,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
return accelerator_orig_compile_file(file_handle, type);
}
persistent_script = zend_accel_hash_find(&ZCSG(hash), key);
} else if (UNEXPECTED(is_stream_path(ZSTR_VAL(file_handle->filename)) && !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename)))) {
} else if (UNEXPECTED(php_is_stream_path(ZSTR_VAL(file_handle->filename)) && !is_cacheable_stream_path(ZSTR_VAL(file_handle->filename)))) {
ZCG(cache_opline) = NULL;
ZCG(cache_persistent_script) = NULL;
return accelerator_orig_compile_file(file_handle, type);
@ -4050,7 +4037,7 @@ static void preload_link(void)
static zend_string *preload_resolve_path(zend_string *filename)
{
if (is_stream_path(ZSTR_VAL(filename))) {
if (php_is_stream_path(ZSTR_VAL(filename))) {
return NULL;
}
return zend_resolve_path(filename);

View File

@ -729,7 +729,7 @@ PHPAPI void php_stat(zend_string *filename, int type, zval *return_value)
char realpath[MAXPATHLEN];
const char *file_path_to_check;
/* if the wrapper is not found, we need to expand path to match open behavior */
if (EXPECTED(strstr(local, "://") == NULL || expand_filepath(local, realpath) == NULL)) {
if (EXPECTED(!php_is_stream_path(local) || expand_filepath(local, realpath) == NULL)) {
file_path_to_check = local;
} else {
file_path_to_check = realpath;

View File

@ -619,6 +619,20 @@ PHPAPI HashTable *_php_get_stream_filters_hash(void);
#define php_get_stream_filters_hash() _php_get_stream_filters_hash()
PHPAPI HashTable *php_get_stream_filters_hash_global(void);
extern const php_stream_wrapper_ops *php_stream_user_wrapper_ops;
static inline bool php_is_stream_path(const char *filename)
{
const char *p;
for (p = filename;
(*p >= 'a' && *p <= 'z') ||
(*p >= 'A' && *p <= 'Z') ||
(*p >= '0' && *p <= '9') ||
*p == '+' || *p == '-' || *p == '.';
p++);
return ((p != filename) && (p[0] == ':') && (p[1] == '/') && (p[2] == '/'));
}
END_EXTERN_C()
#endif