Skip to content

Commit ed49acd

Browse files
committed
Introduce zend_vm_opcode_handler_t / zend_vm_opcode_handler_func_t
This reduces confusion between opcode handlers used by the VM, and opcode handler functions used for tracing. Depending on the VM, zend_vm_opcode_handler_t may not be a real function. For instance in the HYBRID VM this is a label pointer.
1 parent 4a98b36 commit ed49acd

File tree

10 files changed

+109
-84
lines changed

10 files changed

+109
-84
lines changed

Zend/zend_compile.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "zend_types.h"
2525
#include "zend_map_ptr.h"
2626
#include "zend_alloc.h"
27+
#include "zend_vm_opcodes.h"
2728

2829
#include <stdarg.h>
2930
#include <stdint.h>
@@ -135,7 +136,7 @@ void zend_const_expr_to_zval(zval *result, zend_ast **ast_ptr, bool allow_dynami
135136
typedef int (*user_opcode_handler_t) (zend_execute_data *execute_data);
136137

137138
struct _zend_op {
138-
const void *handler;
139+
zend_vm_opcode_handler_t handler;
139140
znode_op op1;
140141
znode_op op2;
141142
znode_op result;

Zend/zend_vm_execute.h

Lines changed: 9 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Zend/zend_vm_execute.skl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ ZEND_API void ZEND_FASTCALL zend_serialize_opcode_handler(zend_op *op)
126126
}
127127
zv = zend_hash_index_find(zend_handlers_table, (zend_long)(uintptr_t)op->handler);
128128
ZEND_ASSERT(zv != NULL);
129-
op->handler = (const void *)(uintptr_t)Z_LVAL_P(zv);
129+
op->handler = (zend_vm_opcode_handler_t)(uintptr_t)Z_LVAL_P(zv);
130130
}
131131

132132
ZEND_API void ZEND_FASTCALL zend_deserialize_opcode_handler(zend_op *op)

Zend/zend_vm_gen.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,11 +1813,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
18131813
out($f,"#define SPEC_RULE_OBSERVER 0x02000000\n");
18141814
out($f,"\n");
18151815
out($f,"static const uint32_t *zend_spec_handlers;\n");
1816-
out($f,"static const void * const *zend_opcode_handlers;\n");
1816+
out($f,"static zend_vm_opcode_handler_t const *zend_opcode_handlers;\n");
18171817
out($f,"static int zend_handlers_count;\n");
18181818
if ($kind == ZEND_VM_KIND_HYBRID) {
18191819
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
1820-
out($f,"static const void * const * zend_opcode_handler_funcs;\n");
1820+
out($f,"static zend_vm_opcode_handler_func_t const * zend_opcode_handler_funcs;\n");
18211821
out($f,"static zend_op hybrid_halt_op;\n");
18221822
out($f,"#endif\n");
18231823
}
@@ -2097,7 +2097,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
20972097
out($f,$prolog."\tstatic const void * const labels[] = {\n");
20982098
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_GOTO : $kind, $prolog."\t\t", $specs);
20992099
out($f,$prolog."\t};\n");
2100-
out($f,$prolog."\tzend_opcode_handlers = (const void **) labels;\n");
2100+
out($f,$prolog."\tzend_opcode_handlers = (zend_vm_opcode_handler_t*) labels;\n");
21012101
out($f,$prolog."\tzend_handlers_count = sizeof(labels) / sizeof(void*);\n");
21022102
if ($kind == ZEND_VM_KIND_HYBRID) {
21032103
out($f,$prolog."\tmemset(&hybrid_halt_op, 0, sizeof(hybrid_halt_op));\n");
@@ -2212,7 +2212,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name)
22122212
out($f,$prolog."zend_spec_handlers = specs;\n");
22132213
out($f,$prolog.$executor_name."_ex(NULL);\n");
22142214
} else {
2215-
out($f,$prolog."static const void * const labels[] = {\n");
2215+
out($f,"#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)\n");
2216+
out($f,$prolog."static zend_vm_opcode_handler_func_t const labels[] = {\n");
2217+
out($f,"#else\n");
2218+
out($f,$prolog."static zend_vm_opcode_handler_t const labels[] = {\n");
2219+
out($f,"#endif\n");
22162220
gen_labels($f, $spec, ($kind == ZEND_VM_KIND_HYBRID) ? ZEND_VM_KIND_CALL : $kind, $prolog."\t", $specs, $switch_labels);
22172221
out($f,$prolog."};\n");
22182222
out($f,$prolog."static const uint32_t specs[] = {\n");
@@ -2359,6 +2363,17 @@ function gen_vm_opcodes_header(
23592363
$str .= "# endif\n";
23602364
$str .= "#endif\n";
23612365
$str .= "\n";
2366+
$str .= "#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID\n";
2367+
$str .= "typedef const void* zend_vm_opcode_handler_t;\n";
2368+
$str .= "typedef void (ZEND_FASTCALL *zend_vm_opcode_handler_func_t)(void);\n";
2369+
$str .= "#elif ZEND_VM_KIND == ZEND_VM_KIND_CALL\n";
2370+
$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";
2371+
$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";
2372+
$str .= "#else\n";
2373+
$str .= "typedef const void* zend_vm_opcode_handler_t;\n";
2374+
$str .= "typedef const void* zend_vm_opcode_handler_func_t;\n";
2375+
$str .= "#endif\n";
2376+
$str .= "\n";
23622377
foreach ($vm_op_flags as $name => $val) {
23632378
$str .= sprintf("#define %-24s 0x%08x\n", $name, $val);
23642379
}

Zend/zend_vm_opcodes.h

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/opcache/jit/zend_jit.c

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ static size_t dasm_size = 0;
9090

9191
static zend_long jit_bisect_pos = 0;
9292

93-
static const void *zend_jit_runtime_jit_handler = NULL;
94-
static const void *zend_jit_profile_jit_handler = NULL;
95-
static const void *zend_jit_func_hot_counter_handler = NULL;
96-
static const void *zend_jit_loop_hot_counter_handler = NULL;
97-
static const void *zend_jit_func_trace_counter_handler = NULL;
98-
static const void *zend_jit_ret_trace_counter_handler = NULL;
99-
static const void *zend_jit_loop_trace_counter_handler = NULL;
93+
static zend_vm_opcode_handler_t zend_jit_runtime_jit_handler = NULL;
94+
static zend_vm_opcode_handler_t zend_jit_profile_jit_handler = NULL;
95+
static zend_vm_opcode_handler_t zend_jit_func_hot_counter_handler = NULL;
96+
static zend_vm_opcode_handler_t zend_jit_loop_hot_counter_handler = NULL;
97+
static zend_vm_opcode_handler_t zend_jit_func_trace_counter_handler = NULL;
98+
static zend_vm_opcode_handler_t zend_jit_ret_trace_counter_handler = NULL;
99+
static zend_vm_opcode_handler_t zend_jit_loop_trace_counter_handler = NULL;
100100

101101
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS);
102102

@@ -1417,7 +1417,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
14171417
zend_jit_ctx ctx;
14181418
zend_jit_ctx *jit = &ctx;
14191419
zend_jit_reg_var *ra = NULL;
1420-
void *handler;
1420+
zend_vm_opcode_handler_t handler;
14211421
int call_level = 0;
14221422
void *checkpoint = NULL;
14231423
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
32133213
}
32143214
}
32153215

3216-
opline->handler = (const void*)zend_jit_func_hot_counter_handler;
3216+
opline->handler = zend_jit_func_hot_counter_handler;
32173217
}
32183218

32193219
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
32233223
if ((cfg->blocks[i].flags & ZEND_BB_REACHABLE) &&
32243224
(cfg->blocks[i].flags & ZEND_BB_LOOP_HEADER)) {
32253225
op_array->opcodes[cfg->blocks[i].start].handler =
3226-
(const void*)zend_jit_loop_hot_counter_handler;
3226+
zend_jit_loop_hot_counter_handler;
32273227
}
32283228
}
32293229
}
@@ -3316,7 +3316,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
33163316
jit_extension->op_array = op_array;
33173317
jit_extension->orig_handler = (void*)opline->handler;
33183318
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
3319-
opline->handler = (const void*)zend_jit_runtime_jit_handler;
3319+
opline->handler = zend_jit_runtime_jit_handler;
33203320
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
33213321

33223322
return SUCCESS;
@@ -3346,7 +3346,7 @@ int zend_jit_op_array(zend_op_array *op_array, zend_script *script)
33463346
jit_extension->op_array = op_array;
33473347
jit_extension->orig_handler = (void*)opline->handler;
33483348
ZEND_SET_FUNC_INFO(op_array, (void*)jit_extension);
3349-
opline->handler = (const void*)zend_jit_profile_jit_handler;
3349+
opline->handler = zend_jit_profile_jit_handler;
33503350
zend_shared_alloc_register_xlat_entry(op_array->opcodes, jit_extension);
33513351
}
33523352

@@ -3566,23 +3566,23 @@ void zend_jit_protect(void)
35663566

35673567
static void zend_jit_init_handlers(void)
35683568
{
3569-
if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
3570-
zend_jit_runtime_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
3571-
zend_jit_profile_jit_handler = zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
3572-
zend_jit_func_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
3573-
zend_jit_loop_hot_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
3574-
zend_jit_func_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
3575-
zend_jit_ret_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
3576-
zend_jit_loop_trace_counter_handler = zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
3577-
} else {
3578-
zend_jit_runtime_jit_handler = (const void*)zend_runtime_jit;
3579-
zend_jit_profile_jit_handler = (const void*)zend_jit_profile_helper;
3580-
zend_jit_func_hot_counter_handler = (const void*)zend_jit_func_counter_helper;
3581-
zend_jit_loop_hot_counter_handler = (const void*)zend_jit_loop_counter_helper;
3582-
zend_jit_func_trace_counter_handler = (const void*)zend_jit_func_trace_helper;
3583-
zend_jit_ret_trace_counter_handler = (const void*)zend_jit_ret_trace_helper;
3584-
zend_jit_loop_trace_counter_handler = (const void*)zend_jit_loop_trace_helper;
3585-
}
3569+
#if ZEND_VM_KIND == ZEND_VM_KIND_HYBRID
3570+
zend_jit_runtime_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_runtime_jit];
3571+
zend_jit_profile_jit_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_profile_jit];
3572+
zend_jit_func_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_hot_counter];
3573+
zend_jit_loop_hot_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_hot_counter];
3574+
zend_jit_func_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_func_trace_counter];
3575+
zend_jit_ret_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_ret_trace_counter];
3576+
zend_jit_loop_trace_counter_handler = (zend_vm_opcode_handler_t)zend_jit_stub_handlers[jit_stub_hybrid_loop_trace_counter];
3577+
#else
3578+
zend_jit_runtime_jit_handler = zend_runtime_jit;
3579+
zend_jit_profile_jit_handler = zend_jit_profile_helper;
3580+
zend_jit_func_hot_counter_handler = zend_jit_func_counter_helper;
3581+
zend_jit_loop_hot_counter_handler = zend_jit_loop_counter_helper;
3582+
zend_jit_func_trace_counter_handler = zend_jit_func_trace_helper;
3583+
zend_jit_ret_trace_counter_handler = zend_jit_ret_trace_helper;
3584+
zend_jit_loop_trace_counter_handler = zend_jit_loop_trace_helper;
3585+
#endif
35863586
}
35873587

35883588
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)
39453945
}
39463946
}
39473947
if (func_info->flags & ZEND_FUNC_JIT_ON_FIRST_EXEC) {
3948-
opline->handler = (const void*)zend_jit_runtime_jit_handler;
3948+
opline->handler = zend_jit_runtime_jit_handler;
39493949
} else {
3950-
opline->handler = (const void*)zend_jit_profile_jit_handler;
3950+
opline->handler = zend_jit_profile_jit_handler;
39513951
}
39523952
#endif
39533953
}

ext/opcache/jit/zend_jit_internal.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "Zend/zend_constants.h"
2727
#include "Zend/Optimizer/zend_func_info.h"
2828
#include "Zend/Optimizer/zend_call_graph.h"
29+
#include "zend_vm_opcodes.h"
2930

3031
/* Address Encoding */
3132
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_
130131
typedef struct _zend_jit_op_array_extension {
131132
zend_func_info func_info;
132133
const zend_op_array *op_array;
133-
const void *orig_handler;
134+
zend_vm_opcode_handler_t orig_handler;
134135
} zend_jit_op_array_extension;
135136

136137
/* Profiler */
@@ -169,7 +170,7 @@ typedef struct _zend_jit_op_array_hot_extension {
169170
zend_func_info func_info;
170171
const zend_op_array *op_array;
171172
int16_t *counter;
172-
const void *orig_handlers[1];
173+
zend_vm_opcode_handler_t orig_handlers[1];
173174
} zend_jit_op_array_hot_extension;
174175

175176
#define zend_jit_op_array_hash(op_array) \
@@ -225,9 +226,6 @@ extern const zend_op *zend_jit_halt_op;
225226
# define ZEND_VM_ENTER_BIT 1ULL
226227
#endif
227228

228-
/* VM handlers */
229-
typedef ZEND_OPCODE_HANDLER_RET (ZEND_FASTCALL *zend_vm_opcode_handler_t)(ZEND_OPCODE_HANDLER_ARGS);
230-
231229
/* VM helpers */
232230
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_nested_func_helper(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t call_info);
233231
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 {
339337
typedef union _zend_op_trace_info {
340338
zend_op dummy; /* the size of this structure must be the same as zend_op */
341339
struct {
342-
const void *orig_handler;
343-
const void *call_handler;
340+
zend_vm_opcode_handler_t orig_handler;
341+
zend_vm_opcode_handler_func_t call_handler;
344342
int16_t *counter;
345343
uint8_t trace_flags;
346344
};

0 commit comments

Comments
 (0)