mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Improve performance by using prealloated op_arrray
This commit is contained in:
parent
df7fbbf949
commit
ec1d9eb592
@ -26,6 +26,7 @@
|
||||
#include "zend_list.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_exceptions.h"
|
||||
#include "zend_objects_API.h"
|
||||
#include "zend_builtin_functions.h"
|
||||
#include "zend_ini.h"
|
||||
#include "zend_vm.h"
|
||||
@ -531,6 +532,8 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
|
||||
#ifdef ZEND_WIN32
|
||||
zend_get_windows_version_info(&executor_globals->windows_version_info);
|
||||
#endif
|
||||
memset(&EG(proxy_call_func), 0, sizeof(zend_op_array));
|
||||
zend_init_proxy_call_func(&EG(proxy_call_func), &EG(proxy_call_op));
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -722,6 +725,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
|
||||
#ifndef ZTS
|
||||
zend_init_rsrc_plist();
|
||||
zend_init_exception_op();
|
||||
zend_init_proxy_call_func(&EG(proxy_call_func), &EG(proxy_call_op));
|
||||
#endif
|
||||
|
||||
zend_ini_startup();
|
||||
|
@ -1292,7 +1292,7 @@ ZEND_FUNCTION(method_exists)
|
||||
|
||||
zend_string_release(lcname);
|
||||
zend_string_release(func->common.function_name);
|
||||
efree(func);
|
||||
zend_free_proxy_call_func(func);
|
||||
return;
|
||||
}
|
||||
zend_string_release(lcname);
|
||||
|
@ -237,6 +237,9 @@ struct _zend_executor_globals {
|
||||
XPFPA_CW_DATATYPE saved_fpu_cw;
|
||||
#endif
|
||||
|
||||
zend_op_array proxy_call_func;
|
||||
zend_op proxy_call_op;
|
||||
|
||||
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "zend_interfaces.h"
|
||||
#include "zend_closures.h"
|
||||
#include "zend_compile.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_hash.h"
|
||||
|
||||
#define DEBUG_OBJECT_HANDLERS 0
|
||||
@ -1035,39 +1034,9 @@ ZEND_API int zend_check_protected(zend_class_entry *ce, zend_class_entry *scope)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static inline zend_op_array *zend_get_proxy_call_function(zend_class_entry *ce, zend_string *method_name, int is_static) /* {{{ */ {
|
||||
zend_op_array *call_user_call = ecalloc(1, ZEND_MM_ALIGNED_SIZE(sizeof(zend_op_array)) + sizeof(zend_op));
|
||||
zend_function *fbc = is_static? ce->__callstatic : ce->__call;
|
||||
|
||||
ZEND_ASSERT(fbc);
|
||||
|
||||
call_user_call->type = ZEND_USER_FUNCTION;
|
||||
call_user_call->scope = ce;
|
||||
call_user_call->prototype = fbc;
|
||||
call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER | (is_static? (ZEND_ACC_STATIC | ZEND_ACC_PUBLIC) : 0);
|
||||
call_user_call->this_var = -1;
|
||||
call_user_call->filename = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.filename : STR_EMPTY_ALLOC();
|
||||
call_user_call->line_start = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_start : 0;
|
||||
call_user_call->line_end = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_end : 0;
|
||||
call_user_call->opcodes = (zend_op *)((char *)call_user_call + ZEND_MM_ALIGNED_SIZE(sizeof(zend_op_array)));
|
||||
call_user_call->opcodes[0].opcode = ZEND_PROXY_CALL;
|
||||
call_user_call->opcodes[0].op1_type = IS_UNUSED;
|
||||
call_user_call->opcodes[0].op2_type = IS_UNUSED;
|
||||
call_user_call->opcodes[0].result_type = IS_UNUSED;
|
||||
ZEND_VM_SET_OPCODE_HANDLER(&call_user_call->opcodes[0]);
|
||||
if (UNEXPECTED(strlen(method_name->val) != method_name->len)) {
|
||||
call_user_call->function_name = zend_string_init(method_name->val, strlen(method_name->val), 0);
|
||||
} else {
|
||||
call_user_call->function_name = zend_string_copy(method_name);
|
||||
}
|
||||
|
||||
return call_user_call;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static inline union _zend_function *zend_get_user_call_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
|
||||
{
|
||||
return (union _zend_function *)zend_get_proxy_call_function(ce, method_name, 0);
|
||||
return (union _zend_function *)zend_get_proxy_call_func(ce, method_name, 0);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -1198,7 +1167,7 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{
|
||||
|
||||
static inline union _zend_function *zend_get_user_callstatic_function(zend_class_entry *ce, zend_string *method_name) /* {{{ */
|
||||
{
|
||||
return (union _zend_function *)zend_get_proxy_call_function(ce, method_name, 1);
|
||||
return (union _zend_function *)zend_get_proxy_call_func(ce, method_name, 1);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "zend.h"
|
||||
#include "zend_globals.h"
|
||||
#include "zend_variables.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_API.h"
|
||||
#include "zend_objects_API.h"
|
||||
|
||||
@ -224,6 +225,57 @@ ZEND_API zend_object_handlers *zend_get_std_object_handlers(void)
|
||||
return &std_object_handlers;
|
||||
}
|
||||
|
||||
ZEND_API void zend_init_proxy_call_func(zend_op_array *func, zend_op *opline)
|
||||
{
|
||||
func->type = ZEND_USER_FUNCTION;
|
||||
|
||||
func->fn_flags = ZEND_ACC_CALL_VIA_HANDLER | ZEND_ACC_PUBLIC;
|
||||
func->this_var = -1;
|
||||
|
||||
opline->opcode = ZEND_PROXY_CALL;
|
||||
opline->op1_type = IS_UNUSED;
|
||||
opline->op2_type = IS_UNUSED;
|
||||
opline->result_type = IS_UNUSED;
|
||||
|
||||
ZEND_VM_SET_OPCODE_HANDLER(opline);
|
||||
|
||||
func->opcodes = opline;
|
||||
}
|
||||
|
||||
ZEND_API zend_op_array *zend_get_proxy_call_func(zend_class_entry *ce, zend_string *method_name, int is_static)
|
||||
{
|
||||
zend_op_array *func;
|
||||
zend_function *fbc = is_static? ce->__callstatic : ce->__call;
|
||||
|
||||
ZEND_ASSERT(fbc);
|
||||
|
||||
if (EXPECTED(EG(proxy_call_func).function_name == NULL)) {
|
||||
func = &EG(proxy_call_func);
|
||||
} else {
|
||||
func = ecalloc(1, ZEND_MM_ALIGNED_SIZE(sizeof(zend_op_array)) + sizeof(zend_op));
|
||||
zend_init_proxy_call_func(func, (zend_op *)((char *)func + ZEND_MM_ALIGNED_SIZE(sizeof(zend_op_array))));
|
||||
}
|
||||
|
||||
if (is_static) {
|
||||
func->fn_flags |= ZEND_ACC_STATIC;
|
||||
} else {
|
||||
func->fn_flags &= ~ZEND_ACC_STATIC;
|
||||
}
|
||||
|
||||
func->scope = ce;
|
||||
func->prototype = fbc;
|
||||
func->filename = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.filename : STR_EMPTY_ALLOC();
|
||||
func->line_start = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_start : 0;
|
||||
func->line_end = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_end : 0;
|
||||
if (UNEXPECTED(strlen(method_name->val) != method_name->len)) {
|
||||
func->function_name = zend_string_init(method_name->val, strlen(method_name->val), 0);
|
||||
} else {
|
||||
func->function_name = zend_string_copy(method_name);
|
||||
}
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -70,8 +70,21 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
|
||||
ZEND_API zend_object *zend_object_create_proxy(zval *object, zval *member);
|
||||
|
||||
ZEND_API zend_object_handlers *zend_get_std_object_handlers(void);
|
||||
|
||||
ZEND_API void zend_init_proxy_call_func(zend_op_array *func, zend_op *opline);
|
||||
|
||||
ZEND_API zend_op_array *zend_get_proxy_call_func(zend_class_entry *ce, zend_string *method_name, int is_static);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#define zend_free_proxy_call_func(func) do { \
|
||||
if (((zend_op_array *)func) == &EG(proxy_call_func)) { \
|
||||
((zend_op_array *)func)->function_name = NULL; \
|
||||
} else { \
|
||||
efree(func); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static zend_always_inline void zend_object_release(zend_object *obj)
|
||||
{
|
||||
if (--GC_REFCOUNT(obj) == 0) {
|
||||
|
@ -6940,7 +6940,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||
}
|
||||
if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
|
||||
zend_string_release(call->func->common.function_name);
|
||||
efree(call->func);
|
||||
zend_free_proxy_call_func(call->func);
|
||||
}
|
||||
|
||||
EX(call) = call->prev_execute_data;
|
||||
@ -7596,7 +7596,7 @@ ZEND_VM_HANDLER(158, ZEND_PROXY_CALL, ANY, ANY)
|
||||
i_init_func_execute_data(call, &call->func->op_array,
|
||||
ret, (fbc->common.fn_flags & ZEND_ACC_STATIC) == 0);
|
||||
|
||||
efree(fbc);
|
||||
zend_free_proxy_call_func(fbc);
|
||||
|
||||
ZEND_VM_ENTER();
|
||||
} else {
|
||||
@ -7618,7 +7618,7 @@ ZEND_VM_HANDLER(158, ZEND_PROXY_CALL, ANY, ANY)
|
||||
|
||||
execute_data = EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
efree(fbc);
|
||||
zend_free_proxy_call_func(fbc);
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
@ -1554,7 +1554,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(
|
||||
}
|
||||
if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) {
|
||||
zend_string_release(call->func->common.function_name);
|
||||
efree(call->func);
|
||||
zend_free_proxy_call_func(call->func);
|
||||
}
|
||||
|
||||
EX(call) = call->prev_execute_data;
|
||||
@ -1810,7 +1810,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PROXY_CALL_SPEC_HANDLER(ZEND_O
|
||||
i_init_func_execute_data(call, &call->func->op_array,
|
||||
ret, (fbc->common.fn_flags & ZEND_ACC_STATIC) == 0);
|
||||
|
||||
efree(fbc);
|
||||
zend_free_proxy_call_func(fbc);
|
||||
|
||||
ZEND_VM_ENTER();
|
||||
} else {
|
||||
@ -1832,7 +1832,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PROXY_CALL_SPEC_HANDLER(ZEND_O
|
||||
|
||||
execute_data = EG(current_execute_data) = call->prev_execute_data;
|
||||
|
||||
efree(fbc);
|
||||
zend_free_proxy_call_func(fbc);
|
||||
|
||||
zend_vm_stack_free_args(call);
|
||||
zend_vm_stack_free_call_frame(call);
|
||||
|
@ -2242,7 +2242,7 @@ ZEND_METHOD(reflection_parameter, __construct)
|
||||
if (fptr->type != ZEND_OVERLOADED_FUNCTION) {
|
||||
zend_string_release(fptr->common.function_name);
|
||||
}
|
||||
efree(fptr);
|
||||
zend_free_proxy_call_func(fptr);
|
||||
}
|
||||
if (is_closure) {
|
||||
zval_ptr_dtor(reference);
|
||||
|
Loading…
Reference in New Issue
Block a user