Skip to content

Commit c1fa4f2

Browse files
committed
Add IR JIT support for Wondows (Win64 support is incomplete)
1 parent 23f39d8 commit c1fa4f2

File tree

6 files changed

+130
-24
lines changed

6 files changed

+130
-24
lines changed

ext/opcache/config.m4

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,8 @@ if test "$PHP_OPCACHE" != "no"; then
4545
esac
4646
fi
4747

48-
if test "$PHP_OPCACHE_JIT" = "yes"; then
48+
if test "$PHP_OPCACHE_JIT" = "yes" -a "$PHP_OPCACHE_JIT_IR" = "no" ; then
4949
AC_DEFINE(HAVE_JIT, 1, [Define to enable JIT])
50-
51-
if test "$PHP_OPCACHE_JIT_IR" = "no"; then
52-
5350
ZEND_JIT_SRC="jit/zend_jit.c jit/zend_jit_gdb.c jit/zend_jit_vm_helpers.c"
5451

5552
dnl Find out which ABI we are using.
@@ -78,6 +75,14 @@ if test "$PHP_OPCACHE" != "no"; then
7875
DASM_FLAGS="$DASM_FLAGS -D ZTS=1"
7976
fi
8077

78+
PKG_CHECK_MODULES([CAPSTONE], [capstone >= 3.0.0],
79+
[have_capstone="yes"], [have_capstone="no"])
80+
if test "$have_capstone" = "yes"; then
81+
AC_DEFINE(HAVE_CAPSTONE, 1, [ ])
82+
PHP_EVAL_LIBLINE($CAPSTONE_LIBS, OPCACHE_SHARED_LIBADD)
83+
PHP_EVAL_INCLINE($CAPSTONE_CFLAGS)
84+
fi
85+
8186
PHP_SUBST(DASM_FLAGS)
8287
PHP_SUBST(DASM_ARCH)
8388

@@ -107,10 +112,9 @@ if test "$PHP_OPCACHE" != "no"; then
107112
])
108113
fi
109114

110-
else
111-
115+
elif test "$PHP_OPCACHE_JIT_IR" = "yes"; then
116+
AC_DEFINE(HAVE_JIT, 1, [Define to enable JIT])
112117
AC_DEFINE(ZEND_JIT_IR, 1, [Use JIT IR framework])
113-
114118
ZEND_JIT_SRC="jit/zend_jit.c jit/zend_jit_vm_helpers.c jit/ir/ir.c jit/ir/ir_strtab.c \
115119
jit/ir/ir_cfg.c jit/ir/ir_sccp.c jit/ir/ir_gcm.c jit/ir/ir_ra.c jit/ir/ir_save.c \
116120
jit/ir/ir_dump.c jit/ir/ir_disasm.c jit/ir/ir_gdb.c jit/ir/ir_perf.c jit/ir/ir_check.c \
@@ -142,17 +146,6 @@ if test "$PHP_OPCACHE" != "no"; then
142146
;;
143147
esac
144148

145-
PHP_SUBST(IR_TARGET)
146-
PHP_SUBST(DASM_FLAGS)
147-
PHP_SUBST(DASM_ARCH)
148-
149-
JIT_CFLAGS="-I@ext_builddir@/jit/ir -D${IR_TARGET} -DIR_PHP"
150-
if test "$ZEND_DEBUG" = "yes"; then
151-
JIT_CFLAGS="${JIT_CFLAGS} -DIR_DEBUG"
152-
fi
153-
154-
fi
155-
156149
PKG_CHECK_MODULES([CAPSTONE], [capstone >= 3.0.0],
157150
[have_capstone="yes"], [have_capstone="no"])
158151
if test "$have_capstone" = "yes"; then
@@ -161,6 +154,14 @@ if test "$PHP_OPCACHE" != "no"; then
161154
PHP_EVAL_INCLINE($CAPSTONE_CFLAGS)
162155
fi
163156

157+
PHP_SUBST(IR_TARGET)
158+
PHP_SUBST(DASM_FLAGS)
159+
PHP_SUBST(DASM_ARCH)
160+
161+
JIT_CFLAGS="-I@ext_builddir@/jit/ir -D${IR_TARGET} -DIR_PHP"
162+
if test "$ZEND_DEBUG" = "yes"; then
163+
JIT_CFLAGS="${JIT_CFLAGS} -DIR_DEBUG"
164+
fi
164165
fi
165166

166167
AC_CHECK_FUNCS([mprotect])

ext/opcache/config.w32

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ if (PHP_OPCACHE != "no") {
55

66
ARG_ENABLE("opcache-jit", "whether to enable JIT", "yes");
77

8+
ARG_ENABLE("opcache-jit-ir", "whether to enable JIT based on IR framework", "no");
9+
810
ZEND_EXTENSION('opcache', "\
911
ZendAccelerator.c \
1012
zend_accelerator_blacklist.c \
@@ -18,7 +20,7 @@ if (PHP_OPCACHE != "no") {
1820
zend_shared_alloc.c \
1921
shared_alloc_win32.c", true, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
2022

21-
if (PHP_OPCACHE_JIT == "yes") {
23+
if (PHP_OPCACHE_JIT == "yes" && PHP_OPCACHE_JIT_IR == "no") {
2224
if (CHECK_HEADER_ADD_INCLUDE("dynasm/dasm_x86.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) {
2325
var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1";
2426
if (PHP_ZTS == "yes") {
@@ -37,6 +39,40 @@ if (PHP_OPCACHE != "no") {
3739
} else {
3840
WARNING("JIT not enabled, headers not found");
3941
}
42+
} else if (PHP_OPCACHE_JIT_IR == "yes") {
43+
if (CHECK_HEADER_ADD_INCLUDE("ir/ir.h", "CFLAGS_OPCACHE", PHP_OPCACHE + ";ext\\opcache\\jit")) {
44+
var dasm_flags = (X64 ? "-D X64=1" : "") + (X64 ? " -D X64WIN=1" : "") + " -D WIN=1";
45+
var ir_target = (X64 ? "IR_TARGET_X64" : "IR_TARGET_X86");
46+
47+
DEFINE("IR_TARGET", ir_target);
48+
DEFINE("DASM_FLAGS", dasm_flags);
49+
DEFINE("DASM_ARCH", "x86");
50+
51+
AC_DEFINE('HAVE_JIT', 1, 'Define to enable JIT');
52+
AC_DEFINE('ZEND_JIT_IR', 1, 'Use JIT IR framework');
53+
54+
ADD_FLAG("CFLAGS_OPCACHE", "/I \"ext\\opcache\\jit\\ir\" /D "+ir_target+" /D IR_PHP");
55+
if (PHP_DEBUG == "yes") {
56+
ADD_FLAG("CFLAGS_OPCACHE", "/D IR_DEBUG");
57+
}
58+
59+
if (CHECK_HEADER_ADD_INCLUDE("capstone\\capstone.h", "CFLAGS_OPCACHE", PHP_OPCACHE+ ";" + PHP_PHP_BUILD + "\\include") &&
60+
CHECK_LIB("capstone.lib", "opcache", PHP_OPCACHE)) {
61+
AC_DEFINE('HAVE_CAPSTONE', 1, 'capstone support enabled');
62+
}
63+
64+
ADD_MAKEFILE_FRAGMENT(configure_module_dirname + "\\jit\\Makefile.frag.w32");
65+
66+
ADD_SOURCES(configure_module_dirname + "\\jit",
67+
"zend_jit.c zend_jit_vm_helpers.c",
68+
"opcache", "ext\\opcache\\jit");
69+
ADD_SOURCES(configure_module_dirname + "\\jit\\ir",
70+
"ir.c ir_strtab.c ir_cfg.c ir_sccp.c ir_gcm.c ir_ra.c ir_save.c \
71+
ir_dump.c ir_disasm.c ir_check.c ir_patch.c ir_emit.c",
72+
"opcache", "ext\\opcache\\jit\\ir");
73+
} else {
74+
WARNING("JIT not enabled, headers not found");
75+
}
4076
}
4177

4278
ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname);

ext/opcache/jit/Makefile.frag.w32

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,48 @@
1+
!if "$(IR_TARGET)" != ""
2+
# New IR based JIT
3+
4+
$(BUILD_DIR)\\minilua.exe: ext\opcache\jit\ir\dynasm\minilua.c
5+
@if exist $(BUILD_DIR)\\minilua.exe del $(BUILD_DIR)\\minilua.exe
6+
$(PHP_CL) /Fo$(BUILD_DIR)\ /Fd$(BUILD_DIR)\ /Fp$(BUILD_DIR)\ /FR$(BUILD_DIR) /Fe$(BUILD_DIR)\minilua.exe ext\opcache\jit\ir\dynasm\minilua.c
7+
8+
ext\opcache\jit\ir\ir_emit_x86.h: ext\opcache\jit\ir\ir_x86.dasc $(BUILD_DIR)\\minilua.exe
9+
@if exist ext\opcache\jit\ir\ir_emit_x86.h del ext\opcache\jit\ir\ir_emit_x86.h
10+
$(BUILD_DIR)\\minilua.exe ext/opcache/jit/ir/dynasm/dynasm.lua $(DASM_FLAGS) -o $@ ext/opcache/jit/ir/ir_x86.dasc
11+
12+
$(BUILD_DIR)\\gen_ir_fold_hash.exe: ext\opcache\jit\ir\gen_ir_fold_hash.c ext\opcache\jit\ir\ir_strtab.c
13+
@if exist $(BUILD_DIR)\\gen_ir_fold_hash.exe del $(BUILD_DIR)\\gen_ir_fold_hash.exe
14+
$(PHP_CL) /D $(IR_TARGET) /Fo$(BUILD_DIR)\ /Fd$(BUILD_DIR)\ /Fp$(BUILD_DIR)\ /Fe$(BUILD_DIR)\\gen_ir_fold_hash.exe $**
15+
16+
ext\opcache\jit\ir\ir_fold_hash.h: $(BUILD_DIR)\\gen_ir_fold_hash.exe ext\opcache\jit\ir\ir_fold.h ext\opcache\jit\ir\ir.h
17+
@if exist ext\opcache\jit\ir\ir_fold_hash.h del ext\opcache\jit\ir\ir_fold_hash.h
18+
$(BUILD_DIR)\\gen_ir_fold_hash.exe < ext\opcache\jit\ir\ir_fold.h > ext\opcache\jit\ir\ir_fold_hash.h
19+
20+
$(BUILD_DIR)\ext\opcache\jit\ir\ir_ra.obj: \
21+
ext\opcache\jit\ir\ir.h \
22+
ext\opcache\jit\ir\ir_private.h \
23+
ext\opcache\jit\ir\ir_x86.h
24+
25+
$(BUILD_DIR)\ext\opcache\jit\ir\ir_emit.obj: \
26+
ext\opcache\jit\ir\ir.h \
27+
ext\opcache\jit\ir\ir_private.h \
28+
ext\opcache\jit\ir\ir_x86.h \
29+
ext\opcache\jit\ir\ir_emit_x86.h
30+
31+
$(BUILD_DIR)\ext\opcache\jit\ir\ir.obj: \
32+
ext\opcache\jit\ir\ir.h \
33+
ext\opcache\jit\ir\ir_private.h \
34+
ext\opcache\jit\ir\ir_fold.h \
35+
ext\opcache\jit\ir\ir_fold_hash.h
36+
37+
$(BUILD_DIR)\ext\opcache\jit\zend_jit.obj: \
38+
ext\opcache\jit\zend_jit_ir.c \
39+
ext\opcache\jit\zend_jit_helpers.c \
40+
ext\opcache\jit\ir\ir.h \
41+
ext\opcache\jit\ir\ir_builder.h
42+
43+
!else
44+
# Old DynAsm based JIT
45+
146
$(BUILD_DIR)\\minilua.exe: ext\opcache\jit\dynasm\minilua.c
247
@if exist $(BUILD_DIR)\\minilua.exe del $(BUILD_DIR)\\minilua.exe
348
$(PHP_CL) /Fo$(BUILD_DIR)\ /Fd$(BUILD_DIR)\ /Fp$(BUILD_DIR)\ /FR$(BUILD_DIR) /Fe$(BUILD_DIR)\minilua.exe ext\opcache\jit\dynasm\minilua.c
@@ -15,3 +60,4 @@ $(BUILD_DIR)\ext\opcache\jit\zend_jit.obj: \
1560
ext/opcache/jit/zend_jit_oprofile.c \
1661
ext/opcache/jit/zend_jit_trace.c \
1762
ext/opcache/jit/zend_jit_vtune.c
63+
!endif

ext/opcache/jit/zend_jit.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5456,10 +5456,11 @@ ZEND_EXT_API int zend_jit_startup(void *buf, size_t size, bool reattached)
54565456
if (!reattached) {
54575457
zend_jit_unprotect();
54585458
*dasm_ptr = dasm_buf;
5459-
#if _WIN32
5459+
#if defined(_WIN32) && !defined(ZEND_JIT_IR)
54605460
/* reserve space for global labels */
54615461
*dasm_ptr = (void**)*dasm_ptr + zend_lb_MAX;
54625462
#endif
5463+
*dasm_ptr = (void*)ZEND_MM_ALIGNED_SIZE_EX(((size_t)(*dasm_ptr)), 16);
54635464
zend_jit_protect();
54645465
}
54655466

ext/opcache/jit/zend_jit_ir.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,16 @@
3030
# define ZREG_FP 14 /* IR_REG_R14 */
3131
# define ZREG_IP 15 /* IR_REG_R15 */
3232
# define ZREG_FIRST_FPR 16
33-
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<12) | (1<<13) | (1<<14) | (1<<15)) /* all preserved registers */
33+
# if defined(_WIN64)
34+
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7) | (1<<12) | (1<<13) | (1<<14) | (1<<15))
35+
/*
36+
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<6) | (1<<7) | (1<<12) | (1<<13) | (1<<14) | (1<<15) | \
37+
(1<<(16+6)) | (1<<(16+7)) | (1<<(16+8)) | (1<<(16+9)) | (1<<(16+10)) | \
38+
(1<<(16+11)) | (1<<(16+12)) | (1<<(16+13)) | (1<<(16+14)) | (1<<(16+15)))
39+
*/
40+
# else
41+
# define IR_REGSET_PRESERVED ((1<<3) | (1<<5) | (1<<12) | (1<<13) | (1<<14) | (1<<15)) /* all preserved registers */
42+
# endif
3443
#elif defined(IR_TARGET_AARCH64)
3544
# define IR_REG_SP 31 /* IR_REG_RSP */
3645
# define ZREG_FP 27 /* IR_REG_X27 */
@@ -2467,7 +2476,7 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags)
24672476
jit->ctx.flags |= IR_FUNCTION;
24682477
/* Stack must be 16 byte aligned */
24692478
/* TODO: select stack size ??? */
2470-
#if defined(IR_TARGET_AARCH64)
2479+
#if defined(IR_TARGET_AARCH64) || defined(_WIN64)
24712480
jit->ctx.fixed_stack_frame_size = sizeof(void*) * 15;
24722481
#else
24732482
jit->ctx.fixed_stack_frame_size = sizeof(void*) * 7;
@@ -2476,6 +2485,9 @@ static void zend_jit_init_ctx(zend_jit_ctx *jit, uint32_t flags)
24762485
jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED & ~((1<<ZREG_FP) | (1<<ZREG_IP));
24772486
} else {
24782487
jit->ctx.fixed_save_regset = IR_REGSET_PRESERVED;
2488+
//#ifdef _WIN64
2489+
// jit->ctx.fixed_save_regset &= 0xffff; // TODO: don't save FP registers ???
2490+
//#endif
24792491
}
24802492
} else {
24812493
#ifdef ZEND_VM_HYBRID_JIT_RED_ZONE_SIZE
@@ -2671,6 +2683,7 @@ static int zend_jit_setup_stubs(void)
26712683
entry, size, (JIT_G(debug) & ZEND_JIT_DEBUG_ASM_ADDR) != 0, &jit.ctx, stderr);
26722684
}
26732685

2686+
#ifndef _WIN32
26742687
if (JIT_G(debug) & ZEND_JIT_DEBUG_GDB) {
26752688
// ir_mem_unprotect(entry, size);
26762689
ir_gdb_register(zend_jit_stubs[i].name, entry, size, 0, 0);
@@ -2683,6 +2696,7 @@ static int zend_jit_setup_stubs(void)
26832696
ir_perf_jitdump_register(zend_jit_stubs[i].name, entry, size);
26842697
}
26852698
}
2699+
#endif
26862700
}
26872701
zend_jit_free_ctx(&jit);
26882702
}
@@ -3088,13 +3102,16 @@ static int zend_jit_setup(void)
30883102
}
30893103
#endif
30903104

3091-
if (JIT_G(debug) & (ZEND_JIT_DEBUG_ASM|ZEND_JIT_DEBUG_ASM_STUBS)) {
3105+
if (JIT_G(debug) & (ZEND_JIT_DEBUG_ASM|ZEND_JIT_DEBUG_ASM_STUBS)) {
30923106
zend_jit_setup_disasm();
30933107
}
3108+
3109+
#ifndef _WIN32
30943110
if (JIT_G(debug) & ZEND_JIT_DEBUG_PERF_DUMP) {
30953111
ir_perf_jitdump_open();
30963112
}
30973113

3114+
#endif
30983115
zend_long debug = JIT_G(debug);
30993116
if (!(debug & ZEND_JIT_DEBUG_ASM_STUBS)) {
31003117
JIT_G(debug) &= ~(ZEND_JIT_DEBUG_IR_SRC|ZEND_JIT_DEBUG_IR_FINAL|ZEND_JIT_DEBUG_IR_CFG|ZEND_JIT_DEBUG_IR_REGS|
@@ -3116,13 +3133,15 @@ static int zend_jit_setup(void)
31163133

31173134
static void zend_jit_shutdown_ir(void)
31183135
{
3136+
#ifndef _WIN32
31193137
if (JIT_G(debug) & ZEND_JIT_DEBUG_PERF_DUMP) {
31203138
ir_perf_jitdump_close();
31213139
}
31223140
if (JIT_G(debug) & ZEND_JIT_DEBUG_GDB) {
31233141
ir_gdb_unregister_all();
31243142
}
3125-
if (JIT_G(debug) & (ZEND_JIT_DEBUG_ASM|ZEND_JIT_DEBUG_ASM_STUBS)) {
3143+
#endif
3144+
if (JIT_G(debug) & (ZEND_JIT_DEBUG_ASM|ZEND_JIT_DEBUG_ASM_STUBS)) {
31263145
ir_disasm_free();
31273146
}
31283147
}
@@ -15109,6 +15128,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit)
1510915128
&jit->ctx, stderr);
1511015129
}
1511115130

15131+
#ifndef _WIN32
1511215132
if (str) {
1511315133
if (JIT_G(debug) & ZEND_JIT_DEBUG_GDB) {
1511415134
uintptr_t sp_offset = 0;
@@ -15135,6 +15155,7 @@ static void *zend_jit_finish(zend_jit_ctx *jit)
1513515155
}
1513615156
}
1513715157
}
15158+
#endif
1513815159
}
1513915160

1514015161
if (jit->op_array) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ static uint32_t zend_jit_exit_point_by_addr(void *addr)
161161
}
162162
}
163163
ZEND_ASSERT(0 && "inalid addr");
164+
return 0;
164165
}
165166
#endif
166167

0 commit comments

Comments
 (0)