mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Use run-time cache to avoid repeatable hash lookups when creating anonymous functions and classes
This commit is contained in:
parent
b065fbde19
commit
d5943f5a11
5 changed files with 63 additions and 34 deletions
|
@ -5851,6 +5851,7 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as
|
|||
|
||||
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
|
||||
opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL);
|
||||
opline->extended_value = zend_alloc_cache_slot();
|
||||
opline->op1_type = IS_CONST;
|
||||
LITERAL_STR(opline->op1, key);
|
||||
} else {
|
||||
|
@ -6470,6 +6471,7 @@ zend_op *zend_compile_class_decl(zend_ast *ast, zend_bool toplevel) /* {{{ */
|
|||
|
||||
if (decl->flags & ZEND_ACC_ANON_CLASS) {
|
||||
opline->opcode = ZEND_DECLARE_ANON_CLASS;
|
||||
opline->extended_value = zend_alloc_cache_slot();
|
||||
opline->result_type = IS_VAR;
|
||||
opline->result.var = get_temporary_variable();
|
||||
|
||||
|
|
|
@ -7264,24 +7264,28 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST)
|
|||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY)
|
||||
ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT)
|
||||
{
|
||||
zval *zv;
|
||||
zend_class_entry *ce;
|
||||
USE_OPLINE
|
||||
|
||||
zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zv != NULL);
|
||||
ce = Z_CE_P(zv);
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = ce;
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_LINKED) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
SAVE_OPLINE();
|
||||
zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
ce = CACHED_PTR(opline->extended_value);
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zv != NULL);
|
||||
ce = Z_CE_P(zv);
|
||||
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
SAVE_OPLINE();
|
||||
zend_do_link_class(ce, (OP2_TYPE == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
CACHE_PTR(opline->extended_value, ce);
|
||||
}
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = ce;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY)
|
||||
|
@ -7550,19 +7554,26 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
|
|||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
|
||||
ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED, CACHE_SLOT)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_function *func;
|
||||
zval *zfunc;
|
||||
zval *object;
|
||||
zend_class_entry *called_scope;
|
||||
|
||||
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
|
||||
func = CACHED_PTR(opline->extended_value);
|
||||
if (UNEXPECTED(func == NULL)) {
|
||||
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zfunc != NULL);
|
||||
func = Z_FUNC_P(zfunc);
|
||||
ZEND_ASSERT(func->type == ZEND_USER_FUNCTION);
|
||||
CACHE_PTR(opline->extended_value, func);
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) == IS_OBJECT) {
|
||||
called_scope = Z_OBJCE(EX(This));
|
||||
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
|
||||
if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) ||
|
||||
(EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
|
||||
object = NULL;
|
||||
} else {
|
||||
|
@ -7572,7 +7583,7 @@ ZEND_VM_HANDLER(142, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
|
|||
called_scope = Z_CE(EX(This));
|
||||
object = NULL;
|
||||
}
|
||||
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
|
||||
zend_create_closure(EX_VAR(opline->result.var), func,
|
||||
EX(func)->op_array.scope, called_scope, object);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
|
|
|
@ -2430,18 +2430,22 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE
|
|||
zend_class_entry *ce;
|
||||
USE_OPLINE
|
||||
|
||||
zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zv != NULL);
|
||||
ce = Z_CE_P(zv);
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = ce;
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_LINKED) {
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
SAVE_OPLINE();
|
||||
zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL);
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
ce = CACHED_PTR(opline->extended_value);
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
zv = zend_hash_find_ex(EG(class_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zv != NULL);
|
||||
ce = Z_CE_P(zv);
|
||||
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
SAVE_OPLINE();
|
||||
zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL);
|
||||
if (UNEXPECTED(EG(exception))) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
CACHE_PTR(opline->extended_value, ce);
|
||||
}
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = ce;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
@ -9395,16 +9399,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U
|
|||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_function *func;
|
||||
zval *zfunc;
|
||||
zval *object;
|
||||
zend_class_entry *called_scope;
|
||||
|
||||
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
|
||||
func = CACHED_PTR(opline->extended_value);
|
||||
if (UNEXPECTED(func == NULL)) {
|
||||
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zfunc != NULL);
|
||||
func = Z_FUNC_P(zfunc);
|
||||
ZEND_ASSERT(func->type == ZEND_USER_FUNCTION);
|
||||
CACHE_PTR(opline->extended_value, func);
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) == IS_OBJECT) {
|
||||
called_scope = Z_OBJCE(EX(This));
|
||||
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
|
||||
if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) ||
|
||||
(EX(func)->common.fn_flags & ZEND_ACC_STATIC))) {
|
||||
object = NULL;
|
||||
} else {
|
||||
|
@ -9414,7 +9425,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C
|
|||
called_scope = Z_CE(EX(This));
|
||||
object = NULL;
|
||||
}
|
||||
zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
|
||||
zend_create_closure(EX_VAR(opline->result.var), func,
|
||||
EX(func)->op_array.scope, called_scope, object);
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
|
|
|
@ -363,11 +363,11 @@ static uint32_t zend_vm_opcodes_flags[195] = {
|
|||
0x00000000,
|
||||
0x00000101,
|
||||
0x00000000,
|
||||
0x00000103,
|
||||
0x00040103,
|
||||
0x00000303,
|
||||
0x00000003,
|
||||
0x00000303,
|
||||
0x00000000,
|
||||
0x00040000,
|
||||
0x00000000,
|
||||
0x00060757,
|
||||
0x00000000,
|
||||
|
|
|
@ -770,6 +770,11 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
|||
bind_var_slot[opline->op2.constant] = opline->extended_value;
|
||||
}
|
||||
break;
|
||||
case ZEND_DECLARE_LAMBDA_FUNCTION:
|
||||
case ZEND_DECLARE_ANON_CLASS:
|
||||
opline->extended_value = cache_size;
|
||||
cache_size += sizeof(void *);
|
||||
break;
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue