From 350a95d16ba39994d916c3e85b92bc251f8524f4 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Sat, 16 May 2020 13:16:40 -0600 Subject: [PATCH 1/3] Add zend_instrument API The instrument API can be used to add handlers that get called before and after a function call. An interested extension can add a call to `zend_instrument_register(...)` during MINIT; zend extensions can do the same during STARTUP. When a function is called for the first time, the registered instruments will be queried to provide the begin/end handlers they wish to install. If they do not want to instrument the function then they may return NULL for both handlers. Co-authored-by: Nikita Popov Co-authored-by: Sammy Powers --- Zend/zend_API.c | 1 + Zend/zend_closures.c | 8 + Zend/zend_compile.c | 5 + Zend/zend_compile.h | 3 + Zend/zend_execute.c | 34 ++- Zend/zend_execute.h | 16 +- Zend/zend_execute_API.c | 12 +- Zend/zend_instrument.c | 131 ++++++++++ Zend/zend_instrument.h | 91 +++++++ Zend/zend_object_handlers.c | 2 + Zend/zend_opcode.c | 1 + Zend/zend_vm_def.h | 82 +++++- Zend/zend_vm_execute.h | 292 ++++++++++++++++++++-- configure.ac | 3 +- ext/opcache/zend_accelerator_util_funcs.c | 3 + ext/opcache/zend_persist.c | 3 + ext/pdo/pdo_dbh.c | 4 + main/main.c | 4 + 18 files changed, 661 insertions(+), 34 deletions(-) create mode 100644 Zend/zend_instrument.c create mode 100644 Zend/zend_instrument.h diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 01f9277214d77..f90ecdc32abf1 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -2061,6 +2061,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio } internal_function->type = ZEND_INTERNAL_FUNCTION; internal_function->module = EG(current_module); + ZEND_MAP_PTR_NEW(internal_function->instrument_cache); memset(internal_function->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*)); if (scope) { diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 02df3504ccf16..6e414263cb9d8 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -309,6 +309,10 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, call.function_name = mptr->common.function_name; call.scope = mptr->common.scope; + // TODO: Is this correct??? + static const zend_instrument_cache *dummy_handlers = ZEND_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call.instrument_cache, (zend_instrument_cache **) &dummy_handlers); + zend_free_trampoline(mptr); mptr = (zend_function *) &call; } @@ -395,6 +399,10 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* { invoke->internal_function.module = 0; invoke->internal_function.scope = zend_ce_closure; invoke->internal_function.function_name = ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE); + + // TODO: Is this correct??? + static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(invoke->internal_function.instrument_cache, (zend_instrument_cache **) &dummy_handler); return invoke; } /* }}} */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 58c74e1da08e9..1e9be24d5f2a5 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -6258,9 +6258,14 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /* op_array->fn_flags |= ZEND_ACC_PRELOADED; ZEND_MAP_PTR_NEW(op_array->run_time_cache); ZEND_MAP_PTR_NEW(op_array->static_variables_ptr); + ZEND_MAP_PTR_NEW(op_array->instrument_cache); } else { ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*))); ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL); + + ZEND_MAP_PTR_INIT(op_array->instrument_cache, + zend_arena_alloc(&CG(arena), sizeof(void*))); + ZEND_MAP_PTR_SET(op_array->instrument_cache, NULL); } op_array->fn_flags |= (orig_op_array->fn_flags & ZEND_ACC_STRICT_TYPES); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index a90219b1b4453..f95e5abba4722 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -403,6 +403,7 @@ struct _zend_op_array { uint32_t num_args; uint32_t required_num_args; zend_arg_info *arg_info; + ZEND_MAP_PTR_DEF(struct zend_instrument_cache *, instrument_cache); /* END of common elements */ int cache_size; /* number of run_time_cache_slots * sizeof(void*) */ @@ -452,6 +453,7 @@ typedef struct _zend_internal_function { uint32_t num_args; uint32_t required_num_args; zend_internal_arg_info *arg_info; + ZEND_MAP_PTR_DEF(struct zend_instrument_cache *, instrument_cache); /* END of common elements */ zif_handler handler; @@ -475,6 +477,7 @@ union _zend_function { uint32_t num_args; uint32_t required_num_args; zend_arg_info *arg_info; /* index -1 represents the return value info, if any */ + ZEND_MAP_PTR_DEF(struct zend_instrument_cache *, instrument_cache); } common; zend_op_array op_array; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 2eb7b1726010c..8027283415b31 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -43,6 +43,7 @@ /* Virtual current working directory support */ #include "zend_virtual_cwd.h" +#include "zend_instrument.h" #ifdef HAVE_GCC_GLOBAL_REGS # if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386) @@ -137,6 +138,7 @@ ZEND_API const zend_internal_function zend_pass_function = { 0, /* num_args */ 0, /* required_num_args */ NULL, /* arg_info */ + NULL, ZEND_FN(pass), /* handler */ NULL, /* module */ {NULL,NULL,NULL,NULL} /* reserved */ @@ -3307,10 +3309,7 @@ static int zend_check_symbol(zval *pz) #define CHECK_SYMBOL_TABLES() #endif -ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value) -{ - execute_data->func->internal_function.handler(execute_data, return_value); -} +ZEND_API extern inline void execute_internal(zend_execute_data *execute_data, zval *return_value); ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */ { @@ -3508,6 +3507,9 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /* if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache_i(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } return fbc; } return NULL; @@ -3523,6 +3525,9 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache_i(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } return fbc; } return NULL; @@ -3555,6 +3560,12 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu ZEND_MAP_PTR_SET(op_array->run_time_cache, ptr); memset(ptr, 0, op_array->cache_size); } + if (!ZEND_MAP_PTR(op_array->instrument_cache)) { + ZEND_MAP_PTR_INIT(op_array->instrument_cache, + zend_arena_alloc(&CG(arena), sizeof(void*))); + ZEND_MAP_PTR_SET(op_array->instrument_cache, NULL); + zend_instrument_install_handlers((zend_function *) op_array); + } EX(run_time_cache) = RUN_TIME_CACHE(op_array); EG(current_execute_data) = execute_data; @@ -3579,6 +3590,9 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array * if (!RUN_TIME_CACHE(op_array)) { init_func_run_time_cache(op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(op_array->instrument_cache))) { + zend_instrument_install_handlers((zend_function *) op_array); + } i_init_func_execute_data(op_array, return_value, 1 EXECUTE_DATA_CC); #if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) @@ -3930,6 +3944,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } else { if (ZSTR_VAL(function)[0] == '\\') { lcname = zend_string_alloc(ZSTR_LEN(function) - 1, 0); @@ -3948,6 +3965,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } called_scope = NULL; } @@ -3992,6 +4012,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } return zend_vm_stack_push_call_frame(call_info, fbc, num_args, object_or_called_scope); @@ -4077,6 +4100,9 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } return zend_vm_stack_push_call_frame(call_info, fbc, num_args, object_or_called_scope); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 2299adf62fe7e..f486174b7bbea 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -23,6 +23,7 @@ #include "zend_compile.h" #include "zend_hash.h" +#include "zend_instrument.h" #include "zend_operators.h" #include "zend_variables.h" @@ -39,7 +40,20 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *execute_data, zend_ ZEND_API void zend_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value); ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value); ZEND_API void execute_ex(zend_execute_data *execute_data); -ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value); + +ZEND_API inline void execute_internal(zend_execute_data *execute_data, zval *return_value) +{ + zend_instrument_cache *cache = (zend_instrument_cache *) + ZEND_MAP_PTR_GET(execute_data->func->common.instrument_cache); + if (UNEXPECTED(cache != ZEND_NOT_INSTRUMENTED)) { + zend_instrument_call_begin_handlers(execute_data, cache); + execute_data->func->internal_function.handler(execute_data, return_value); + zend_instrument_call_end_handlers(execute_data, cache); + } else { + execute_data->func->internal_function.handler(execute_data, return_value); + } +} + ZEND_API zend_class_entry *zend_lookup_class(zend_string *name); ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *lcname, uint32_t flags); ZEND_API zend_class_entry *zend_get_called_scope(zend_execute_data *ex); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0a7a7e3b15cec..229f1462bebde 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -797,6 +797,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / const zend_op *current_opline_before_exception = EG(opline_before_exception); zend_init_func_execute_data(call, &func->op_array, fci->retval); + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } zend_execute_ex(call); EG(opline_before_exception) = current_opline_before_exception; if (call_via_handler) { @@ -807,12 +811,16 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION); + + if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { + zend_instrument_install_handlers(func); + } + ZVAL_NULL(fci->retval); call->prev_execute_data = EG(current_execute_data); EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { - /* saves one function call if zend_execute_internal is not used */ - func->internal_function.handler(call, fci->retval); + execute_internal(call, fci->retval); } else { zend_execute_internal(call, fci->retval); } diff --git a/Zend/zend_instrument.c b/Zend/zend_instrument.c new file mode 100644 index 0000000000000..600891fe8aa44 --- /dev/null +++ b/Zend/zend_instrument.c @@ -0,0 +1,131 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Levi Morrison | + | Sammy Kaye Powers | + +----------------------------------------------------------------------+ +*/ + +#include "zend.h" +#include "zend_API.h" +#include "zend_instrument.h" + +struct zend_instruments_list { + struct zend_instruments_list *prev; + zend_instrument instrument; +}; +typedef struct zend_instruments_list zend_instruments_list; + +static zend_instruments_list *_zend_instruments; + +ZEND_API void zend_instrument_init(void) +{ + _zend_instruments = NULL; +} + +ZEND_API void zend_instrument_shutdown(void) +{ + zend_instruments_list *curr, *prev; + for (curr = _zend_instruments; curr; curr = prev) { + prev = curr->prev; + free(curr); + } +} + +ZEND_API void zend_instrument_register(zend_instrument instrument) +{ + zend_instruments_list *node = malloc(sizeof(zend_instruments_list)); + node->instrument = instrument; + node->prev = _zend_instruments; + _zend_instruments = node; +} + +struct zend_instrument_handlers_list { + struct zend_instrument_handlers_list *prev; + zend_instrument_handlers handlers; + size_t count; +}; +typedef struct zend_instrument_handlers_list zend_instrument_handlers_list; + + +extern inline void zend_instrument_call_begin_handlers( + zend_execute_data *execute_data, zend_instrument_cache *cache); +extern inline void zend_instrument_call_end_handlers( + zend_execute_data *execute_data, zend_instrument_cache *cache); + +static zend_instrument_handlers_list *_instrument_add( + zend_instrument_handlers_list *instruments, + zend_instrument_handlers handlers) +{ + if (!handlers.begin && !handlers.end) { + return instruments; + } + + zend_instrument_handlers_list *n = + emalloc(sizeof(zend_instrument_handlers_list)); + if (instruments) { + n->prev = instruments; + n->count = instruments->count + 1; + } else { + n->prev = NULL; + n->count = 1; + } + n->handlers = handlers; + return n; +} + +static zend_instrument_cache *_instrument_attach_handler( + zend_function *function, + zend_instrument_handlers_list *handlers_list) +{ + zend_instrument_cache *cache = + malloc(sizeof(zend_instrument_cache)); + cache->instruments_len = handlers_list->count; + cache->handlers = + calloc(handlers_list->count, sizeof(zend_instrument_handlers)); + + zend_instrument_handlers *handlers = cache->handlers; + zend_instrument_handlers_list *curr; + for (curr = handlers_list; curr; curr = curr->prev) { + *handlers++ = curr->handlers; + } + + ZEND_MAP_PTR_SET(function->common.instrument_cache, cache); + + return cache; +} + +ZEND_API void zend_instrument_install_handlers(zend_function *function) +{ + zend_instrument_handlers_list *handlers_list = NULL; + zend_instruments_list *elem; + + for (elem = _zend_instruments; elem; elem = elem->prev) { + zend_instrument_handlers handlers = elem->instrument(function); + handlers_list = _instrument_add(handlers_list, handlers); + } + + if (handlers_list) { + _instrument_attach_handler(function, handlers_list); + + // cleanup handlers_list + zend_instrument_handlers_list *curr, *prev; + for (curr = handlers_list; curr; curr = prev) { + prev = curr->prev; + efree(curr); + } + } else { + ZEND_MAP_PTR_SET(function->common.instrument_cache, ZEND_NOT_INSTRUMENTED); + } +} diff --git a/Zend/zend_instrument.h b/Zend/zend_instrument.h new file mode 100644 index 0000000000000..5b819f3b23292 --- /dev/null +++ b/Zend/zend_instrument.h @@ -0,0 +1,91 @@ +/* + +----------------------------------------------------------------------+ + | Zend Engine | + +----------------------------------------------------------------------+ + | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) | + +----------------------------------------------------------------------+ + | This source file is subject to version 2.00 of the Zend license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.zend.com/license/2_00.txt. | + | If you did not receive a copy of the Zend license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@zend.com so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Levi Morrison | + | Sammy Kaye Powers | + +----------------------------------------------------------------------+ +*/ + +#ifndef ZEND_INSTRUMENT_H +#define ZEND_INSTRUMENT_H + +BEGIN_EXTERN_C() + +typedef void (*zend_instrument_begin_handler)(zend_execute_data *ex); +typedef void (*zend_instrument_end_handler)(zend_execute_data *ex/*, zval *return_value*/); + +struct zend_instrument_handlers { + zend_instrument_begin_handler begin; + + /* todo: need to figure out how to tell end that it is exiting normally + * or not; checking for EG(exception) is not enough (unclean shutdown). + */ + zend_instrument_end_handler end; +}; +typedef struct zend_instrument_handlers zend_instrument_handlers; + +struct zend_instrument_cache { + // todo: use arena + size_t instruments_len; + zend_instrument_handlers *handlers; +}; +typedef struct zend_instrument_cache zend_instrument_cache; + +/* If the fn should not be instrumented then return {NULL, NULL} */ +typedef zend_instrument_handlers (*zend_instrument)(zend_function *func); + +#define ZEND_NOT_INSTRUMENTED ((void *) 1) + +// Call during minit/startup ONLY +ZEND_API void zend_instrument_register(zend_instrument cb); + +// Called by engine before MINITs +ZEND_API void zend_instrument_init(void); +ZEND_API void zend_instrument_shutdown(void); + +ZEND_API void zend_instrument_install_handlers(zend_function *function); + +inline void zend_instrument_call_begin_handlers( + zend_execute_data *execute_data, zend_instrument_cache *cache) +{ + zend_instrument_handlers *handler; + zend_instrument_handlers *stop = + cache->handlers + cache->instruments_len; + + for (handler = cache->handlers; handler != stop; ++handler) { + if (handler->begin) { + handler->begin(execute_data); + } + } +} + +inline void zend_instrument_call_end_handlers( + zend_execute_data *execute_data, zend_instrument_cache *cache) +{ + zend_instrument_handlers *handler = + cache->handlers + cache->instruments_len; + zend_instrument_handlers *stop = cache->handlers; + + // todo: send return_value to end, maybe protected via zval copy + // todo: decide if this should run in reverse order or not + while (handler-- != stop) { + if (handler->end) { + handler->end(execute_data); + } + } +} + +END_EXTERN_C() + +#endif /* ZEND_INSTRUMENT_H */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 7abc87d75ec7c..3fa56e6558737 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1204,6 +1204,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend * The low bit must be zero, to not be interpreted as a MAP_PTR offset. */ static const void *dummy = (void*)(intptr_t)2; + static const zend_instrument_cache *dummy_handlers = ZEND_NOT_INSTRUMENTED; ZEND_ASSERT(fbc); @@ -1223,6 +1224,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend } func->opcodes = &EG(call_trampoline_op); ZEND_MAP_PTR_INIT(func->run_time_cache, (void***)&dummy); + ZEND_MAP_PTR_INIT(func->instrument_cache, (zend_instrument_cache **) &dummy_handlers); func->scope = fbc->common.scope; /* reserve space for arguments, local and temporary variables */ func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, 2) : 2; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 0dd42f8e6e1ba..a412dcd89cb7a 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -67,6 +67,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->arg_info = NULL; op_array->num_args = 0; op_array->required_num_args = 0; + ZEND_MAP_PTR_INIT(op_array->instrument_cache, NULL); op_array->scope = NULL; op_array->prototype = NULL; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index de0dfa2f357c3..82114224d330f 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3468,6 +3468,9 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (OP2_TYPE != IS_CONST) { @@ -3592,6 +3595,9 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (OP2_TYPE != IS_CONST) { FREE_OP2(); } @@ -3608,6 +3614,9 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -3658,6 +3667,9 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } CACHE_PTR(opline->result.num, fbc); } call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, @@ -3770,6 +3782,9 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { init_func_run_time_cache(&func->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { + zend_instrument_install_handlers(func); + } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); @@ -3807,6 +3822,9 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } CACHE_PTR(opline->result.num, fbc); } @@ -3837,6 +3855,9 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT) if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } CACHE_PTR(opline->result.num, fbc); } @@ -3853,7 +3874,6 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) { USE_OPLINE zend_execute_data *call = EX(call); - zend_function *fbc = call->func; zval *ret; zval retval; @@ -3864,13 +3884,13 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL)) EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + zend_bool should_throw = zend_internal_call_should_throw(call->func, call); #endif ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -3919,6 +3939,12 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL)) call->prev_execute_data = execute_data; execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -3943,6 +3969,12 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) call->prev_execute_data = execute_data; execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -3972,7 +4004,7 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -4025,6 +4057,11 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + if (EXPECTED(zend_execute_ex == execute_ex)) { LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -4061,9 +4098,9 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); + /* saves one function call if zend_execute_internal is not used */ if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); } else { zend_execute_internal(call, ret); } @@ -4230,6 +4267,15 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } @@ -5331,14 +5377,19 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N ZEND_VM_NEXT_OPCODE_EX(1, 2); } - /* Perform a dummy function call */ + /* Perform a dummy function call to evaluate arguments */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); + static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { + zend_instrument_install_handlers(constructor); + } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, @@ -7317,6 +7368,15 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca } /* Uncaught exception */ + + if (execute_data->func) { + zend_function *func = execute_data->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(execute_data, cache); + } + } + cleanup_live_vars(execute_data, op_num, 0); if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); @@ -8107,6 +8167,9 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { @@ -8135,9 +8198,10 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) } ZVAL_NULL(ret); + + /* saves one function call if zend_execute_internal is not used */ if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); } else { zend_execute_internal(call, ret); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0bf16a6fee812..bd4b9d2c95b13 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1216,7 +1216,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV { USE_OPLINE zend_execute_data *call = EX(call); - zend_function *fbc = call->func; zval *ret; zval retval; @@ -1227,13 +1226,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + zend_bool should_throw = zend_internal_call_should_throw(call->func, call); #endif ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -1268,7 +1267,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV { USE_OPLINE zend_execute_data *call = EX(call); - zend_function *fbc = call->func; zval *ret; zval retval; @@ -1279,13 +1277,13 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV EG(current_execute_data) = call; #if ZEND_DEBUG - zend_bool should_throw = zend_internal_call_should_throw(fbc, call); + zend_bool should_throw = zend_internal_call_should_throw(call->func, call); #endif ret = 1 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -1334,6 +1332,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV call->prev_execute_data = execute_data; execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -1357,6 +1361,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV call->prev_execute_data = execute_data; execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -1381,6 +1391,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S call->prev_execute_data = execute_data; execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -1410,7 +1426,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -1462,6 +1478,12 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S call->prev_execute_data = execute_data; execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -1491,7 +1513,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S ret = 1 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); #if ZEND_DEBUG if (!EG(exception) && call->func) { @@ -1544,6 +1566,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + if (EXPECTED(zend_execute_ex == execute_ex)) { LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -1580,9 +1607,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV ret = 0 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); + /* saves one function call if zend_execute_internal is not used */ if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); } else { zend_execute_internal(call, ret); } @@ -1642,6 +1669,11 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_begin_handlers(call, cache); + } + if (EXPECTED(zend_execute_ex == execute_ex)) { LOAD_OPLINE_EX(); ZEND_VM_ENTER_EX(); @@ -1678,9 +1710,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV ret = 1 ? EX_VAR(opline->result.var) : &retval; ZVAL_NULL(ret); + /* saves one function call if zend_execute_internal is not used */ if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); } else { zend_execute_internal(call, ret); } @@ -2522,6 +2554,15 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try } /* Uncaught exception */ + + if (execute_data->func) { + zend_function *func = execute_data->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(execute_data, cache); + } + } + cleanup_live_vars(execute_data, op_num, 0); if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); @@ -2748,6 +2789,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); if (EXPECTED(zend_execute_ex == execute_ex)) { @@ -2776,9 +2820,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z } ZVAL_NULL(ret); + + /* saves one function call if zend_execute_internal is not used */ if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); + execute_internal(call, ret); } else { zend_execute_internal(call, ret); } @@ -2863,6 +2908,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } CACHE_PTR(opline->result.num, fbc); } call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, @@ -2949,6 +2997,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } CACHE_PTR(opline->result.num, fbc); } @@ -2979,6 +3030,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } CACHE_PTR(opline->result.num, fbc); } @@ -3523,6 +3577,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -5680,6 +5743,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CONST != IS_CONST) { @@ -5803,6 +5869,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_CONST != IS_CONST) { } @@ -5819,6 +5888,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -5897,6 +5969,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { init_func_run_time_cache(&func->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { + zend_instrument_install_handlers(func); + } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); @@ -7855,6 +7930,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -7978,6 +8056,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -7994,6 +8075,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -8073,6 +8157,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { init_func_run_time_cache(&func->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { + zend_instrument_install_handlers(func); + } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); @@ -8721,6 +8808,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_UNUSED != IS_CONST) { } @@ -8737,6 +8827,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -8876,14 +8969,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER( ZEND_VM_NEXT_OPCODE_EX(1, 2); } - /* Perform a dummy function call */ + /* Perform a dummy function call to evaluate arguments */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); + static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { + zend_instrument_install_handlers(constructor); + } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, @@ -10111,6 +10209,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CV != IS_CONST) { @@ -10234,6 +10335,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_CV != IS_CONST) { } @@ -10250,6 +10354,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -10328,6 +10435,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { init_func_run_time_cache(&func->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { + zend_instrument_install_handlers(func); + } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); @@ -14401,6 +14511,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CONST != IS_CONST) { @@ -15782,6 +15895,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -17057,6 +17173,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CV != IS_CONST) { @@ -17377,6 +17496,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -19799,6 +19927,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -22716,6 +22853,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_CONST != IS_CONST) { } @@ -22732,6 +22872,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -24946,6 +25089,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -24962,6 +25108,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -26218,6 +26367,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_UNUSED != IS_CONST) { } @@ -26234,6 +26386,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -26373,14 +26528,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZE ZEND_VM_NEXT_OPCODE_EX(1, 2); } - /* Perform a dummy function call */ + /* Perform a dummy function call to evaluate arguments */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); + static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { + zend_instrument_install_handlers(constructor); + } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, @@ -28471,6 +28631,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_CV != IS_CONST) { } @@ -28487,6 +28650,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -30533,6 +30699,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CONST != IS_CONST) { @@ -30656,6 +30825,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_CONST != IS_CONST) { } @@ -30672,6 +30844,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -32401,6 +32576,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -32524,6 +32702,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -32540,6 +32721,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -32940,6 +33124,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_UNUSED != IS_CONST) { } @@ -32956,6 +33143,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -33095,14 +33285,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER ZEND_VM_NEXT_OPCODE_EX(1, 2); } - /* Perform a dummy function call */ + /* Perform a dummy function call to evaluate arguments */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); + static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { + zend_instrument_install_handlers(constructor); + } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, @@ -34795,6 +34990,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CV != IS_CONST) { @@ -34918,6 +35116,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } if (IS_CV != IS_CONST) { } @@ -34934,6 +35135,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { @@ -35732,6 +35936,15 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -39643,6 +39856,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CONST != IS_CONST) { @@ -43080,6 +43296,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { @@ -47962,6 +48181,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } + if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { + zend_instrument_install_handlers(fbc); + } } if (IS_CV != IS_CONST) { @@ -52297,6 +52519,15 @@ ZEND_API void execute_ex(zend_execute_data *ex) } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + goto zend_leave_helper_SPEC_LABEL; } @@ -53782,6 +54013,15 @@ ZEND_API void execute_ex(zend_execute_data *ex) } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + goto zend_leave_helper_SPEC_LABEL; } @@ -54059,6 +54299,15 @@ ZEND_API void execute_ex(zend_execute_data *ex) } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + goto zend_leave_helper_SPEC_LABEL; } @@ -55124,6 +55373,15 @@ ZEND_API void execute_ex(zend_execute_data *ex) } } } + + if (EG(current_execute_data)->func) { + zend_function *func = EG(current_execute_data)->func; + zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_NOT_INSTRUMENTED) { + zend_instrument_call_end_handlers(EG(current_execute_data), cache); + } + } + goto zend_leave_helper_SPEC_LABEL; } diff --git a/configure.ac b/configure.ac index 5278718f1a7e3..1ef4417454466 100644 --- a/configure.ac +++ b/configure.ac @@ -1462,7 +1462,8 @@ PHP_ADD_SOURCES(Zend, \ zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \ zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \ zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \ - zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c, \ + zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c \ + zend_instrument.c, \ -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1) dnl Selectively disable optimization due to high RAM usage during compiling the diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 131fc8495b910..90c002c654cc5 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -202,6 +202,9 @@ static void zend_hash_clone_methods(HashTable *ht) if (IN_ARENA(ZEND_MAP_PTR(new_entry->run_time_cache))) { ZEND_MAP_PTR_INIT(new_entry->run_time_cache, ARENA_REALLOC(ZEND_MAP_PTR(new_entry->run_time_cache))); } + if (IN_ARENA(ZEND_MAP_PTR(new_entry->instrument_cache))) { + ZEND_MAP_PTR_INIT(new_entry->instrument_cache, ARENA_REALLOC(ZEND_MAP_PTR(new_entry->instrument_cache))); + } ZEND_MAP_PTR_INIT(new_entry->static_variables_ptr, &new_entry->static_variables); } } diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 6a158e73f9e33..64421d089ec38 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -584,6 +584,7 @@ static void zend_persist_op_array(zval *zv) if (!ZCG(current_persistent_script)->corrupted) { op_array->fn_flags |= ZEND_ACC_IMMUTABLE; ZEND_MAP_PTR_NEW(op_array->run_time_cache); + ZEND_MAP_PTR_NEW(op_array->instrument_cache); if (op_array->static_variables) { ZEND_MAP_PTR_NEW(op_array->static_variables_ptr); } @@ -591,6 +592,8 @@ static void zend_persist_op_array(zval *zv) ZEND_MAP_PTR_INIT(op_array->run_time_cache, ZCG(arena_mem)); ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*))); ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL); + ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*))); + ZEND_MAP_PTR_SET(op_array->instrument_cache, NULL); } } diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 769fe25f9d832..7f8d0205c50d6 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1238,6 +1238,10 @@ int pdo_hash_methods(pdo_dbh_object_t *dbh_obj, int kind) func.num_args = 0; func.required_num_args = 0; } + + ZEND_MAP_PTR_INIT(func.instrument_cache, zend_arena_alloc(&CG(arena), sizeof(void*))); + ZEND_MAP_PTR_SET(func.instrument_cache, NULL); + zend_set_function_arg_flags((zend_function*)&func); namelen = strlen(funcs->fname); lc_name = emalloc(namelen+1); diff --git a/main/main.c b/main/main.c index 6143718d05d42..5a2cfed6e69b4 100644 --- a/main/main.c +++ b/main/main.c @@ -71,6 +71,7 @@ #include "zend_highlight.h" #include "zend_extensions.h" #include "zend_ini.h" +#include "zend_instrument.h" #include "zend_dtrace.h" #include "php_content_types.h" @@ -2297,6 +2298,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod ahead of all other internals */ php_ini_register_extensions(); + zend_instrument_init(); zend_startup_modules(); /* start Zend extensions */ @@ -2495,6 +2497,8 @@ void php_module_shutdown(void) _set_invalid_parameter_handler(old_invalid_parameter_handler); } #endif + + zend_instrument_shutdown(); } /* }}} */ From 9e1eb7f66e2b21a5f1a831270999cd6d836038d3 Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Sun, 26 Apr 2020 02:13:13 -0600 Subject: [PATCH 2/3] Rename zend_instrument -> zend_instrument_fcall This leaves room for other types of instruments in the future. Also passes the return_value into the end handler, or an undef one in the case of an exception. --- Zend/zend_closures.c | 8 +- Zend/zend_compile.h | 6 +- Zend/zend_execute.c | 16 +-- Zend/zend_execute.h | 11 +- Zend/zend_execute_API.c | 8 +- Zend/zend_instrument.c | 104 +++++++++--------- Zend/zend_instrument.h | 46 ++++---- Zend/zend_object_handlers.c | 5 +- Zend/zend_vm_def.h | 59 +++++----- Zend/zend_vm_execute.h | 211 +++++++++++++++++++----------------- 10 files changed, 250 insertions(+), 224 deletions(-) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 6e414263cb9d8..9d8b07c203351 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -310,8 +310,8 @@ static int zend_create_closure_from_callable(zval *return_value, zval *callable, call.scope = mptr->common.scope; // TODO: Is this correct??? - static const zend_instrument_cache *dummy_handlers = ZEND_NOT_INSTRUMENTED; - ZEND_MAP_PTR_INIT(call.instrument_cache, (zend_instrument_cache **) &dummy_handlers); + static const zend_instrument_fcall_cache *dummy_handlers = ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call.instrument_cache, (zend_instrument_fcall_cache **) &dummy_handlers); zend_free_trampoline(mptr); mptr = (zend_function *) &call; @@ -401,8 +401,8 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zend_object *object) /* { invoke->internal_function.function_name = ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE); // TODO: Is this correct??? - static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; - ZEND_MAP_PTR_INIT(invoke->internal_function.instrument_cache, (zend_instrument_cache **) &dummy_handler); + static const zend_instrument_fcall_cache *dummy_handler = ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(invoke->internal_function.instrument_cache, (zend_instrument_fcall_cache **) &dummy_handler); return invoke; } /* }}} */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index f95e5abba4722..90b9268b780f0 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -403,7 +403,7 @@ struct _zend_op_array { uint32_t num_args; uint32_t required_num_args; zend_arg_info *arg_info; - ZEND_MAP_PTR_DEF(struct zend_instrument_cache *, instrument_cache); + ZEND_MAP_PTR_DEF(struct zend_instrument_fcall_cache *, instrument_cache); /* END of common elements */ int cache_size; /* number of run_time_cache_slots * sizeof(void*) */ @@ -453,7 +453,7 @@ typedef struct _zend_internal_function { uint32_t num_args; uint32_t required_num_args; zend_internal_arg_info *arg_info; - ZEND_MAP_PTR_DEF(struct zend_instrument_cache *, instrument_cache); + ZEND_MAP_PTR_DEF(struct zend_instrument_fcall_cache *, instrument_cache); /* END of common elements */ zif_handler handler; @@ -477,7 +477,7 @@ union _zend_function { uint32_t num_args; uint32_t required_num_args; zend_arg_info *arg_info; /* index -1 represents the return value info, if any */ - ZEND_MAP_PTR_DEF(struct zend_instrument_cache *, instrument_cache); + ZEND_MAP_PTR_DEF(struct zend_instrument_fcall_cache *, instrument_cache); } common; zend_op_array op_array; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 8027283415b31..89c7468ee3b13 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3508,7 +3508,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /* init_func_run_time_cache_i(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } return fbc; } @@ -3526,7 +3526,7 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, init_func_run_time_cache_i(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } return fbc; } @@ -3564,7 +3564,7 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu ZEND_MAP_PTR_INIT(op_array->instrument_cache, zend_arena_alloc(&CG(arena), sizeof(void*))); ZEND_MAP_PTR_SET(op_array->instrument_cache, NULL); - zend_instrument_install_handlers((zend_function *) op_array); + zend_instrument_fcall_install((zend_function *)op_array); } EX(run_time_cache) = RUN_TIME_CACHE(op_array); @@ -3591,7 +3591,7 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array * init_func_run_time_cache(op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(op_array->instrument_cache))) { - zend_instrument_install_handlers((zend_function *) op_array); + zend_instrument_fcall_install((zend_function *)op_array); } i_init_func_execute_data(op_array, return_value, 1 EXECUTE_DATA_CC); @@ -3945,7 +3945,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } else { if (ZSTR_VAL(function)[0] == '\\') { @@ -3966,7 +3966,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } called_scope = NULL; } @@ -4013,7 +4013,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zend_o init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } return zend_vm_stack_push_call_frame(call_info, @@ -4101,7 +4101,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } return zend_vm_stack_push_call_frame(call_info, diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index f486174b7bbea..e1d62000e69c1 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -41,14 +41,13 @@ ZEND_API void zend_init_code_execute_data(zend_execute_data *execute_data, zend_ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value); ZEND_API void execute_ex(zend_execute_data *execute_data); -ZEND_API inline void execute_internal(zend_execute_data *execute_data, zval *return_value) -{ - zend_instrument_cache *cache = (zend_instrument_cache *) +ZEND_API inline void execute_internal(zend_execute_data *execute_data, zval *return_value) { + zend_instrument_fcall_cache *cache = (zend_instrument_fcall_cache *) ZEND_MAP_PTR_GET(execute_data->func->common.instrument_cache); - if (UNEXPECTED(cache != ZEND_NOT_INSTRUMENTED)) { - zend_instrument_call_begin_handlers(execute_data, cache); + if (UNEXPECTED(cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED)) { + zend_instrument_fcall_call_begin(cache, execute_data); execute_data->func->internal_function.handler(execute_data, return_value); - zend_instrument_call_end_handlers(execute_data, cache); + zend_instrument_fcall_call_end(cache, execute_data, return_value); } else { execute_data->func->internal_function.handler(execute_data, return_value); } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 229f1462bebde..e2b7e067ed0df 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -797,9 +797,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / const zend_op *current_opline_before_exception = EG(opline_before_exception); zend_init_func_execute_data(call, &func->op_array, fci->retval); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } zend_execute_ex(call); EG(opline_before_exception) = current_opline_before_exception; @@ -813,7 +813,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / ZEND_ASSERT(func->type == ZEND_INTERNAL_FUNCTION); if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { - zend_instrument_install_handlers(func); + zend_instrument_fcall_install(func); } ZVAL_NULL(fci->retval); diff --git a/Zend/zend_instrument.c b/Zend/zend_instrument.c index 600891fe8aa44..2bf38d87ffd0e 100644 --- a/Zend/zend_instrument.c +++ b/Zend/zend_instrument.c @@ -21,59 +21,61 @@ #include "zend_API.h" #include "zend_instrument.h" -struct zend_instruments_list { - struct zend_instruments_list *prev; - zend_instrument instrument; +struct zend_instrument_fcall_init_list { + struct zend_instrument_fcall_init_list *prev; + zend_instrument_fcall_init instrument; }; -typedef struct zend_instruments_list zend_instruments_list; +typedef struct zend_instrument_fcall_init_list zend_instrument_fcall_init_list; -static zend_instruments_list *_zend_instruments; +static zend_instrument_fcall_init_list *zend_instrument_fcalls; -ZEND_API void zend_instrument_init(void) -{ - _zend_instruments = NULL; +ZEND_API void zend_instrument_init(void) { + zend_instrument_fcalls = NULL; } -ZEND_API void zend_instrument_shutdown(void) -{ - zend_instruments_list *curr, *prev; - for (curr = _zend_instruments; curr; curr = prev) { +ZEND_API void zend_instrument_shutdown(void) { + zend_instrument_fcall_init_list *curr, *prev; + for (curr = zend_instrument_fcalls; curr; curr = prev) { prev = curr->prev; free(curr); } } -ZEND_API void zend_instrument_register(zend_instrument instrument) -{ - zend_instruments_list *node = malloc(sizeof(zend_instruments_list)); - node->instrument = instrument; - node->prev = _zend_instruments; - _zend_instruments = node; +ZEND_API void zend_instrument_fcall_register(zend_instrument_fcall_init cb) { + zend_instrument_fcall_init_list *node = + malloc(sizeof(zend_instrument_fcall_init_list)); + node->instrument = cb; + node->prev = zend_instrument_fcalls; + zend_instrument_fcalls = node; } -struct zend_instrument_handlers_list { - struct zend_instrument_handlers_list *prev; - zend_instrument_handlers handlers; +struct zend_instrument_fcall_list { + struct zend_instrument_fcall_list *prev; + zend_instrument_fcall handlers; size_t count; }; -typedef struct zend_instrument_handlers_list zend_instrument_handlers_list; +typedef struct zend_instrument_fcall_list zend_instrument_fcall_list; -extern inline void zend_instrument_call_begin_handlers( - zend_execute_data *execute_data, zend_instrument_cache *cache); -extern inline void zend_instrument_call_end_handlers( - zend_execute_data *execute_data, zend_instrument_cache *cache); +extern inline void zend_instrument_fcall_call_begin( + zend_instrument_fcall_cache *cache, + zend_execute_data *execute_data); -static zend_instrument_handlers_list *_instrument_add( - zend_instrument_handlers_list *instruments, - zend_instrument_handlers handlers) +extern inline void zend_instrument_fcall_call_end( + zend_instrument_fcall_cache *cache, + zend_execute_data *execute_data, + zval *return_value); + +static zend_instrument_fcall_list *zend_instrument_fcall_add( + zend_instrument_fcall_list *instruments, + zend_instrument_fcall handlers) { if (!handlers.begin && !handlers.end) { return instruments; } - zend_instrument_handlers_list *n = - emalloc(sizeof(zend_instrument_handlers_list)); + zend_instrument_fcall_list *n = + emalloc(sizeof(zend_instrument_fcall_list)); if (instruments) { n->prev = instruments; n->count = instruments->count + 1; @@ -85,18 +87,18 @@ static zend_instrument_handlers_list *_instrument_add( return n; } -static zend_instrument_cache *_instrument_attach_handler( +static zend_instrument_fcall_cache *zend_instrument_fcall_list_attach( zend_function *function, - zend_instrument_handlers_list *handlers_list) + zend_instrument_fcall_list *handlers_list) { - zend_instrument_cache *cache = - malloc(sizeof(zend_instrument_cache)); + zend_instrument_fcall_cache *cache = + malloc(sizeof(zend_instrument_fcall_cache)); cache->instruments_len = handlers_list->count; cache->handlers = - calloc(handlers_list->count, sizeof(zend_instrument_handlers)); + calloc(handlers_list->count, sizeof(zend_instrument_fcall)); - zend_instrument_handlers *handlers = cache->handlers; - zend_instrument_handlers_list *curr; + zend_instrument_fcall *handlers = cache->handlers; + zend_instrument_fcall_list *curr; for (curr = handlers_list; curr; curr = curr->prev) { *handlers++ = curr->handlers; } @@ -106,26 +108,26 @@ static zend_instrument_cache *_instrument_attach_handler( return cache; } -ZEND_API void zend_instrument_install_handlers(zend_function *function) -{ - zend_instrument_handlers_list *handlers_list = NULL; - zend_instruments_list *elem; +ZEND_API void zend_instrument_fcall_install(zend_function *function) { + zend_instrument_fcall_list *fcall_list = NULL; + zend_instrument_fcall_init_list *elem; - for (elem = _zend_instruments; elem; elem = elem->prev) { - zend_instrument_handlers handlers = elem->instrument(function); - handlers_list = _instrument_add(handlers_list, handlers); + for (elem = zend_instrument_fcalls; elem; elem = elem->prev) { + zend_instrument_fcall handlers = elem->instrument(function); + fcall_list = zend_instrument_fcall_add(fcall_list, handlers); } - if (handlers_list) { - _instrument_attach_handler(function, handlers_list); + if (fcall_list) { + zend_instrument_fcall_list_attach(function, fcall_list); - // cleanup handlers_list - zend_instrument_handlers_list *curr, *prev; - for (curr = handlers_list; curr; curr = prev) { + // cleanup fcall_list + zend_instrument_fcall_list *curr, *prev; + for (curr = fcall_list; curr; curr = prev) { prev = curr->prev; efree(curr); } } else { - ZEND_MAP_PTR_SET(function->common.instrument_cache, ZEND_NOT_INSTRUMENTED); + ZEND_MAP_PTR_SET(function->common.instrument_cache, + ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED); } } diff --git a/Zend/zend_instrument.h b/Zend/zend_instrument.h index 5b819f3b23292..9795a91800f02 100644 --- a/Zend/zend_instrument.h +++ b/Zend/zend_instrument.h @@ -22,45 +22,43 @@ BEGIN_EXTERN_C() -typedef void (*zend_instrument_begin_handler)(zend_execute_data *ex); -typedef void (*zend_instrument_end_handler)(zend_execute_data *ex/*, zval *return_value*/); - -struct zend_instrument_handlers { - zend_instrument_begin_handler begin; +struct zend_instrument_fcall { + void (*begin)(zend_execute_data *execute_data); /* todo: need to figure out how to tell end that it is exiting normally * or not; checking for EG(exception) is not enough (unclean shutdown). */ - zend_instrument_end_handler end; + void (*end)(zend_execute_data* execute_data, zval *return_value); }; -typedef struct zend_instrument_handlers zend_instrument_handlers; +typedef struct zend_instrument_fcall zend_instrument_fcall; -struct zend_instrument_cache { +struct zend_instrument_fcall_cache { // todo: use arena size_t instruments_len; - zend_instrument_handlers *handlers; + zend_instrument_fcall *handlers; }; -typedef struct zend_instrument_cache zend_instrument_cache; +typedef struct zend_instrument_fcall_cache zend_instrument_fcall_cache; /* If the fn should not be instrumented then return {NULL, NULL} */ -typedef zend_instrument_handlers (*zend_instrument)(zend_function *func); +typedef zend_instrument_fcall (*zend_instrument_fcall_init)(zend_function *func); -#define ZEND_NOT_INSTRUMENTED ((void *) 1) +#define ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED ((void *) 1) // Call during minit/startup ONLY -ZEND_API void zend_instrument_register(zend_instrument cb); +ZEND_API void zend_instrument_fcall_register(zend_instrument_fcall_init cb); // Called by engine before MINITs ZEND_API void zend_instrument_init(void); ZEND_API void zend_instrument_shutdown(void); -ZEND_API void zend_instrument_install_handlers(zend_function *function); +ZEND_API void zend_instrument_fcall_install(zend_function *function); -inline void zend_instrument_call_begin_handlers( - zend_execute_data *execute_data, zend_instrument_cache *cache) +inline void zend_instrument_fcall_call_begin( + zend_instrument_fcall_cache *cache, + zend_execute_data *execute_data) { - zend_instrument_handlers *handler; - zend_instrument_handlers *stop = + zend_instrument_fcall *handler; + zend_instrument_fcall *stop = cache->handlers + cache->instruments_len; for (handler = cache->handlers; handler != stop; ++handler) { @@ -70,18 +68,20 @@ inline void zend_instrument_call_begin_handlers( } } -inline void zend_instrument_call_end_handlers( - zend_execute_data *execute_data, zend_instrument_cache *cache) +inline void zend_instrument_fcall_call_end( + zend_instrument_fcall_cache *cache, + zend_execute_data *execute_data, + zval *return_value) { - zend_instrument_handlers *handler = + zend_instrument_fcall *handler = cache->handlers + cache->instruments_len; - zend_instrument_handlers *stop = cache->handlers; + zend_instrument_fcall *stop = cache->handlers; // todo: send return_value to end, maybe protected via zval copy // todo: decide if this should run in reverse order or not while (handler-- != stop) { if (handler->end) { - handler->end(execute_data); + handler->end(execute_data, return_value); } } } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 3fa56e6558737..e5e61d0ad4831 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1204,7 +1204,8 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend * The low bit must be zero, to not be interpreted as a MAP_PTR offset. */ static const void *dummy = (void*)(intptr_t)2; - static const zend_instrument_cache *dummy_handlers = ZEND_NOT_INSTRUMENTED; + static const zend_instrument_fcall_cache *dummy_handlers = + ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; ZEND_ASSERT(fbc); @@ -1224,7 +1225,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend } func->opcodes = &EG(call_trampoline_op); ZEND_MAP_PTR_INIT(func->run_time_cache, (void***)&dummy); - ZEND_MAP_PTR_INIT(func->instrument_cache, (zend_instrument_cache **) &dummy_handlers); + ZEND_MAP_PTR_INIT(func->instrument_cache, (zend_instrument_fcall_cache **) &dummy_handlers); func->scope = fbc->common.scope; /* reserve space for arguments, local and temporary variables */ func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, 2) : 2; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 82114224d330f..ae1cad7ecaf94 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3469,7 +3469,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -3596,7 +3596,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (OP2_TYPE != IS_CONST) { FREE_OP2(); @@ -3615,7 +3615,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -3668,7 +3668,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } CACHE_PTR(opline->result.num, fbc); } @@ -3783,7 +3783,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM) init_func_run_time_cache(&func->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { - zend_instrument_install_handlers(func); + zend_instrument_fcall_install(func); } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); @@ -3823,7 +3823,7 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } CACHE_PTR(opline->result.num, fbc); } @@ -3856,7 +3856,7 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT) init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } CACHE_PTR(opline->result.num, fbc); } @@ -3940,9 +3940,10 @@ ZEND_VM_HOT_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL)) execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } LOAD_OPLINE_EX(); @@ -3970,9 +3971,10 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL)) execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } LOAD_OPLINE_EX(); @@ -4057,9 +4059,10 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL)) execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } if (EXPECTED(zend_execute_ex == execute_ex)) { @@ -4270,9 +4273,10 @@ ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY) if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -5381,14 +5385,14 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); - static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; - ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); + static const zend_instrument_fcall_cache *dummy_handler = ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_fcall_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { - zend_instrument_install_handlers(constructor); + zend_instrument_fcall_install(constructor); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( @@ -7371,9 +7375,12 @@ ZEND_VM_HELPER(zend_dispatch_try_catch_finally_helper, ANY, ANY, uint32_t try_ca if (execute_data->func) { zend_function *func = execute_data->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(execute_data, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zval undef; + ZVAL_UNDEF(&undef); + zend_instrument_fcall_call_end(cache, execute_data, &undef); } } @@ -8168,7 +8175,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY) init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index bd4b9d2c95b13..3a133bbbc9d20 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1333,9 +1333,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } LOAD_OPLINE_EX(); @@ -1362,9 +1363,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETV execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } LOAD_OPLINE_EX(); @@ -1392,9 +1394,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } LOAD_OPLINE_EX(); @@ -1479,9 +1482,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } LOAD_OPLINE_EX(); @@ -1566,9 +1570,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } if (EXPECTED(zend_execute_ex == execute_ex)) { @@ -1669,9 +1674,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETV execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(fbc->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_begin_handlers(call, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(fbc->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_begin(cache, call); } if (EXPECTED(zend_execute_ex == execute_ex)) { @@ -2557,9 +2563,12 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try if (execute_data->func) { zend_function *func = execute_data->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(execute_data, cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zval undef; + ZVAL_UNDEF(&undef); + zend_instrument_fcall_call_end(cache, execute_data, &undef); } } @@ -2790,7 +2799,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } execute_data = call; i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); @@ -2909,7 +2918,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } CACHE_PTR(opline->result.num, fbc); } @@ -2998,7 +3007,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } CACHE_PTR(opline->result.num, fbc); } @@ -3031,7 +3040,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } CACHE_PTR(opline->result.num, fbc); } @@ -3580,9 +3589,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_ if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -5744,7 +5754,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -5870,7 +5880,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_CONST != IS_CONST) { @@ -5889,7 +5899,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -5970,7 +5980,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS init_func_run_time_cache(&func->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { - zend_instrument_install_handlers(func); + zend_instrument_fcall_install(func); } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); @@ -7931,7 +7941,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -8057,7 +8067,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -8076,7 +8086,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -8158,7 +8168,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV init_func_run_time_cache(&func->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { - zend_instrument_install_handlers(func); + zend_instrument_fcall_install(func); } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); @@ -8809,7 +8819,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_UNUSED != IS_CONST) { @@ -8828,7 +8838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -8973,14 +8983,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER( call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); - static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; - ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); + static const zend_instrument_fcall_cache *dummy_handler = ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_fcall_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { - zend_instrument_install_handlers(constructor); + zend_instrument_fcall_install(constructor); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( @@ -10210,7 +10220,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -10336,7 +10346,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_CV != IS_CONST) { @@ -10355,7 +10365,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -10436,7 +10446,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H init_func_run_time_cache(&func->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(func->common.instrument_cache))) { - zend_instrument_install_handlers(func); + zend_instrument_fcall_install(func); } } else { zend_type_error("%s(): Argument #1 ($function) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); @@ -14512,7 +14522,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -15896,7 +15906,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -17174,7 +17184,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -17499,9 +17509,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HA if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -19930,9 +19941,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HA if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -22854,7 +22866,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_CONST != IS_CONST) { @@ -22873,7 +22885,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -25090,7 +25102,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -25109,7 +25121,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -26368,7 +26380,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_UNUSED != IS_CONST) { @@ -26387,7 +26399,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -26532,14 +26544,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZE call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); - static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; - ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); + static const zend_instrument_fcall_cache *dummy_handler = ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_fcall_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { - zend_instrument_install_handlers(constructor); + zend_instrument_fcall_install(constructor); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( @@ -28632,7 +28644,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_CV != IS_CONST) { @@ -28651,7 +28663,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -30700,7 +30712,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -30826,7 +30838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_CONST != IS_CONST) { @@ -30845,7 +30857,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -32577,7 +32589,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -32703,7 +32715,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -32722,7 +32734,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -33125,7 +33137,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_UNUSED != IS_CONST) { @@ -33144,7 +33156,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -33289,14 +33301,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER call = zend_vm_stack_push_call_frame( ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, opline->extended_value, NULL); - static const zend_instrument_cache *dummy_handler = ZEND_NOT_INSTRUMENTED; - ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_cache **) &dummy_handler); + static const zend_instrument_fcall_cache *dummy_handler = ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED; + ZEND_MAP_PTR_INIT(call->func->common.instrument_cache, (zend_instrument_fcall_cache **) &dummy_handler); } else { if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { init_func_run_time_cache(&constructor->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(constructor->common.instrument_cache))) { - zend_instrument_install_handlers(constructor); + zend_instrument_fcall_install(constructor); } /* We are not handling overloaded classes right now */ call = zend_vm_stack_push_call_frame( @@ -34991,7 +35003,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -35117,7 +35129,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } if (IS_CV != IS_CONST) { @@ -35136,7 +35148,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -35939,9 +35951,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HAN if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -39857,7 +39870,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -43297,7 +43310,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -48182,7 +48195,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA init_func_run_time_cache(&fbc->op_array); } if (UNEXPECTED(!ZEND_MAP_PTR_GET(fbc->common.instrument_cache))) { - zend_instrument_install_handlers(fbc); + zend_instrument_fcall_install(fbc); } } @@ -52522,9 +52535,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -54016,9 +54030,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -54302,9 +54317,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } @@ -55376,9 +55392,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) if (EG(current_execute_data)->func) { zend_function *func = EG(current_execute_data)->func; - zend_instrument_cache *cache = ZEND_MAP_PTR_GET(func->common.instrument_cache); - if (cache != ZEND_NOT_INSTRUMENTED) { - zend_instrument_call_end_handlers(EG(current_execute_data), cache); + zend_instrument_fcall_cache *cache = + ZEND_MAP_PTR_GET(func->common.instrument_cache); + if (cache != ZEND_INSTRUMENT_FCALL_NOT_INSTRUMENTED) { + zend_instrument_fcall_call_end(cache, EG(current_execute_data), return_value); } } From 7071dfef14546a1062a5dbe0b2efddf0c70e3ccc Mon Sep 17 00:00:00 2001 From: Levi Morrison Date: Sun, 17 May 2020 10:49:12 -0600 Subject: [PATCH 3/3] Add instrument API to Windows build --- win32/build/config.w32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 62dbeb40d9b08..5f3b7b2b308ce 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -236,7 +236,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \ zend_object_handlers.c zend_objects_API.c \ zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \ zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \ - zend_inheritance.c zend_smart_str.c zend_cpuinfo.c"); + zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_instrument.c"); ADD_FLAG("CFLAGS_BD_ZEND", "/D ZEND_ENABLE_STATIC_TSRMLS_CACHE=1"); if (VS_TOOLSET && VCVERS >= 1914) {