Skip to content

Commit 7c2a015

Browse files
committed
Cache the class_name typehint key in arg_info
This leads to up to 2% improvement on one tested real world application by not having to always recalculate the lowercased string and its hash
1 parent c872356 commit 7c2a015

File tree

8 files changed

+28
-3
lines changed

8 files changed

+28
-3
lines changed

Zend/zend_API.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ typedef struct _zend_fcall_info_cache {
6868
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
6969
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
7070

71-
#define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
71+
#define ZEND_FENTRY(zend_name, name, arg_info, flags) { #zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
7272

73-
#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_arg_info)-1), flags },
73+
#define ZEND_RAW_FENTRY(zend_name, name, arg_info, flags) { zend_name, name, arg_info, (uint32_t) (sizeof(arg_info)/sizeof(struct _zend_internal_arg_info)-1), flags },
7474
#define ZEND_RAW_NAMED_FE(zend_name, name, arg_info) ZEND_RAW_FENTRY(#zend_name, name, arg_info, 0)
7575

7676
#define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)

Zend/zend_compile.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4238,9 +4238,11 @@ static void zend_compile_typename(zend_ast *ast, zend_arg_info *arg_info) /* {{{
42384238
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
42394239
class_name = zend_resolve_class_name_ast(ast);
42404240
zend_assert_valid_class_name(class_name);
4241+
arg_info->lower_class_name = zend_string_tolower(class_name);
42414242
} else {
42424243
zend_ensure_valid_class_fetch_type(fetch_type);
42434244
zend_string_addref(class_name);
4245+
arg_info->lower_class_name = NULL;
42444246
}
42454247

42464248
arg_info->type_hint = IS_OBJECT;

Zend/zend_compile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ typedef struct _zend_internal_arg_info {
297297
zend_uchar pass_by_reference;
298298
zend_bool allow_null;
299299
zend_bool is_variadic;
300+
void *reserved; /* to align with zend_arg_info */
300301
} zend_internal_arg_info;
301302

302303
/* arg_info for user functions */
@@ -307,6 +308,7 @@ typedef struct _zend_arg_info {
307308
zend_uchar pass_by_reference;
308309
zend_bool allow_null;
309310
zend_bool is_variadic;
311+
zend_string *lower_class_name;
310312
} zend_arg_info;
311313

312314
/* the following structure repeats the layout of zend_internal_arg_info,

Zend/zend_execute.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,12 @@ ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info
587587

588588
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
589589
{
590-
*pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
590+
/* optimization to not always recalculate the lowercase name and hash */
591+
if (cur_arg_info->lower_class_name) {
592+
*pce = zend_hash_find_ptr(EG(class_table), cur_arg_info->lower_class_name);
593+
} else { /* "extra" fetch type */
594+
*pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
595+
}
591596

592597
*class_name = (*pce) ? (*pce)->name->val : cur_arg_info->class_name->val;
593598
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {

Zend/zend_opcode.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
410410
}
411411
if (arg_info[i].class_name) {
412412
zend_string_release(arg_info[i].class_name);
413+
414+
if (arg_info[i].lower_class_name) {
415+
zend_string_release(arg_info[i].lower_class_name);
416+
}
413417
}
414418
}
415419
efree(arg_info);

ext/opcache/zend_file_cache.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,9 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
438438
if (!IS_SERIALIZED(p->class_name)) {
439439
SERIALIZE_STR(p->class_name);
440440
}
441+
if (p->class_name && !IS_SERIALIZED(p->lower_class_name)) {
442+
SERIALIZE_STR(p->lower_class_name);
443+
}
441444
p++;
442445
}
443446
}
@@ -962,6 +965,9 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
962965
if (!IS_UNSERIALIZED(p->class_name)) {
963966
UNSERIALIZE_STR(p->class_name);
964967
}
968+
if (p->class_name && !IS_UNSERIALIZED(p->lower_class_name)) {
969+
UNSERIALIZE_STR(p->lower_class_name);
970+
}
965971
p++;
966972
}
967973
}

ext/opcache/zend_persist.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
581581
}
582582
if (arg_info[i].class_name) {
583583
zend_accel_store_interned_string(arg_info[i].class_name);
584+
if (arg_info[i].lower_class_name) {
585+
zend_accel_store_interned_string(arg_info[i].lower_class_name);
586+
}
584587
}
585588
}
586589
}

ext/opcache/zend_persist_calc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,9 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
225225
}
226226
if (arg_info[i].class_name) {
227227
ADD_INTERNED_STRING(arg_info[i].class_name, 1);
228+
if (arg_info[i].lower_class_name) {
229+
ADD_INTERNED_STRING(arg_info[i].lower_class_name, 1);
230+
}
228231
}
229232
}
230233
}

0 commit comments

Comments
 (0)