Skip to content

Commit 8bef9e2

Browse files
committed
fix jit
1 parent eef606e commit 8bef9e2

File tree

3 files changed

+73
-15
lines changed

3 files changed

+73
-15
lines changed

ext/opcache/jit/ir/ir_x86.dasc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,9 +1051,15 @@ const ir_call_conv_dsc ir_call_conv_x86_64_preserve_none = {
10511051
IR_REG_XMM0, /* fp_ret_reg */
10521052
IR_REG_RAX, /* fp_varargs_reg */
10531053
IR_REG_SCRATH_X86_64_PN,
1054+
#ifdef _WIN32
1055+
(const int8_t[12]){IR_REG_R13, IR_REG_R14, IR_REG_R15, IR_REG_R12,
1056+
IR_REG_RDI, IR_REG_RSI, IR_REG_RDX, IR_REG_RCX, IR_REG_R8, IR_REG_R9,
1057+
IR_REG_R11, IR_REG_RAX},
1058+
#else
10541059
(const int8_t[12]){IR_REG_R12, IR_REG_R13, IR_REG_R14, IR_REG_R15,
10551060
IR_REG_RDI, IR_REG_RSI, IR_REG_RDX, IR_REG_RCX, IR_REG_R8, IR_REG_R9,
10561061
IR_REG_R11, IR_REG_RAX},
1062+
#endif
10571063
(const int8_t[8]){IR_REG_XMM0, IR_REG_XMM1, IR_REG_XMM2, IR_REG_XMM3,
10581064
IR_REG_XMM4, IR_REG_XMM5, IR_REG_XMM6, IR_REG_XMM7},
10591065
IR_REGSET(IR_REG_RBP),

ext/opcache/jit/zend_jit_ir.c

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222
#include "jit/ir/ir_builder.h"
2323
#include "jit/tls/zend_jit_tls.h"
2424

25+
#if ZEND_VM_KIND == ZEND_VM_KIND_CALL && defined(HAVE_PRESERVE_NONE) && defined(_WIN32)
26+
# define IR_OPCODE_HANDLER_CC IR_CC_PRESERVE_NONE
27+
#else
28+
# define IR_OPCODE_HANDLER_CC IR_FASTCALL_FUNC
29+
#endif
30+
31+
/* Whether args arrive directly in ZREG registers (don't need IR_PARAM) */
32+
#define ZEND_JIT_ARGS_IN_ZREG (ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL || IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC)
33+
2534
#if defined(IR_TARGET_X86)
2635
# define IR_REG_SP 4 /* IR_REG_RSP */
2736
# define IR_REG_FP 5 /* IR_REG_RBP */
@@ -40,6 +49,9 @@
4049
* https://github.com/llvm/llvm-project/blob/68bfe91b5a34f80dbcc4f0a7fa5d7aa1cdf959c2/llvm/lib/Target/X86/X86CallingConv.td#L1029 */
4150
# define ZREG_FP 12 /* IR_REG_R12 */
4251
# define ZREG_IP 13 /* IR_REG_R13 */
52+
# elif IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
53+
# define ZREG_FP 13 /* IR_REG_R13 = MSVC preserve_none arg1 */
54+
# define ZREG_IP 14 /* IR_REG_R14 = MSVC preserve_none arg2 */
4355
# else
4456
# define ZREG_FP 14 /* IR_REG_R14 */
4557
# define ZREG_IP 15 /* IR_REG_R15 */
@@ -99,7 +111,7 @@
99111
# define ir_CONST_OPCODE_HANDLER_FUNC(_addr) \
100112
jit_CONST_OPCODE_HANDLER_FUNC(jit, _addr)
101113
# define ir_CAST_OPCODE_HANDLER_FUNC(_addr) ir_fold2(_ir_CTX, IR_OPT(IR_PROTO, IR_ADDR), (_addr), \
102-
ir_proto_0(_ir_CTX, IR_FASTCALL_FUNC, IR_OPCODE_HANDLER_RET))
114+
ir_proto_0(_ir_CTX, IR_OPCODE_HANDLER_CC, IR_OPCODE_HANDLER_RET))
103115

104116
#define ir_CONST_FUNC_PROTO(_addr, _proto) \
105117
jit_CONST_FUNC_PROTO(jit, (uintptr_t)(_addr), (_proto))
@@ -573,15 +585,15 @@ static ir_ref jit_CONST_FUNC(zend_jit_ctx *jit, uintptr_t addr, uint16_t flags)
573585
/* TODO: dummy prototype (only flags matter) ??? */
574586
ir_ref proto = flags ? ir_proto_0(&jit->ctx, flags, IR_I32) : 0;
575587
#else
576-
ir_ref proto = 0;
588+
ir_ref proto = (flags == IR_CC_PRESERVE_NONE) ? ir_proto_0(&jit->ctx, flags, IR_ADDR) : 0;
577589
#endif
578590

579591
return jit_CONST_FUNC_PROTO(jit, addr, proto);
580592
}
581593

582594
static ir_ref jit_CONST_OPCODE_HANDLER_FUNC(zend_jit_ctx *jit, zend_vm_opcode_handler_t handler)
583595
{
584-
return jit_CONST_FUNC(jit, (uintptr_t)handler, IR_FASTCALL_FUNC);
596+
return jit_CONST_FUNC(jit, (uintptr_t)handler, IR_OPCODE_HANDLER_CC);
585597
}
586598

587599
static ir_ref jit_ADD_OFFSET(zend_jit_ctx *jit, ir_ref addr, uintptr_t offset)
@@ -1958,15 +1970,19 @@ static void zend_jit_vm_leave(zend_jit_ctx *jit, ir_ref to_opline)
19581970

19591971
static void zend_jit_tailcall_handler(zend_jit_ctx *jit, ir_ref handler)
19601972
{
1961-
#if defined(IR_TARGET_X86)
1973+
#if defined(IR_TARGET_X86) || IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
19621974
if (!IR_IS_CONST_REF(handler)) {
19631975
handler = ir_CAST_OPCODE_HANDLER_FUNC(handler);
19641976
}
19651977
#endif
19661978
if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) {
19671979
ir_TAILCALL(IR_OPCODE_HANDLER_RET, handler);
19681980
} else {
1981+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
1982+
ir_RETURN(ir_CALL_2(IR_ADDR, handler, jit_FP(jit), jit_IP(jit)));
1983+
#else
19691984
ir_TAILCALL_2(IR_ADDR, handler, jit_FP(jit), jit_IP(jit));
1985+
#endif
19701986
}
19711987
}
19721988

@@ -2535,7 +2551,7 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit)
25352551
if (GCC_GLOBAL_REGS || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) {
25362552
zend_jit_tailcall_handler(jit, addr);
25372553
} else {
2538-
#if defined(IR_TARGET_X86)
2554+
#if defined(IR_TARGET_X86) || IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
25392555
addr = ir_CAST_OPCODE_HANDLER_FUNC(addr);
25402556
#endif
25412557
ref = ir_CALL_2(IR_ADDR, addr, jit_FP(jit), jit_IP(jit));
@@ -3229,7 +3245,7 @@ static void zend_jit_calc_trace_prologue_size(void)
32293245
zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : IR_START_BR_TARGET);
32303246

32313247
if (!GCC_GLOBAL_REGS) {
3232-
if (ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) {
3248+
if (!ZEND_JIT_ARGS_IN_ZREG) {
32333249
ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1);
32343250
ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2);
32353251
jit_STORE_FP(jit, execute_data_ref);
@@ -4066,7 +4082,7 @@ static void zend_jit_recv_entry(zend_jit_ctx *jit, int b)
40664082

40674083
/* Insert a MERGE block with additional ENTRY input between predecessor and this one */
40684084
ir_ENTRY(ref, bb->start);
4069-
if (!GCC_GLOBAL_REGS && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) {
4085+
if (!GCC_GLOBAL_REGS && !ZEND_JIT_ARGS_IN_ZREG) {
40704086
/* 2 and 3 are hardcoded reference to IR_PARAMs */
40714087
ZEND_ASSERT(jit->ctx.ir_base[2].op == IR_PARAM);
40724088
ZEND_ASSERT(jit->ctx.ir_base[2].op3 == 1);
@@ -4087,7 +4103,7 @@ static void zend_jit_osr_entry(zend_jit_ctx *jit, int b)
40874103

40884104
/* Insert a MERGE block with additional ENTRY input between predecessor and this one */
40894105
ir_ENTRY(ref, bb->start);
4090-
if (!GCC_GLOBAL_REGS && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) {
4106+
if (!GCC_GLOBAL_REGS && !ZEND_JIT_ARGS_IN_ZREG) {
40914107
/* 2 and 3 are hardcoded reference to IR_PARAMs */
40924108
ZEND_ASSERT(jit->ctx.ir_base[2].op == IR_PARAM);
40934109
ZEND_ASSERT(jit->ctx.ir_base[2].op3 == 1);
@@ -4103,7 +4119,7 @@ static void zend_jit_osr_entry(zend_jit_ctx *jit, int b)
41034119
static ir_ref zend_jit_continue_entry(zend_jit_ctx *jit, ir_ref src, unsigned int label)
41044120
{
41054121
ir_ENTRY(src, label);
4106-
if (!GCC_GLOBAL_REGS && ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) {
4122+
if (!GCC_GLOBAL_REGS && !ZEND_JIT_ARGS_IN_ZREG) {
41074123
/* 2 and 3 are hardcoded reference to IR_PARAMs */
41084124
ZEND_ASSERT(jit->ctx.ir_base[2].op == IR_PARAM);
41094125
ZEND_ASSERT(jit->ctx.ir_base[2].op3 == 1);
@@ -4127,7 +4143,13 @@ static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_th
41274143
jit_STORE_IP(jit, ip);
41284144
} else {
41294145
zend_vm_opcode_handler_t handler = opline->handler;
4130-
ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit));
4146+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
4147+
ir_STORE(jit_EG(current_execute_data), jit_FP(jit));
4148+
#endif
4149+
ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit));
4150+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
4151+
jit_STORE_FP(jit, ir_LOAD_A(jit_EG(current_execute_data)));
4152+
#endif
41314153
jit_STORE_IP(jit, ip);
41324154
}
41334155
if (may_throw) {
@@ -4151,6 +4173,9 @@ static int zend_jit_handler(zend_jit_ctx *jit, const zend_op *opline, int may_th
41514173
zend_jit_set_last_valid_opline(jit, opline + 1);
41524174
break;
41534175
}
4176+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
4177+
zend_jit_reset_last_valid_opline(jit);
4178+
#endif
41544179
return 1;
41554180
}
41564181

@@ -4189,7 +4214,11 @@ static int zend_jit_tail_handler(zend_jit_ctx *jit, const zend_op *opline)
41894214
ir_ref ip = ir_CALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit));
41904215
zend_jit_vm_enter(jit, ip);
41914216
} else {
4217+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
4218+
ir_RETURN(ir_CALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit)));
4219+
#else
41924220
ir_TAILCALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC(handler), jit_FP(jit), jit_IP(jit));
4221+
#endif
41934222
}
41944223
}
41954224
if (jit->b >= 0) {
@@ -7983,8 +8012,13 @@ static int zend_jit_escape_if_undef(zend_jit_ctx *jit, int var, uint32_t flags,
79838012
} else {
79848013
#if defined(IR_TARGET_X86)
79858014
ref = ir_CAST_FC_FUNC(ref);
7986-
#endif
79878015
ir_TAILCALL_2(IR_ADDR, ref, jit_FP(jit), jit_IP(jit));
8016+
#elif IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
8017+
ref = ir_CAST_OPCODE_HANDLER_FUNC(ref);
8018+
ir_RETURN(ir_CALL_2(IR_ADDR, ref, jit_FP(jit), jit_IP(jit)));
8019+
#else
8020+
ir_TAILCALL_2(IR_ADDR, ref, jit_FP(jit), jit_IP(jit));
8021+
#endif
79888022
}
79898023

79908024
ir_IF_TRUE(if_def);
@@ -16719,7 +16753,7 @@ static int zend_jit_start(zend_jit_ctx *jit, const zend_op_array *op_array, zend
1671916753
jit->bb_edges = zend_arena_calloc(&CG(arena), count, sizeof(ir_ref));
1672016754

1672116755
if (!GCC_GLOBAL_REGS) {
16722-
if (ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) {
16756+
if (!ZEND_JIT_ARGS_IN_ZREG) {
1672316757
ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1);
1672416758
ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2);
1672516759
jit_STORE_FP(jit, execute_data_ref);
@@ -17107,7 +17141,13 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr
1710717141
if (GCC_GLOBAL_REGS) {
1710817142
ir_CALL(IR_VOID, ir_CONST_FUNC(handler));
1710917143
} else {
17110-
ref = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(handler), jit_FP(jit), jit_IP(jit));
17144+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
17145+
ir_STORE(jit_EG(current_execute_data), jit_FP(jit));
17146+
#endif
17147+
ref = ir_CALL_2(IR_ADDR, ir_CONST_OPCODE_HANDLER_FUNC((zend_vm_opcode_handler_t)handler), jit_FP(jit), jit_IP(jit));
17148+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
17149+
jit_STORE_FP(jit, ir_LOAD_A(jit_EG(current_execute_data)));
17150+
#endif
1711117151
if (opline->opcode == ZEND_RETURN ||
1711217152
opline->opcode == ZEND_RETURN_BY_REF ||
1711317153
opline->opcode == ZEND_DO_UCALL ||
@@ -17120,6 +17160,9 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr
1712017160
} else {
1712117161
jit_STORE_IP(jit, ref);
1712217162
}
17163+
#if IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
17164+
zend_jit_reset_last_valid_opline(jit);
17165+
#endif
1712317166
}
1712417167
if (may_throw
1712517168
&& opline->opcode != ZEND_RETURN
@@ -17301,7 +17344,7 @@ static int zend_jit_trace_start(zend_jit_ctx *jit,
1730117344

1730217345
if (!GCC_GLOBAL_REGS) {
1730317346
if (!parent) {
17304-
if (ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL) {
17347+
if (!ZEND_JIT_ARGS_IN_ZREG) {
1730517348
ir_ref execute_data_ref = ir_PARAM(IR_ADDR, "execute_data", 1);
1730617349
ir_ref opline_ref = ir_PARAM(IR_ADDR, "opline", 2);
1730717350
jit_STORE_FP(jit, execute_data_ref);
@@ -17422,6 +17465,8 @@ static int zend_jit_trace_return(zend_jit_ctx *jit, bool original_handler, const
1742217465

1742317466
#if defined(IR_TARGET_X86)
1742417467
addr = ir_CAST_FC_FUNC(addr);
17468+
#elif IR_OPCODE_HANDLER_CC != IR_FASTCALL_FUNC
17469+
addr = ir_CAST_OPCODE_HANDLER_FUNC(addr);
1742517470
#endif
1742617471
ref = ir_CALL_2(IR_ADDR, addr, jit_FP(jit), jit_IP(jit));
1742717472
zend_jit_vm_enter(jit, ref);

win32/build/confutils.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3496,7 +3496,14 @@ function toolset_setup_common_ldflags()
34963496

34973497
if (VS_TOOLSET) {
34983498
if (PHP_SECURITY_FLAGS == "yes") {
3499-
ADD_FLAG('LDFLAGS', "/GUARD:CF");
3499+
if (VCVERS >= 1944 && TARGET_ARCH === 'x64') {
3500+
// TODO: fix JIT with /guard:cf
3501+
var _cf = configure_subst.Item("CFLAGS");
3502+
configure_subst.Remove("CFLAGS");
3503+
configure_subst.Add("CFLAGS", _cf.replace(/\/guard:cf/g, ""));
3504+
} else {
3505+
ADD_FLAG('LDFLAGS', "/GUARD:CF");
3506+
}
35003507
}
35013508
if (PHP_VS_LINK_COMPAT != "no") {
35023509
// Allow compatible IL versions, do not require an exact match.

0 commit comments

Comments
 (0)