Browse Source

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
pull/1339/merge
Bob Weinand 11 years ago
parent
commit
7c2a0157c7
  1. 4
      Zend/zend_API.h
  2. 2
      Zend/zend_compile.c
  3. 2
      Zend/zend_compile.h
  4. 7
      Zend/zend_execute.c
  5. 4
      Zend/zend_opcode.c
  6. 6
      ext/opcache/zend_file_cache.c
  7. 3
      ext/opcache/zend_persist.c
  8. 3
      ext/opcache/zend_persist_calc.c

4
Zend/zend_API.h

@ -68,9 +68,9 @@ typedef struct _zend_fcall_info_cache {
#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))
#define ZEND_METHOD(classname, name) ZEND_NAMED_FUNCTION(ZEND_MN(classname##_##name))
#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 },
#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 },
#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 },
#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 },
#define ZEND_RAW_NAMED_FE(zend_name, name, arg_info) ZEND_RAW_FENTRY(#zend_name, name, arg_info, 0)
#define ZEND_NAMED_FE(zend_name, name, arg_info) ZEND_FENTRY(zend_name, name, arg_info, 0)

2
Zend/zend_compile.c

@ -4238,9 +4238,11 @@ static void zend_compile_typename(zend_ast *ast, zend_arg_info *arg_info) /* {{{
if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) {
class_name = zend_resolve_class_name_ast(ast);
zend_assert_valid_class_name(class_name);
arg_info->lower_class_name = zend_string_tolower(class_name);
} else {
zend_ensure_valid_class_fetch_type(fetch_type);
zend_string_addref(class_name);
arg_info->lower_class_name = NULL;
}
arg_info->type_hint = IS_OBJECT;

2
Zend/zend_compile.h

@ -297,6 +297,7 @@ typedef struct _zend_internal_arg_info {
zend_uchar pass_by_reference;
zend_bool allow_null;
zend_bool is_variadic;
void *reserved; /* to align with zend_arg_info */
} zend_internal_arg_info;
/* arg_info for user functions */
@ -307,6 +308,7 @@ typedef struct _zend_arg_info {
zend_uchar pass_by_reference;
zend_bool allow_null;
zend_bool is_variadic;
zend_string *lower_class_name;
} zend_arg_info;
/* the following structure repeats the layout of zend_internal_arg_info,

7
Zend/zend_execute.c

@ -587,7 +587,12 @@ ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce)
{
*pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
/* optimization to not always recalculate the lowercase name and hash */
if (cur_arg_info->lower_class_name) {
*pce = zend_hash_find_ptr(EG(class_table), cur_arg_info->lower_class_name);
} else { /* "extra" fetch type */
*pce = zend_fetch_class(cur_arg_info->class_name, (ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD));
}
*class_name = (*pce) ? (*pce)->name->val : cur_arg_info->class_name->val;
if (*pce && (*pce)->ce_flags & ZEND_ACC_INTERFACE) {

4
Zend/zend_opcode.c

@ -410,6 +410,10 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
}
if (arg_info[i].class_name) {
zend_string_release(arg_info[i].class_name);
if (arg_info[i].lower_class_name) {
zend_string_release(arg_info[i].lower_class_name);
}
}
}
efree(arg_info);

6
ext/opcache/zend_file_cache.c

@ -438,6 +438,9 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
if (!IS_SERIALIZED(p->class_name)) {
SERIALIZE_STR(p->class_name);
}
if (p->class_name && !IS_SERIALIZED(p->lower_class_name)) {
SERIALIZE_STR(p->lower_class_name);
}
p++;
}
}
@ -962,6 +965,9 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
if (!IS_UNSERIALIZED(p->class_name)) {
UNSERIALIZE_STR(p->class_name);
}
if (p->class_name && !IS_UNSERIALIZED(p->lower_class_name)) {
UNSERIALIZE_STR(p->lower_class_name);
}
p++;
}
}

3
ext/opcache/zend_persist.c

@ -581,6 +581,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
}
if (arg_info[i].class_name) {
zend_accel_store_interned_string(arg_info[i].class_name);
if (arg_info[i].lower_class_name) {
zend_accel_store_interned_string(arg_info[i].lower_class_name);
}
}
}
}

3
ext/opcache/zend_persist_calc.c

@ -225,6 +225,9 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array)
}
if (arg_info[i].class_name) {
ADD_INTERNED_STRING(arg_info[i].class_name, 1);
if (arg_info[i].lower_class_name) {
ADD_INTERNED_STRING(arg_info[i].lower_class_name, 1);
}
}
}
}

Loading…
Cancel
Save