Skip to content

Commit 5a8968e

Browse files
committed
ext/opcache/jit: add some API documentation
1 parent 4f79661 commit 5a8968e

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,12 +115,48 @@ static int zend_jit_vm_kind = 0;
115115
static bool zend_write_protect = true;
116116
#endif
117117

118+
/**
119+
* Start of the shared memory area to contain JIT machine code. Call
120+
* zend_jit_unprotect() before writing to it, and call
121+
* zend_jit_protect() when done.
122+
*
123+
* #dasmn_end is the end of the area and #dasm_ptr points to the end
124+
* of the portion that is really used currently.
125+
*
126+
* This area is allocated during startup and is never changed.
127+
* Allocations are linear by incrementing #dasm_ptr.
128+
*/
118129
static void *dasm_buf = NULL;
130+
131+
/**
132+
* End of the shared memory area to contain JIT machine code.
133+
*/
119134
static void *dasm_end = NULL;
135+
136+
/**
137+
* Pointer to pointer to end of the used portion of the shared memory
138+
* area to contain JIT machine code.
139+
*
140+
* This "pointer to pointer" points to inside the shared memory area,
141+
* because it needs to be shared across all processes/threads. All
142+
* accesses to the pointed-to pointer need to be protected using
143+
* zend_shared_alloc_lock().
144+
*
145+
* Additionally, dasm_ptr[1] contains a pointer to the end of the
146+
* stubs and veneers. This is used by zend_jit_restart() to free all
147+
* JIT-generated functions, but keep those stubs and veneers.
148+
*/
120149
static void **dasm_ptr = NULL;
121150

151+
/**
152+
* The total size of the #dasm_buf, including the trailer which
153+
* #dasm_ptr points to (after #dasm_end).
154+
*/
122155
static size_t dasm_size = 0;
123156

157+
/**
158+
* Counter for checking the opcache.jit_bisect_limit setting.
159+
*/
124160
static zend_long jit_bisect_pos = 0;
125161

126162
static const void *zend_jit_runtime_jit_handler = NULL;
@@ -805,6 +841,10 @@ ZEND_EXT_API void zend_jit_status(zval *ret)
805841
add_assoc_zval(ret, "jit", &stats);
806842
}
807843

844+
/**
845+
* Generate a name for a JIT-generated native function (for the
846+
* disassembler and for external debuggers/profilers/tracers).
847+
*/
808848
static zend_string *zend_jit_func_name(const zend_op_array *op_array)
809849
{
810850
smart_str buf = {0};
@@ -2677,6 +2717,10 @@ static bool zend_jit_supported_binary_op(zend_uchar op, uint32_t op1_info, uint3
26772717
}
26782718
}
26792719

2720+
/**
2721+
* Caller must have called zend_shared_alloc_lock() and
2722+
* zend_jit_unprotect().
2723+
*/
26802724
static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_opline)
26812725
{
26822726
int b, i, end;
@@ -4717,6 +4761,9 @@ static void zend_jit_init_handlers(void)
47174761
}
47184762
}
47194763

4764+
/**
4765+
* Generate all JIT stub functions.
4766+
*/
47204767
static bool zend_jit_make_stubs(void)
47214768
{
47224769
dasm_State* dasm_state = NULL;

ext/opcache/jit/zend_jit.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ typedef struct _zend_jit_globals {
119119

120120
zend_sym_node *symbols; /* symbols for disassembler */
121121

122+
/**
123+
* True while zend_jit_trace_execute() runs, to avoid
124+
* recursively calling it twice.
125+
*/
122126
bool tracing;
123127

124128
zend_jit_trace_rec *current_trace;
@@ -140,10 +144,36 @@ extern int jit_globals_id;
140144
extern zend_jit_globals jit_globals;
141145
#endif
142146

147+
/**
148+
* Activate the JIT on the given #zend_op_array.
149+
*
150+
* @return SUCCESS or FAILURE
151+
*/
143152
ZEND_EXT_API int zend_jit_op_array(zend_op_array *op_array, zend_script *script);
153+
154+
/**
155+
* Activate the JIT on the given #zend_script.
156+
*
157+
* @return SUCCESS or FAILURE
158+
*/
144159
ZEND_EXT_API int zend_jit_script(zend_script *script);
160+
161+
/**
162+
* Make the JIT machine code area (i.e. #dasm_buf) writable (but not
163+
* executable). Call this before generating new machine code. Call
164+
* zend_jit_protect() when done.
165+
*
166+
* (These write/execute permissions affect only the current process.)
167+
*/
145168
ZEND_EXT_API void zend_jit_unprotect(void);
169+
170+
/**
171+
* Make the JIT machine code area (i.e. #dasm_buf) executable (but not
172+
* writable). Call this after generating new machine code to undo the
173+
* effect of zend_jit_unprotect().
174+
*/
146175
ZEND_EXT_API void zend_jit_protect(void);
176+
147177
ZEND_EXT_API void zend_jit_init(void);
148178
ZEND_EXT_API int zend_jit_config(zend_string *jit_options, int stage);
149179
ZEND_EXT_API int zend_jit_debug_config(zend_long old_val, zend_long new_val, int stage);

ext/opcache/jit/zend_jit_internal.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,18 @@ static zend_always_inline bool zend_jit_same_addr(zend_jit_addr addr1, zend_jit_
219219
return 0;
220220
}
221221

222+
/**
223+
* #ZEND_FUNC_INFO for functions handled by the JIT with trigger
224+
* #ZEND_JIT_ON_FIRST_EXEC or #ZEND_JIT_ON_PROF_REQUEST. The handler
225+
* #override is zend_jit_runtime_jit_handler().
226+
*/
222227
typedef struct _zend_jit_op_array_extension {
223228
zend_func_info func_info;
229+
230+
/**
231+
* The original opcode handler, just in case we need to
232+
* restore it.
233+
*/
224234
const void *orig_handler;
225235
} zend_jit_op_array_extension;
226236

@@ -252,9 +262,24 @@ static zend_always_inline zend_long zend_jit_hash(const void *ptr)
252262

253263
void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend_op *opline);
254264

265+
/**
266+
* #ZEND_FUNC_INFO for functions being handled by the JIT with trigger
267+
* #ZEND_JIT_ON_HOT_COUNTERS. The handler override is
268+
* #zend_jit_func_hot_counter_handler().
269+
*/
255270
typedef struct _zend_jit_op_array_hot_extension {
256271
zend_func_info func_info;
272+
273+
/**
274+
* Pointer to the counter. Points to inside global variable
275+
* #zend_jit_hot_counters.
276+
*/
257277
int16_t *counter;
278+
279+
/**
280+
* The original handler for each opline, just in case we need
281+
* to restore it.
282+
*/
258283
const void *orig_handlers[1];
259284
} zend_jit_op_array_hot_extension;
260285

@@ -392,10 +417,29 @@ typedef enum _zend_jit_trace_stop {
392417
#define ZEND_JIT_TRACE_START_RETURN (1<<2)
393418
#define ZEND_JIT_TRACE_START_SIDE (1<<3) /* used for side traces */
394419

420+
/**
421+
* Was this opline already processed by the JIT? This is used to skip
422+
* further JIT calls.
423+
*/
395424
#define ZEND_JIT_TRACE_JITED (1<<4)
425+
426+
/**
427+
* Was this opline blacklisted by the JIT? Blacklisted oplines will
428+
* never be inspected again by the JIT.
429+
*/
396430
#define ZEND_JIT_TRACE_BLACKLISTED (1<<5)
431+
432+
/**
433+
* Is this opline supported by the JIT? This is determined by
434+
* zend_jit_trace_supported().
435+
*/
397436
#define ZEND_JIT_TRACE_UNSUPPORTED (1<<6)
398437

438+
/**
439+
* Not an actual trace_flag; just a descriptive macro indicating the
440+
* absence of #ZEND_JIT_TRACE_UNSUPPORTED for the
441+
* zend_jit_trace_supported() return value.
442+
*/
399443
#define ZEND_JIT_TRACE_SUPPORTED 0
400444

401445
#define ZEND_JIT_EXIT_JITED (1<<0)
@@ -410,20 +454,47 @@ typedef enum _zend_jit_trace_stop {
410454
#define ZEND_JIT_EXIT_METHOD_CALL (1<<9) /* exit because of polymorphic INIT_METHOD_CALL call */
411455
#define ZEND_JIT_EXIT_INVALIDATE (1<<10) /* invalidate current trace */
412456

457+
/**
458+
* Per-opline information for #zend_jit_op_array_trace_extension.
459+
*/
413460
typedef union _zend_op_trace_info {
414461
zend_op dummy; /* the size of this structure must be the same as zend_op */
415462
struct {
463+
/**
464+
* The original opcode handler, just in case we need
465+
* to restore it.
466+
*/
416467
const void *orig_handler;
417468
const void *call_handler;
469+
470+
/**
471+
* Pointer to the counter. Points to inside global variable
472+
* #zend_jit_hot_counters.
473+
*/
418474
int16_t *counter;
475+
476+
/**
477+
* Bit mask of the ZEND_JIT_TRACE_* flags.
478+
*/
419479
uint8_t trace_flags;
420480
};
421481
} zend_op_trace_info;
422482

483+
/**
484+
* #ZEND_FUNC_INFO for functions handled by the JIT with trigger
485+
* #ZEND_JIT_ON_HOT_TRACE. The handler override is
486+
* #zend_jit_loop_trace_counter_handler() or
487+
* #zend_jit_func_trace_counter_handler(), configured by
488+
* #zend_jit_setup_hot_trace_counters().
489+
*/
423490
typedef struct _zend_jit_op_array_trace_extension {
424491
zend_func_info func_info;
425492
const zend_op_array *op_array;
426493
size_t offset; /* offset from "zend_op" to corresponding "op_info" */
494+
495+
/**
496+
* Information for each opline.
497+
*/
427498
zend_op_trace_info trace_info[1];
428499
} zend_jit_op_array_trace_extension;
429500

ext/opcache/jit/zend_jit_trace.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3970,6 +3970,10 @@ static bool zend_jit_trace_next_is_send_result(const zend_op *oplin
39703970
return false;
39713971
}
39723972

3973+
/**
3974+
* Caller must have called zend_shared_alloc_lock() and
3975+
* zend_jit_unprotect().
3976+
*/
39733977
static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t parent_trace, uint32_t exit_num)
39743978
{
39753979
const void *handler = NULL;

0 commit comments

Comments
 (0)