Skip to content

Commit 9a06876

Browse files
committed
Added JIT compiler for x86 and x86_64
1 parent a0fbb64 commit 9a06876

File tree

148 files changed

+51909
-36
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

148 files changed

+51909
-36
lines changed

TSRM/TSRM.c

+20
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,26 @@ TSRM_API void *tsrm_get_ls_cache(void)
761761
return tsrm_tls_get();
762762
}/*}}}*/
763763

764+
/* Returns offset of tsrm_ls_cache slot from Thread Control Block address */
765+
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void)
766+
{/*{{{*/
767+
#if defined(__x86_64__) && defined(__GNUC__)
768+
size_t ret;
769+
770+
asm ("movq _tsrm_ls_cache@gottpoff(%%rip),%0"
771+
: "=r" (ret));
772+
return ret;
773+
#elif defined(__i386__) && defined(__GNUC__)
774+
size_t ret;
775+
776+
asm ("leal _tsrm_ls_cache@ntpoff,%0"
777+
: "=r" (ret));
778+
return ret;
779+
#else
780+
return 0;
781+
#endif
782+
}/*}}}*/
783+
764784
TSRM_API uint8_t tsrm_is_main_thread(void)
765785
{/*{{{*/
766786
return in_main_thread;

TSRM/TSRM.h

+1
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ TSRM_API void *tsrm_set_new_thread_end_handler(tsrm_thread_end_func_t new_thread
137137
TSRM_API void *tsrm_set_shutdown_handler(tsrm_shutdown_func_t shutdown_handler);
138138

139139
TSRM_API void *tsrm_get_ls_cache(void);
140+
TSRM_API size_t tsrm_get_ls_cache_tcb_offset(void);
140141
TSRM_API uint8_t tsrm_is_main_thread(void);
141142
TSRM_API const char *tsrm_api_name(void);
142143

Zend/zend_gdb.c

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Zend Engine |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 2.00 of the Zend license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.zend.com/license/2_00.txt. |
11+
| If you did not receive a copy of the Zend license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Authors: Dmitry Stogov <[email protected]> |
16+
| Xinchen Hui <[email protected]> |
17+
+----------------------------------------------------------------------+
18+
*/
19+
20+
#include "zend.h"
21+
#include "zend_gdb.h"
22+
23+
#include <sys/types.h>
24+
#include <sys/stat.h>
25+
#include <fcntl.h>
26+
#include <unistd.h>
27+
28+
enum {
29+
ZEND_GDBJIT_NOACTION,
30+
ZEND_GDBJIT_REGISTER,
31+
ZEND_GDBJIT_UNREGISTER
32+
};
33+
34+
typedef struct _zend_gdbjit_code_entry {
35+
struct _zend_gdbjit_code_entry *next_entry;
36+
struct _zend_gdbjit_code_entry *prev_entry;
37+
const char *symfile_addr;
38+
uint64_t symfile_size;
39+
} zend_gdbjit_code_entry;
40+
41+
typedef struct _zend_gdbjit_descriptor {
42+
uint32_t version;
43+
uint32_t action_flag;
44+
struct _zend_gdbjit_code_entry *relevant_entry;
45+
struct _zend_gdbjit_code_entry *first_entry;
46+
} zend_gdbjit_descriptor;
47+
48+
ZEND_API zend_gdbjit_descriptor __jit_debug_descriptor = {
49+
1, ZEND_GDBJIT_NOACTION, NULL, NULL
50+
};
51+
52+
ZEND_API zend_never_inline void __jit_debug_register_code()
53+
{
54+
__asm__ __volatile__("");
55+
}
56+
57+
ZEND_API int zend_gdb_register_code(const void *object, size_t size)
58+
{
59+
zend_gdbjit_code_entry *entry;
60+
61+
entry = malloc(sizeof(zend_gdbjit_code_entry) + size);
62+
if (entry == NULL) {
63+
return 0;
64+
}
65+
66+
entry->symfile_addr = ((char*)entry) + sizeof(zend_gdbjit_code_entry);
67+
entry->symfile_size = size;
68+
69+
memcpy((char *)entry->symfile_addr, object, size);
70+
71+
entry->prev_entry = NULL;
72+
entry->next_entry = __jit_debug_descriptor.first_entry;
73+
74+
if (entry->next_entry) {
75+
entry->next_entry->prev_entry = entry;
76+
}
77+
__jit_debug_descriptor.first_entry = entry;
78+
79+
/* Notify GDB */
80+
__jit_debug_descriptor.relevant_entry = entry;
81+
__jit_debug_descriptor.action_flag = ZEND_GDBJIT_REGISTER;
82+
__jit_debug_register_code();
83+
84+
return 1;
85+
}
86+
87+
ZEND_API void zend_gdb_unregister_all(void)
88+
{
89+
zend_gdbjit_code_entry *entry;
90+
91+
__jit_debug_descriptor.action_flag = ZEND_GDBJIT_UNREGISTER;
92+
while ((entry = __jit_debug_descriptor.first_entry)) {
93+
__jit_debug_descriptor.first_entry = entry->next_entry;
94+
if (entry->next_entry) {
95+
entry->next_entry->prev_entry = NULL;
96+
}
97+
/* Notify GDB */
98+
__jit_debug_descriptor.relevant_entry = entry;
99+
__jit_debug_register_code();
100+
101+
free(entry);
102+
}
103+
}
104+
105+
ZEND_API int zend_gdb_present(void)
106+
{
107+
int ret = 0;
108+
int fd = open("/proc/self/status", O_RDONLY);
109+
110+
if (fd > 0) {
111+
char buf[1024];
112+
ssize_t n = read(fd, buf, sizeof(buf) - 1);
113+
char *s;
114+
pid_t pid;
115+
116+
if (n > 0) {
117+
buf[n] = 0;
118+
s = strstr(buf, "TracerPid:");
119+
if (s) {
120+
s += sizeof("TracerPid:") - 1;
121+
while (*s == ' ' || *s == '\t') {
122+
s++;
123+
}
124+
pid = atoi(s);
125+
if (pid) {
126+
sprintf(buf, "/proc/%d/exe", (int)pid);
127+
if (readlink(buf, buf, sizeof(buf) - 1) > 0) {
128+
if (strstr(buf, "gdb")) {
129+
ret = 1;
130+
}
131+
}
132+
}
133+
}
134+
}
135+
136+
close(fd);
137+
}
138+
139+
return ret;
140+
}

Zend/zend_gdb.h

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Zend Engine |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 2.00 of the Zend license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.zend.com/license/2_00.txt. |
11+
| If you did not receive a copy of the Zend license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Authors: Dmitry Stogov <[email protected]> |
16+
| Xinchen Hui <[email protected]> |
17+
+----------------------------------------------------------------------+
18+
*/
19+
20+
#ifndef ZEND_GDB
21+
#define ZEND_GDB
22+
23+
ZEND_API int zend_gdb_register_code(const void *object, size_t size);
24+
ZEND_API void zend_gdb_unregister_all(void);
25+
ZEND_API int zend_gdb_present(void);
26+
27+
#endif

configure.ac

+1-1
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,7 @@ PHP_ADD_SOURCES(Zend, \
15541554
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
15551555
zend_closures.c zend_weakrefs.c zend_float.c zend_string.c zend_signal.c zend_generators.c \
15561556
zend_virtual_cwd.c zend_ast.c zend_objects.c zend_object_handlers.c zend_objects_API.c \
1557-
zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c, \
1557+
zend_default_classes.c zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_gdb.c, \
15581558
-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1)
15591559

15601560
dnl Selectively disable optimization due to high RAM usage during

ext/opcache/ZendAccelerator.c

+72-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@
4646
#include "ext/pcre/php_pcre.h"
4747
#include "ext/standard/md5.h"
4848

49+
#ifdef HAVE_JIT
50+
# include "jit/zend_jit.h"
51+
#endif
52+
4953
#ifndef ZEND_WIN32
5054
#include <netdb.h>
5155
#endif
@@ -2394,13 +2398,25 @@ int accel_activate(INIT_FUNC_ARGS)
23942398
accel_reset_pcre_cache();
23952399
}
23962400

2401+
2402+
#ifdef HAVE_JIT
2403+
zend_jit_activate();
2404+
#endif
2405+
23972406
if (ZCSG(preload_script)) {
23982407
preload_activate();
23992408
}
24002409

24012410
return SUCCESS;
24022411
}
24032412

2413+
#ifdef HAVE_JIT
2414+
void accel_deactivate(void)
2415+
{
2416+
zend_jit_deactivate();
2417+
}
2418+
#endif
2419+
24042420
int accel_post_deactivate(void)
24052421
{
24062422
if (ZCG(cwd)) {
@@ -2813,12 +2829,46 @@ static int accel_post_startup(void)
28132829
}
28142830
}
28152831

2832+
/* Initialize zend_func_info_rid */
2833+
zend_optimizer_startup();
2834+
28162835
/********************************************/
28172836
/* End of non-SHM dependent initializations */
28182837
/********************************************/
28192838
file_cache_only = ZCG(accel_directives).file_cache_only;
28202839
if (!file_cache_only) {
2821-
switch (zend_shared_alloc_startup(ZCG(accel_directives).memory_consumption)) {
2840+
size_t shm_size = ZCG(accel_directives).memory_consumption;
2841+
#ifdef HAVE_JIT
2842+
size_t jit_size = 0;
2843+
zend_bool reattached = 0;
2844+
2845+
if (ZCG(accel_directives).jit &&
2846+
ZCG(accel_directives).jit_buffer_size) {
2847+
size_t page_size;
2848+
2849+
# ifdef _WIN32
2850+
SYSTEM_INFO system_info;
2851+
GetSystemInfo(&system_info);
2852+
page_size = system_info.dwPageSize;
2853+
# else
2854+
page_size = getpagesize();
2855+
# endif
2856+
if (!page_size || (page_size & (page_size - 1))) {
2857+
zend_accel_error(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - can't get page size.");
2858+
abort();
2859+
}
2860+
jit_size = ZCG(accel_directives).jit_buffer_size;
2861+
jit_size = ZEND_MM_ALIGNED_SIZE_EX(jit_size, page_size);
2862+
shm_size += jit_size;
2863+
} else {
2864+
ZCG(accel_directives).jit = 0;
2865+
ZCG(accel_directives).jit_buffer_size = 0;
2866+
}
2867+
2868+
switch (zend_shared_alloc_startup(shm_size, jit_size)) {
2869+
#else
2870+
switch (zend_shared_alloc_startup(shm_size, 0)) {
2871+
#endif
28222872
case ALLOC_SUCCESS:
28232873
if (zend_accel_init_shm() == FAILURE) {
28242874
accel_startup_ok = 0;
@@ -2830,6 +2880,9 @@ static int accel_post_startup(void)
28302880
zend_accel_error(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - probably not enough shared memory.");
28312881
return SUCCESS;
28322882
case SUCCESSFULLY_REATTACHED:
2883+
#ifdef HAVE_JIT
2884+
reattached = 1;
2885+
#endif
28332886
zend_shared_alloc_lock();
28342887
accel_shared_globals = (zend_accel_shared_globals *) ZSMMG(app_shared_globals);
28352888
zend_interned_strings_set_request_storage_handlers(accel_new_interned_string_for_php, accel_init_interned_string_for_php);
@@ -2861,6 +2914,16 @@ static int accel_post_startup(void)
28612914
zend_accel_init_auto_globals();
28622915

28632916
zend_shared_alloc_lock();
2917+
#ifdef HAVE_JIT
2918+
if (ZCG(accel_directives).jit &&
2919+
ZCG(accel_directives).jit_buffer_size &&
2920+
ZSMMG(reserved)) {
2921+
zend_jit_startup(ZCG(accel_directives).jit, ZSMMG(reserved), jit_size, reattached);
2922+
} else {
2923+
ZCG(accel_directives).jit = 0;
2924+
ZCG(accel_directives).jit_buffer_size = 0;
2925+
}
2926+
#endif
28642927
zend_shared_alloc_save_state();
28652928
zend_shared_alloc_unlock();
28662929

@@ -2944,6 +3007,10 @@ void accel_shutdown(void)
29443007
zend_ini_entry *ini_entry;
29453008
zend_bool _file_cache_only = 0;
29463009

3010+
#ifdef HAVE_JIT
3011+
zend_jit_shutdown();
3012+
#endif
3013+
29473014
zend_optimizer_shutdown();
29483015

29493016
zend_accel_blacklist_shutdown(&accel_blacklist);
@@ -4244,7 +4311,11 @@ ZEND_EXT_API zend_extension zend_extension_entry = {
42444311
accel_startup, /* startup */
42454312
NULL, /* shutdown */
42464313
NULL, /* per-script activation */
4314+
#ifdef HAVE_JIT
4315+
accel_deactivate, /* per-script deactivation */
4316+
#else
42474317
NULL, /* per-script deactivation */
4318+
#endif
42484319
NULL, /* message handler */
42494320
NULL, /* op_array handler */
42504321
NULL, /* extended statement handler */

ext/opcache/ZendAccelerator.h

+5
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ typedef struct _zend_accel_directives {
185185
zend_bool huge_code_pages;
186186
#endif
187187
char *preload;
188+
#ifdef HAVE_JIT
189+
zend_long jit;
190+
zend_long jit_buffer_size;
191+
zend_long jit_debug;
192+
#endif
188193
} zend_accel_directives;
189194

190195
typedef struct _zend_accel_globals {

0 commit comments

Comments
 (0)