mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Introduce zend_vm_opcode_handler_t / zend_vm_opcode_handler_func_t
This reduces the chances of confusion between opcode handlers used by the VM, and opcode handler functions used for tracing or debugging. Depending on the VM, zend_vm_opcode_handler_t may not be a function. For instance in the HYBRID VM this is a label pointer. Closes GH-19006
This commit is contained in:
parent
747ecce51f
commit
7f7b3cdb90
10 changed files with 130 additions and 99 deletions
|
@ -24,6 +24,7 @@
|
|||
#include "zend_types.h"
|
||||
#include "zend_map_ptr.h"
|
||||
#include "zend_alloc.h"
|
||||
#include "zend_vm_opcodes.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
|
@ -135,7 +136,7 @@ void zend_const_expr_to_zval(zval *result, zend_ast **ast_ptr, bool allow_dynami
|
|||
typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data);
|
||||
|
||||
struct _zend_op {
|
||||
const void *handler;
|
||||
zend_vm_opcode_handler_t handler;
|
||||
znode_op op1;
|
||||
znode_op op2;
|
||||
znode_op result;
|
||||
|
|
22
Zend/zend_vm_execute.h
generated
22
Zend/zend_vm_execute.h
generated
|
@ -321,14 +321,14 @@ static uint8_t zend_user_opcodes[256] = {0,
|
|||
#define SPEC_RULE_OBSERVER 0x02000000
|
||||
|
||||
static const uint32_t *zend_spec_handlers;
|
||||
static const void * const *zend_opcode_handlers;
|
||||
static zend_vm_opcode_handler_t const *zend_opcode_handlers;
|
||||
static int zend_handlers_count;
|
||||
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
|
||||
static const void * const * zend_opcode_handler_funcs;
|
||||
static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;
|
||||
static zend_op hybrid_halt_op;
|
||||
#endif
|
||||
#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC
|
||||
static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);
|
||||
static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);
|
||||
#endif
|
||||
|
||||
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
|
||||
|
@ -58666,8 +58666,8 @@ ZEND_API void execute_ex(zend_execute_data *ex)
|
|||
(void*)&&ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_LABEL,
|
||||
(void*)&&ZEND_NULL_LABEL
|
||||
};
|
||||
zend_opcode_handlers = (const void **) labels;
|
||||
zend_handlers_count = sizeof(labels) / sizeof(void*);
|
||||
zend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;
|
||||
zend_handlers_count = sizeof(labels) / sizeof(labels[0]);
|
||||
memset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));
|
||||
hybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;
|
||||
#ifdef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
|
||||
|
@ -64398,7 +64398,11 @@ ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value)
|
|||
|
||||
void zend_vm_init(void)
|
||||
{
|
||||
static const void * const labels[] = {
|
||||
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
|
||||
static zend_vm_opcode_handler_func_t const labels[] = {
|
||||
#else
|
||||
static zend_vm_opcode_handler_t const labels[] = {
|
||||
#endif
|
||||
ZEND_NOP_SPEC_HANDLER,
|
||||
ZEND_ADD_SPEC_CONST_CONST_HANDLER,
|
||||
ZEND_ADD_SPEC_CONST_TMPVARCV_HANDLER,
|
||||
|
@ -68158,7 +68162,7 @@ void zend_vm_init(void)
|
|||
execute_ex(NULL);
|
||||
#else
|
||||
zend_opcode_handlers = labels;
|
||||
zend_handlers_count = sizeof(labels) / sizeof(void*);
|
||||
zend_handlers_count = sizeof(labels) / sizeof(labels[0]);
|
||||
zend_spec_handlers = specs;
|
||||
#endif
|
||||
VM_TRACE_START();
|
||||
|
@ -68200,7 +68204,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
|
|||
}
|
||||
zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
|
||||
ZEND_ASSERT(zv != NULL);
|
||||
op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv);
|
||||
op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
|
||||
}
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)
|
||||
|
@ -68286,7 +68290,7 @@ static uint32_t ZEND_FASTCALL zend_vm_get_opcode_handler_idx(uint32_t spec, cons
|
|||
}
|
||||
|
||||
#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC
|
||||
static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)
|
||||
static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)
|
||||
{
|
||||
return zend_opcode_handlers[zend_vm_get_opcode_handler_idx(zend_spec_handlers[opcode], op)];
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
|
|||
}
|
||||
zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
|
||||
ZEND_ASSERT(zv != NULL);
|
||||
op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv);
|
||||
op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
|
||||
}
|
||||
|
||||
ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)
|
||||
|
|
|
@ -1186,7 +1186,7 @@ function gen_null_label($f, $kind, $prolog) {
|
|||
out($f,$prolog."ZEND_NULL_HANDLER,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,$prolog."(void*)(uintptr_t)-1,\n");
|
||||
out($f,$prolog."-1,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_GOTO:
|
||||
out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
|
||||
|
@ -1388,7 +1388,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
|||
out($f,"$prolog{$spec_name}_HANDLER,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,$prolog."(void*)(uintptr_t)$switch_labels[$spec_name],\n");
|
||||
out($f,$prolog."$switch_labels[$spec_name],\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_GOTO:
|
||||
out($f,$prolog."(void*)&&{$spec_name}_LABEL,\n");
|
||||
|
@ -1436,7 +1436,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
|||
out($f,$prolog."ZEND_NULL_HANDLER,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,$prolog."(void*)(uintptr_t)-1,\n");
|
||||
out($f,$prolog."-1,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_GOTO:
|
||||
out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
|
||||
|
@ -1467,7 +1467,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
|||
out($f,$prolog.$dsc["op"]."_HANDLER,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,$prolog."(void*)(uintptr_t)".((string)$num).",\n");
|
||||
out($f,$prolog.((string)$num).",\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_GOTO:
|
||||
out($f,$prolog."(void*)&&".$dsc["op"]."_LABEL,\n");
|
||||
|
@ -1480,7 +1480,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
|||
out($f,$prolog."ZEND_NULL_HANDLER,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,$prolog."(void*)(uintptr_t)-1,\n");
|
||||
out($f,$prolog."-1,\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_GOTO:
|
||||
out($f,$prolog."(void*)&&ZEND_NULL_LABEL,\n");
|
||||
|
@ -1497,7 +1497,7 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
|||
out($f,$prolog."ZEND_NULL_HANDLER\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_SWITCH:
|
||||
out($f,$prolog."(void*)(uintptr_t)-1\n");
|
||||
out($f,$prolog."-1\n");
|
||||
break;
|
||||
case ZEND_VM_KIND_GOTO:
|
||||
out($f,$prolog."(void*)&&ZEND_NULL_LABEL\n");
|
||||
|
@ -1813,16 +1813,16 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
|||
out($f,"#define SPEC_RULE_OBSERVER 0x02000000\n");
|
||||
out($f,"\n");
|
||||
out($f,"static const uint32_t *zend_spec_handlers;\n");
|
||||
out($f,"static const void * const *zend_opcode_handlers;\n");
|
||||
out($f,"static zend_vm_opcode_handler_t const *zend_opcode_handlers;\n");
|
||||
out($f,"static int zend_handlers_count;\n");
|
||||
if ($kind == ZEND_VM_KIND_HYBRID) {
|
||||
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
|
||||
out($f,"static const void * const * zend_opcode_handler_funcs;\n");
|
||||
out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
|
||||
out($f,"static zend_op hybrid_halt_op;\n");
|
||||
out($f,"#endif\n");
|
||||
}
|
||||
out($f,"#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
|
||||
out($f,"static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
|
||||
out($f,"static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op);\n");
|
||||
out($f,"#endif\n\n");
|
||||
if ($kind == ZEND_VM_KIND_HYBRID) {
|
||||
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
|
||||
|
@ -2040,7 +2040,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
|||
break;
|
||||
case "HELPER_VARS":
|
||||
if ($kind == ZEND_VM_KIND_SWITCH) {
|
||||
out($f,$m[1]."const void *dispatch_handler;\n");
|
||||
out($f,$m[1]."zend_vm_opcode_handler_t dispatch_handler;\n");
|
||||
}
|
||||
if ($kind != ZEND_VM_KIND_CALL && count($params)) {
|
||||
if ($kind == ZEND_VM_KIND_HYBRID) {
|
||||
|
@ -2097,8 +2097,8 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
|||
out($f,$prolog."\tstatic const void * const labels[] = {\n");
|
||||
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
|
||||
out($f,$prolog."\t};\n");
|
||||
out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
|
||||
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
|
||||
out($f,$prolog."\tzend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;\n");
|
||||
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n");
|
||||
if ($kind == ZEND_VM_KIND_HYBRID) {
|
||||
out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n");
|
||||
out($f,$prolog."\thybrid_halt_op.handler = (void*)&&HYBRID_HALT_LABEL;\n");
|
||||
|
@ -2212,7 +2212,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
|||
out($f,$prolog."zend_spec_handlers = specs;\n");
|
||||
out($f,$prolog.$executor_name."_ex(NULL);\n");
|
||||
} else {
|
||||
out($f,$prolog."static const void * const labels[] = {\n");
|
||||
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
|
||||
out($f,$prolog."static zend_vm_opcode_handler_func_t const labels[] = {\n");
|
||||
out($f,"#else\n");
|
||||
out($f,$prolog."static zend_vm_opcode_handler_t const labels[] = {\n");
|
||||
out($f,"#endif\n");
|
||||
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
|
||||
out($f,$prolog."};\n");
|
||||
out($f,$prolog."static const uint32_t specs[] = {\n");
|
||||
|
@ -2226,7 +2230,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
|
|||
out($f,"#else\n");
|
||||
}
|
||||
out($f,$prolog."zend_opcode_handlers = labels;\n");
|
||||
out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(void*);\n");
|
||||
out($f,$prolog."zend_handlers_count = sizeof(labels) / sizeof(labels[0]);\n");
|
||||
out($f,$prolog."zend_spec_handlers = specs;\n");
|
||||
if ($kind == ZEND_VM_KIND_HYBRID) {
|
||||
out($f,"#endif\n");
|
||||
|
@ -2359,6 +2363,20 @@ function gen_vm_opcodes_header(
|
|||
$str .= "# endif\n";
|
||||
$str .= "#endif\n";
|
||||
$str .= "\n";
|
||||
$str .= "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n";
|
||||
$str .= "typedef const void* zend_vm_opcode_handler_t;\n";
|
||||
$str .= "typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void);\n";
|
||||
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL\n";
|
||||
$str .= "typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);\n";
|
||||
$str .= "typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);\n";
|
||||
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH\n";
|
||||
$str .= "typedef int zend_vm_opcode_handler_t;\n";
|
||||
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO\n";
|
||||
$str .= "typedef const void* zend_vm_opcode_handler_t;\n";
|
||||
$str .= "#else\n";
|
||||
$str .= "# error\n";
|
||||
$str .= "#endif\n";
|
||||
$str .= "\n";
|
||||
foreach ($vm_op_flags as $name => $val) {
|
||||
$str .= sprintf("#define %-24s 0x%08x\n", $name, $val);
|
||||
}
|
||||
|
@ -2840,7 +2858,7 @@ function gen_vm($def, $skel) {
|
|||
}
|
||||
out($f, "}\n\n");
|
||||
out($f, "#if (ZEND_VM_KIND != ZEND_VM_KIND_HYBRID) || !ZEND_VM_SPEC\n");
|
||||
out($f, "static const void *zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
|
||||
out($f, "static zend_vm_opcode_handler_t zend_vm_get_opcode_handler(uint8_t opcode, const zend_op* op)\n");
|
||||
out($f, "{\n");
|
||||
if (!ZEND_VM_SPEC) {
|
||||
out($f, "\treturn zend_opcode_handlers[zend_vm_get_opcode_handler_idx(opcode, op)];\n");
|
||||
|
|
14
Zend/zend_vm_opcodes.h
generated
14
Zend/zend_vm_opcodes.h
generated
|
@ -42,6 +42,20 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
|
||||
typedef const void* zend_vm_opcode_handler_t;
|
||||
typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void);
|
||||
#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL
|
||||
typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
|
||||
typedef const struct _zend_op *(ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(struct _zend_execute_data *execute_data, const struct _zend_op *opline);
|
||||
#elif ZEND_VM_KIND == ZEND_VM_KIND_SWITCH
|
||||
typedef int zend_vm_opcode_handler_t;
|
||||
#elif ZEND_VM_KIND == ZEND_VM_KIND_GOTO
|
||||
typedef const void* zend_vm_opcode_handler_t;
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
#define ZEND_VM_OP_SPEC 0x00000001
|
||||
#define ZEND_VM_OP_CONST 0x00000002
|
||||
#define ZEND_VM_OP_TMPVAR 0x00000004
|
||||
|
|
|
@ -90,13 +90,13 @@ static size_t dasm_size = 0;
|
|||
|
||||
static zend_long jit_bisect_pos = 0;
|
||||
|
||||
static const void *zend_jit_runtime_jit_handler = NULL;
|
||||
static const void *zend_jit_profile_jit_handler = NULL;
|
||||
static const void *zend_jit_func_hot_counter_handler = NULL;
|
||||
static const void *zend_jit_loop_hot_counter_handler = NULL;
|
||||
static const void *zend_jit_func_trace_counter_handler = NULL;
|
||||
static const void *zend_jit_ret_trace_counter_handler = NULL;
|
||||
static const void *zend_jit_loop_trace_counter_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_runtime_jit_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_profile_jit_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_func_hot_counter_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_loop_hot_counter_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_func_trace_counter_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_ret_trace_counter_handler = NULL;
|
||||
static zend_vm_opcode_handler_t zend_jit_loop_trace_counter_handler = NULL;
|
||||
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS);
|
||||
|
||||
|
@ -1417,7 +1417,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
|
|||
zend_jit_ctx ctx;
|
||||
zend_jit_ctx *jit = &ctx;
|
||||
zend_jit_reg_var *ra = NULL;
|
||||
void *handler;
|
||||
zend_vm_opcode_handler_t handler;
|
||||
int call_level = 0;
|
||||
void *checkpoint = NULL;
|
||||
bool recv_emitted = 0; /* emitted at least one RECV opcode */
|
||||
|
@ -3213,7 +3213,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf
|
|||
}
|
||||
}
|
||||
|
||||
opline->handler = (const void*)zend_jit_func_hot_counter_handler;
|
||||
opline->handler = zend_jit_func_hot_counter_handler;
|
||||
}
|
||||
|
||||
if (JIT_G(hot_loop)) {
|
||||
|
@ -3223,7 +3223,7 @@ static void zend_jit_setup_hot_counters_ex(zend_op_array *op_array, zend_cfg *cf
|
|||
if ((cfg->blocks[i].flags & ZEND_BB_REACHABLE) &&
|
||||
(cfg->blocks[i].flags & ZEND_BB_LOOP_HEADER)) {
|
||||
op_array->opcodes[cfg->blocks[i].start].handler =
|
||||
(const void*)zend_jit_loop_hot_counter_handler;
|
||||
zend_jit_loop_hot_counter_handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3316,7 +3316,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
|
|||
jit_extension->op_array = op_array;
|
||||
jit_extension->orig_handler = (void*)opline->handler;
|
||||
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
|
||||
opline->handler = (const void*)zend_jit_runtime_jit_handler;
|
||||
opline->handler = zend_jit_runtime_jit_handler;
|
||||
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
|
||||
|
||||
return SUCCESS;
|
||||
|
@ -3346,7 +3346,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
|
|||
jit_extension->op_array = op_array;
|
||||
jit_extension->orig_handler = (void*)opline->handler;
|
||||
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
|
||||
opline->handler = (const void*)zend_jit_profile_jit_handler;
|
||||
opline->handler = zend_jit_profile_jit_handler;
|
||||
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
|
||||
}
|
||||
|
||||
|
@ -3566,23 +3566,23 @@ void zend_jit_protect(void)
|
|||
|
||||
static void zend_jit_init_handlers(void)
|
||||
{
|
||||
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
|
||||
zend_jit_runtime_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
|
||||
zend_jit_profile_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
|
||||
zend_jit_func_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
|
||||
zend_jit_loop_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
|
||||
zend_jit_func_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
|
||||
zend_jit_ret_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
|
||||
zend_jit_loop_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
|
||||
} else {
|
||||
zend_jit_runtime_jit_handler = (const void*)zend_runtime_jit;
|
||||
zend_jit_profile_jit_handler = (const void*)zend_jit_profile_helper;
|
||||
zend_jit_func_hot_counter_handler = (const void*)zend_jit_func_counter_helper;
|
||||
zend_jit_loop_hot_counter_handler = (const void*)zend_jit_loop_counter_helper;
|
||||
zend_jit_func_trace_counter_handler = (const void*)zend_jit_func_trace_helper;
|
||||
zend_jit_ret_trace_counter_handler = (const void*)zend_jit_ret_trace_helper;
|
||||
zend_jit_loop_trace_counter_handler = (const void*)zend_jit_loop_trace_helper;
|
||||
}
|
||||
#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
|
||||
zend_jit_runtime_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
|
||||
zend_jit_profile_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
|
||||
zend_jit_func_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
|
||||
zend_jit_loop_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
|
||||
zend_jit_func_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
|
||||
zend_jit_ret_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
|
||||
zend_jit_loop_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
|
||||
#else
|
||||
zend_jit_runtime_jit_handler = zend_runtime_jit;
|
||||
zend_jit_profile_jit_handler = zend_jit_profile_helper;
|
||||
zend_jit_func_hot_counter_handler = zend_jit_func_counter_helper;
|
||||
zend_jit_loop_hot_counter_handler = zend_jit_loop_counter_helper;
|
||||
zend_jit_func_trace_counter_handler = zend_jit_func_trace_helper;
|
||||
zend_jit_ret_trace_counter_handler = zend_jit_ret_trace_helper;
|
||||
zend_jit_loop_trace_counter_handler = zend_jit_loop_trace_helper;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void zend_jit_globals_ctor(zend_jit_globals *jit_globals)
|
||||
|
@ -3945,9 +3945,9 @@ static void zend_jit_restart_preloaded_op_array(zend_op_array *op_array)
|
|||
}
|
||||
}
|
||||
if (func_info->flags & ZEND_FUNC_JIT_ON_FIRST_EXEC) {
|
||||
opline->handler = (const void*)zend_jit_runtime_jit_handler;
|
||||
opline->handler = zend_jit_runtime_jit_handler;
|
||||
} else {
|
||||
opline->handler = (const void*)zend_jit_profile_jit_handler;
|
||||
opline->handler = zend_jit_profile_jit_handler;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "Zend/zend_constants.h"
|
||||
#include "Zend/Optimizer/zend_func_info.h"
|
||||
#include "Zend/Optimizer/zend_call_graph.h"
|
||||
#include "zend_vm_opcodes.h"
|
||||
|
||||
/* Address Encoding */
|
||||
typedef uintptr_t zend_jit_addr;
|
||||
|
@ -130,7 +131,7 @@ static zend_always_inline bool zend_jit_same_addr(zend_jit_addr addr1, zend_jit_
|
|||
typedef struct _zend_jit_op_array_extension {
|
||||
zend_func_info func_info;
|
||||
const zend_op_array *op_array;
|
||||
const void *orig_handler;
|
||||
zend_vm_opcode_handler_t orig_handler;
|
||||
} zend_jit_op_array_extension;
|
||||
|
||||
/* Profiler */
|
||||
|
@ -169,7 +170,7 @@ typedef struct _zend_jit_op_array_hot_extension {
|
|||
zend_func_info func_info;
|
||||
const zend_op_array *op_array;
|
||||
int16_t *counter;
|
||||
const void *orig_handlers[1];
|
||||
zend_vm_opcode_handler_t orig_handlers[1];
|
||||
} zend_jit_op_array_hot_extension;
|
||||
|
||||
#define zend_jit_op_array_hash(op_array) \
|
||||
|
@ -225,9 +226,6 @@ extern const zend_op *zend_jit_halt_op;
|
|||
# define ZEND_VM_ENTER_BIT 1ULL
|
||||
#endif
|
||||
|
||||
/* VM handlers */
|
||||
typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *zend_vm_opcode_handler_t)(ZEND_OPCODE_HANDLER_ARGS);
|
||||
|
||||
/* VM helpers */
|
||||
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info);
|
||||
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info);
|
||||
|
@ -339,8 +337,8 @@ typedef enum _zend_jit_trace_stop {
|
|||
typedef union _zend_op_trace_info {
|
||||
zend_op dummy; /* the size of this structure must be the same as zend_op */
|
||||
struct {
|
||||
const void *orig_handler;
|
||||
const void *call_handler;
|
||||
zend_vm_opcode_handler_t orig_handler;
|
||||
zend_vm_opcode_handler_func_t call_handler;
|
||||
int16_t *counter;
|
||||
uint8_t trace_flags;
|
||||
};
|
||||
|
|
|
@ -1918,15 +1918,13 @@ static void zend_jit_vm_leave(zend_jit_ctx *jit, ir_ref to_opline)
|
|||
|
||||
static int zend_jit_exception_handler_stub(zend_jit_ctx *jit)
|
||||
{
|
||||
const void *handler;
|
||||
|
||||
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
|
||||
handler = zend_get_opcode_handler_func(EG(exception_op));
|
||||
zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(EG(exception_op));
|
||||
|
||||
ir_CALL(IR_VOID, ir_CONST_FUNC(handler));
|
||||
ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit)));
|
||||
} else {
|
||||
handler = EG(exception_op)->handler;
|
||||
zend_vm_opcode_handler_t handler = EG(exception_op)->handler;
|
||||
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler));
|
||||
|
@ -4176,17 +4174,12 @@ static ir_ref zend_jit_continue_entry(zend_jit_ctx *jit, ir_ref src, unsigned in
|
|||
|
||||
static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_throw)
|
||||
{
|
||||
const void *handler;
|
||||
|
||||
zend_jit_set_ip(jit, opline);
|
||||
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
|
||||
handler = zend_get_opcode_handler_func(opline);
|
||||
} else {
|
||||
handler = opline->handler;
|
||||
}
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline);
|
||||
ir_CALL(IR_VOID, ir_CONST_FUNC(handler));
|
||||
} else {
|
||||
zend_vm_opcode_handler_t handler = opline->handler;
|
||||
ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit));
|
||||
jit_STORE_IP(jit, ip);
|
||||
}
|
||||
|
@ -4216,7 +4209,6 @@ static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_th
|
|||
|
||||
static int zend_jit_tail_handler(zend_jit_ctx *jit, const zend_op *opline)
|
||||
{
|
||||
const void *handler;
|
||||
ir_ref ref;
|
||||
zend_basic_block *bb;
|
||||
|
||||
|
@ -4228,16 +4220,16 @@ static int zend_jit_tail_handler(zend_jit_ctx *jit, const zend_op *opline)
|
|||
opline->opcode == ZEND_RETURN) {
|
||||
|
||||
/* Use inlined HYBRID VM handler */
|
||||
handler = opline->handler;
|
||||
zend_vm_opcode_handler_t handler = opline->handler;
|
||||
ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler));
|
||||
} else {
|
||||
handler = zend_get_opcode_handler_func(opline);
|
||||
zend_vm_opcode_handler_func_t handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(opline);
|
||||
ir_CALL(IR_VOID, ir_CONST_FUNC(handler));
|
||||
ref = ir_LOAD_A(jit_IP(jit));
|
||||
ir_TAILCALL(IR_VOID, ref);
|
||||
}
|
||||
} else {
|
||||
handler = opline->handler;
|
||||
zend_vm_opcode_handler_t handler = opline->handler;
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ir_TAILCALL(IR_VOID, ir_CONST_FUNC(handler));
|
||||
} else if ((jit->ssa->cfg.flags & ZEND_FUNC_RECURSIVE_DIRECTLY)
|
||||
|
@ -16741,7 +16733,7 @@ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void *zend_jit_finish(zend_jit_ctx *jit)
|
||||
static zend_vm_opcode_handler_t zend_jit_finish(zend_jit_ctx *jit)
|
||||
{
|
||||
void *entry;
|
||||
size_t size;
|
||||
|
@ -16825,14 +16817,14 @@ static void *zend_jit_finish(zend_jit_ctx *jit)
|
|||
opline++;
|
||||
}
|
||||
}
|
||||
opline->handler = entry;
|
||||
opline->handler = (zend_vm_opcode_handler_t)entry;
|
||||
|
||||
if (jit->ctx.entries_count) {
|
||||
/* For all entries */
|
||||
int i = jit->ctx.entries_count;
|
||||
do {
|
||||
ir_insn *insn = &jit->ctx.ir_base[jit->ctx.entries[--i]];
|
||||
op_array->opcodes[insn->op2].handler = (char*)entry + insn->op3;
|
||||
op_array->opcodes[insn->op2].handler = (zend_vm_opcode_handler_t)((char*)entry + insn->op3);
|
||||
} while (i != 0);
|
||||
}
|
||||
} else {
|
||||
|
@ -16859,7 +16851,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit)
|
|||
zend_string_release(str);
|
||||
}
|
||||
|
||||
return entry;
|
||||
return (zend_vm_opcode_handler_t)entry;
|
||||
}
|
||||
|
||||
static const void *zend_jit_trace_allocate_exit_group(uint32_t n)
|
||||
|
|
|
@ -3409,7 +3409,7 @@ static void zend_jit_trace_setup_ret_counter(const zend_op *opline, size_t offse
|
|||
ZEND_JIT_COUNTER_NUM = (ZEND_JIT_COUNTER_NUM + 1) % ZEND_HOT_COUNTERS_COUNT;
|
||||
}
|
||||
ZEND_OP_TRACE_INFO(next_opline, offset)->trace_flags = ZEND_JIT_TRACE_START_RETURN;
|
||||
next_opline->handler = (const void*)zend_jit_ret_trace_counter_handler;
|
||||
next_opline->handler = zend_jit_ret_trace_counter_handler;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4079,9 +4079,9 @@ static bool zend_jit_trace_may_throw(const zend_op *opline,
|
|||
return zend_may_throw_ex(opline, ssa_op, op_array, ssa, t1, t2);
|
||||
}
|
||||
|
||||
static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num)
|
||||
static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num)
|
||||
{
|
||||
const void *handler = NULL;
|
||||
zend_vm_opcode_handler_t handler = NULL;
|
||||
zend_jit_ctx ctx;
|
||||
zend_jit_ctx *jit = &ctx;
|
||||
zend_jit_reg_var *ra = NULL;
|
||||
|
@ -7392,9 +7392,9 @@ static zend_string *zend_jit_trace_escape_name(uint32_t trace_num, uint32_t exit
|
|||
return buf.s;
|
||||
}
|
||||
|
||||
static const void *zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_num)
|
||||
static zend_vm_opcode_handler_t zend_jit_trace_exit_to_vm(uint32_t trace_num, uint32_t exit_num)
|
||||
{
|
||||
const void *handler = NULL;
|
||||
zend_vm_opcode_handler_t handler = NULL;
|
||||
zend_jit_ctx ctx;
|
||||
zend_string *name;
|
||||
void *checkpoint;
|
||||
|
@ -7458,7 +7458,7 @@ jit_failure:
|
|||
static zend_jit_trace_stop zend_jit_compile_root_trace(zend_jit_trace_rec *trace_buffer, const zend_op *opline, size_t offset)
|
||||
{
|
||||
zend_jit_trace_stop ret;
|
||||
const void *handler;
|
||||
zend_vm_opcode_handler_t handler;
|
||||
uint8_t orig_trigger;
|
||||
zend_jit_trace_info *t = NULL;
|
||||
zend_jit_trace_exit_info exit_info[ZEND_JIT_TRACE_MAX_EXITS];
|
||||
|
@ -8832,11 +8832,11 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf
|
|||
zend_jit_unprotect();
|
||||
|
||||
if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_LOOP) {
|
||||
((zend_op*)(t->opline))->handler = (const void*)zend_jit_loop_trace_counter_handler;
|
||||
((zend_op*)(t->opline))->handler = zend_jit_loop_trace_counter_handler;
|
||||
} else if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_ENTER) {
|
||||
((zend_op*)(t->opline))->handler = (const void*)zend_jit_func_trace_counter_handler;
|
||||
((zend_op*)(t->opline))->handler = zend_jit_func_trace_counter_handler;
|
||||
} else if (ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_START_RETURN) {
|
||||
((zend_op*)(t->opline))->handler = (const void*)zend_jit_ret_trace_counter_handler;
|
||||
((zend_op*)(t->opline))->handler = zend_jit_ret_trace_counter_handler;
|
||||
}
|
||||
ZEND_OP_TRACE_INFO(t->opline, jit_extension->offset)->trace_flags &=
|
||||
ZEND_JIT_TRACE_START_LOOP|ZEND_JIT_TRACE_START_ENTER|ZEND_JIT_TRACE_START_RETURN;
|
||||
|
@ -8889,9 +8889,9 @@ static int zend_jit_restart_hot_trace_counters(zend_op_array *op_array)
|
|||
jit_extension->trace_info[i].trace_flags &=
|
||||
ZEND_JIT_TRACE_START_LOOP | ZEND_JIT_TRACE_START_ENTER | ZEND_JIT_TRACE_UNSUPPORTED;
|
||||
if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_LOOP) {
|
||||
op_array->opcodes[i].handler = (const void*)zend_jit_loop_trace_counter_handler;
|
||||
op_array->opcodes[i].handler = zend_jit_loop_trace_counter_handler;
|
||||
} else if (jit_extension->trace_info[i].trace_flags == ZEND_JIT_TRACE_START_ENTER) {
|
||||
op_array->opcodes[i].handler = (const void*)zend_jit_func_trace_counter_handler;
|
||||
op_array->opcodes[i].handler = zend_jit_func_trace_counter_handler;
|
||||
} else {
|
||||
op_array->opcodes[i].handler = jit_extension->trace_info[i].orig_handler;
|
||||
}
|
||||
|
@ -8917,7 +8917,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array)
|
|||
jit_extension->offset = (char*)jit_extension->trace_info - (char*)op_array->opcodes;
|
||||
for (i = 0; i < op_array->last; i++) {
|
||||
jit_extension->trace_info[i].orig_handler = op_array->opcodes[i].handler;
|
||||
jit_extension->trace_info[i].call_handler = zend_get_opcode_handler_func(&op_array->opcodes[i]);
|
||||
jit_extension->trace_info[i].call_handler = (zend_vm_opcode_handler_func_t)zend_get_opcode_handler_func(&op_array->opcodes[i]);
|
||||
jit_extension->trace_info[i].counter = NULL;
|
||||
jit_extension->trace_info[i].trace_flags =
|
||||
zend_jit_trace_supported(&op_array->opcodes[i]);
|
||||
|
@ -8939,7 +8939,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array)
|
|||
/* loop header */
|
||||
opline = op_array->opcodes + cfg.blocks[i].start;
|
||||
if (!(ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags & ZEND_JIT_TRACE_UNSUPPORTED)) {
|
||||
opline->handler = (const void*)zend_jit_loop_trace_counter_handler;
|
||||
opline->handler = zend_jit_loop_trace_counter_handler;
|
||||
if (!ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter) {
|
||||
ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter =
|
||||
&zend_jit_hot_counters[ZEND_JIT_COUNTER_NUM];
|
||||
|
@ -8964,7 +8964,7 @@ static int zend_jit_setup_hot_trace_counters(zend_op_array *op_array)
|
|||
|
||||
if (!ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->trace_flags) {
|
||||
/* function entry */
|
||||
opline->handler = (const void*)zend_jit_func_trace_counter_handler;
|
||||
opline->handler = zend_jit_func_trace_counter_handler;
|
||||
ZEND_OP_TRACE_INFO(opline, jit_extension->offset)->counter =
|
||||
&zend_jit_hot_counters[ZEND_JIT_COUNTER_NUM];
|
||||
ZEND_JIT_COUNTER_NUM = (ZEND_JIT_COUNTER_NUM + 1) % ZEND_HOT_COUNTERS_COUNT;
|
||||
|
|
|
@ -298,6 +298,7 @@ void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D)
|
|||
ZVAL_NULL(result);
|
||||
}
|
||||
|
||||
#if ZEND_VM_KIND != ZEND_VM_KIND_HYBRID
|
||||
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op_array *op_array = (zend_op_array*)EX(func);
|
||||
|
@ -341,6 +342,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H
|
|||
ZEND_OPCODE_TAIL_CALL(handler);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static zend_always_inline zend_constant* _zend_quick_get_constant(
|
||||
const zval *key, uint32_t flags, int check_defined_only)
|
||||
|
@ -402,6 +404,7 @@ zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key)
|
|||
return _zend_quick_get_constant(key, 0, 1);
|
||||
}
|
||||
|
||||
#if ZEND_VM_KIND != ZEND_VM_KIND_HYBRID
|
||||
static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_trace_counter_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t cost)
|
||||
{
|
||||
zend_jit_op_array_trace_extension *jit_extension =
|
||||
|
@ -450,6 +453,7 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_trace_helper(ZEND_OPCODE_HAN
|
|||
ZEND_OPCODE_TAIL_CALL_EX(zend_jit_trace_counter_helper,
|
||||
((ZEND_JIT_COUNTER_INIT + JIT_G(hot_loop) - 1) / JIT_G(hot_loop)));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TRACE_RECORD(_op, _info, _ptr) \
|
||||
trace_buffer[idx].info = _op | (_info); \
|
||||
|
@ -657,7 +661,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
|
|||
zend_jit_trace_stop halt = 0;
|
||||
int level = 0;
|
||||
int ret_level = 0;
|
||||
zend_vm_opcode_handler_t handler;
|
||||
zend_vm_opcode_handler_func_t handler;
|
||||
const zend_op_array *op_array;
|
||||
zend_jit_op_array_trace_extension *jit_extension;
|
||||
size_t offset;
|
||||
|
@ -983,7 +987,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
|
|||
break;
|
||||
}
|
||||
|
||||
handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler;
|
||||
handler = ZEND_OP_TRACE_INFO(opline, offset)->call_handler;
|
||||
#ifdef HAVE_GCC_GLOBAL_REGS
|
||||
handler();
|
||||
if (UNEXPECTED(opline == zend_jit_halt_op)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue