Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] Pass opline as argument to opcode handlers in CALL VM #17952

Draft
wants to merge 30 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
04bff56
Pass opline via op handler args
arnaud-lb Feb 25, 2025
1f12382
Move extra vm helper parameters after standard ones
arnaud-lb Feb 25, 2025
6ebf91b
Improve reproducibility
arnaud-lb Aug 26, 2024
a773fbe
Update JIT for new op handler signature (wip)
arnaud-lb Feb 25, 2025
5a63362
Return -1 to signal execute_data reloading
arnaud-lb Feb 27, 2025
919e1a0
Revert "Return -1 to signal execute_data reloading"
arnaud-lb Feb 27, 2025
dc1a571
Use indempotent operation to signal execute_data reloading
arnaud-lb Feb 27, 2025
46de8b2
Save registers in generated code
arnaud-lb Feb 27, 2025
841f0ea
Force reload execute_data when returning from exception
arnaud-lb Feb 28, 2025
cb83679
Cleanup
arnaud-lb Feb 28, 2025
f382249
ZEND_VM_ENTER_BIT
arnaud-lb Feb 28, 2025
fad6772
GCC build fix
arnaud-lb Feb 28, 2025
5ae328d
Generated file
arnaud-lb Feb 28, 2025
44f0a90
Build fix
arnaud-lb Feb 28, 2025
0da3e5f
Define CHAR_BITS
arnaud-lb Feb 28, 2025
a5b9f66
Support platforms in which user space addresses may have the higher b…
arnaud-lb Mar 13, 2025
e00982e
Update zend_vm_call_opcode_handler()
arnaud-lb Mar 13, 2025
42f60ba
Fix zend_runtime_jit(): Return the original opline
arnaud-lb Mar 13, 2025
64f27cc
run-tests.php: Save stdin section to a file
arnaud-lb Mar 13, 2025
91284db
Rename ZEND_OPCODE_HANDLER_ARGS_DC / ZEND_OPCODE_HANDLER_ARGS_PASSTHR…
arnaud-lb Mar 14, 2025
93317c0
Fix build
arnaud-lb Mar 14, 2025
f4f9ec5
Fix windows build
arnaud-lb Mar 14, 2025
54cd812
Fix after rebase
arnaud-lb Mar 14, 2025
ad3c920
Fix zend_jit_leave_func
arnaud-lb Mar 14, 2025
f013aa1
Remove zend_jit_set_ip_ex
arnaud-lb Mar 17, 2025
d50c5d1
Re-add/update comments
arnaud-lb Mar 17, 2025
8637220
Update zend_jit_trace_handler
arnaud-lb Mar 17, 2025
ced459a
Update zend_jit_trace_execute
arnaud-lb Mar 17, 2025
23a1cb4
Fix Zend/tests/bug70689.phpt
arnaud-lb Mar 17, 2025
d31339f
Fix x32
arnaud-lb Mar 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Zend/zend_portability.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@

#include <stdarg.h>
#include <stddef.h>
#include <stdint.h>

#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
Expand Down Expand Up @@ -864,4 +865,20 @@ static zend_always_inline uint64_t ZEND_BYTES_SWAP64(uint64_t u)
# define ZEND_OPCACHE_SHM_REATTACHMENT 1
#endif

#ifndef CHAR_BITS
# define CHAR_BITS 8
#endif

#ifndef UINTPTR_WIDTH
# define UINTPTR_WIDTH (CHAR_BITS * sizeof(uintptr_t))
#endif

#if (defined(__linux__) && defined(__x86_64__)) \
|| (defined(ZEND_WIN32) && defined(_M_AMD64))
/* The kernel reserves the higher part of the address space for itself.
* Therefore, we can assume that the higher bit of user space addresses is
* never set. */
# define ZEND_HIGH_HALF_KERNEL
#endif

#endif /* ZEND_PORTABILITY_H */
3 changes: 1 addition & 2 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -5602,11 +5602,10 @@ ZEND_VM_HOT_HANDLER(199, ZEND_CHECK_UNDEF_ARGS, UNUSED, UNUSED)

ZEND_VM_COLD_HELPER(zend_missing_arg_helper, ANY, ANY)
{
#ifdef ZEND_VM_IP_GLOBAL_REG
USE_OPLINE

SAVE_OPLINE();
#endif

Comment on lines -5605 to +5608
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removes EX(opline) = opline when ZEND_VM_IP_GLOBAL_REG is defined.
This may cause output of incorrect line number in error message.
May be I miss something?

zend_missing_arg_error(execute_data);
HANDLE_EXCEPTION();
}
Expand Down
388 changes: 211 additions & 177 deletions Zend/zend_vm_execute.h

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Zend/zend_vm_execute.skl
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "Zend/zend_vm_opcodes.h"

{%DEFINES%}

#if (ZEND_VM_KIND != ZEND_VM_KIND_CALL) && (ZEND_GCC_VERSION >= 4000) && !defined(__clang__)
Expand Down
108 changes: 71 additions & 37 deletions Zend/zend_vm_gen.php

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions Zend/zend_vm_opcodes.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 18 additions & 7 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ 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 int ZEND_FASTCALL zend_runtime_jit(void);
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS);

static int zend_jit_trace_op_len(const zend_op *opline);
static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op *opline);
Expand Down Expand Up @@ -2871,7 +2871,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
if (GCC_GLOBAL_REGS) {
ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit)));
} else {
ir_RETURN(ir_CONST_I32(1)); /* ZEND_VM_ENTER */
zend_jit_vm_enter(jit, jit_IP(jit));
}
ir_IF_TRUE(if_hook_enter);
}
Expand Down Expand Up @@ -3074,11 +3074,18 @@ static int zend_real_jit_func(zend_op_array *op_array, zend_script *script, cons
}

/* Run-time JIT handler */
static int ZEND_FASTCALL zend_runtime_jit(void)
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_runtime_jit(ZEND_OPCODE_HANDLER_ARGS)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ops. It looks like the previous prototype was wrong.

{
zend_execute_data *execute_data = EG(current_execute_data);
#if GCC_GLOBAL_REGS
zend_execute_data *execute_data;
zend_op *opline;
#else
const zend_op *orig_opline = opline;
#endif

execute_data = EG(current_execute_data);
zend_op_array *op_array = &EX(func)->op_array;
zend_op *opline = op_array->opcodes;
opline = op_array->opcodes;
zend_jit_op_array_extension *jit_extension;
bool do_bailout = 0;

Expand All @@ -3097,7 +3104,7 @@ static int ZEND_FASTCALL zend_runtime_jit(void)
}
}
jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array);
opline->handler = jit_extension->orig_handler;
((zend_op*)opline)->handler = jit_extension->orig_handler;

/* perform real JIT for this function */
zend_real_jit_func(op_array, NULL, NULL, ZEND_JIT_ON_FIRST_EXEC);
Expand All @@ -3116,7 +3123,11 @@ static int ZEND_FASTCALL zend_runtime_jit(void)
}

/* JIT-ed code is going to be called by VM */
return 0;
#if GCC_GLOBAL_REGS
return; // ZEND_VM_CONTINUE
#else
return orig_opline; // ZEND_VM_CONTINUE
#endif
}

void zend_jit_check_funcs(HashTable *function_table, bool is_method) {
Expand Down
41 changes: 28 additions & 13 deletions ext/opcache/jit/zend_jit_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@
#ifndef ZEND_JIT_INTERNAL_H
#define ZEND_JIT_INTERNAL_H

#include "Zend/zend_types.h"
#include "Zend/zend_compile.h"
#include "Zend/zend_constants.h"
#include "Zend/Optimizer/zend_func_info.h"
#include "Zend/Optimizer/zend_call_graph.h"

/* Address Encoding */
typedef uintptr_t zend_jit_addr;

Expand Down Expand Up @@ -183,17 +189,19 @@ extern const zend_op *zend_jit_halt_op;
# define ZEND_OPCODE_HANDLER_RET void
# define ZEND_OPCODE_HANDLER_ARGS EXECUTE_DATA_D
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU
# define ZEND_OPCODE_HANDLER_ARGS_DC
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC
# define ZEND_OPCODE_HANDLER_ARGS_EX
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX
# define ZEND_OPCODE_RETURN() return
# define ZEND_OPCODE_TAIL_CALL(handler) do { \
handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \
return; \
} while(0)
# define ZEND_OPCODE_TAIL_CALL_EX(handler, arg) do { \
handler(arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC); \
handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg); \
return; \
} while(0)
# define ZEND_VM_ENTER_BIT 0
# define ZEND_VM_RETURN_VAL 0
#else
# define EXECUTE_DATA_D zend_execute_data* execute_data
# define EXECUTE_DATA_C execute_data
Expand All @@ -203,27 +211,34 @@ extern const zend_op *zend_jit_halt_op;
# define OPLINE_C opline
# define OPLINE_DC , OPLINE_D
# define OPLINE_CC , OPLINE_C
# define ZEND_OPCODE_HANDLER_RET int
# define ZEND_OPCODE_HANDLER_ARGS EXECUTE_DATA_D
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU EXECUTE_DATA_C
# define ZEND_OPCODE_HANDLER_ARGS_DC EXECUTE_DATA_DC
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC EXECUTE_DATA_CC
# define ZEND_OPCODE_RETURN() return 0
# define ZEND_OPCODE_HANDLER_RET const zend_op *
# define ZEND_OPCODE_HANDLER_ARGS EXECUTE_DATA_D OPLINE_DC
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU EXECUTE_DATA_C OPLINE_CC
# define ZEND_OPCODE_HANDLER_ARGS_EX EXECUTE_DATA_D OPLINE_DC,
# define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX EXECUTE_DATA_C OPLINE_CC,
# define ZEND_OPCODE_RETURN() return opline
# define ZEND_OPCODE_TAIL_CALL(handler) do { \
return handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); \
} while(0)
# define ZEND_OPCODE_TAIL_CALL_EX(handler, arg) do { \
return handler(arg ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC); \
return handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg); \
} while(0)
# ifdef ZEND_HIGH_HALF_KERNEL
# define ZEND_VM_ENTER_BIT (1ULL<<(UINTPTR_WIDTH-1))
# define ZEND_VM_RETURN_VAL 0
# else
# define ZEND_VM_ENTER_BIT 1ULL
# define ZEND_VM_RETURN_VAL ZEND_VM_ENTER_BIT
# endif
Comment on lines +226 to +232
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we redifine ZEND_VM_ENTER_BIT here?

#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(uint32_t call_info EXECUTE_DATA_DC);
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_top_func_helper(uint32_t call_info EXECUTE_DATA_DC);
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_func_helper(EXECUTE_DATA_D);
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);
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_leave_func_helper(ZEND_OPCODE_HANDLER_ARGS);

ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS);

Expand Down
Loading
Loading