Skip to content

Commit 18c9ee5

Browse files
committed
Refactor information about FFI calls
1 parent 7998262 commit 18c9ee5

File tree

3 files changed

+83
-47
lines changed

3 files changed

+83
-47
lines changed

ext/opcache/jit/zend_jit_internal.h

+26-17
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,11 @@ struct _zend_jit_trace_stack_frame {
555555
int used_stack;
556556
int old_checked_stack;
557557
int old_peek_checked_stack;
558+
#ifdef HAVE_FFI
559+
uint32_t ffi_info;
560+
int ffi_obj_ref;
561+
int ffi_func_ref;
562+
#endif
558563
zend_jit_trace_stack stack[1];
559564
};
560565

@@ -575,23 +580,24 @@ struct _zend_jit_trace_stack_frame {
575580
#define TRACE_FRAME_MASK_ALWAYS_RELEASE_THIS 0x00000400
576581

577582
#define TRACE_FRAME_MASK_FFI 0x00000800
578-
#define TRACE_FRAME_MASK_FFI_FUNC 0x0000f000
579-
580-
#define TRACE_FRAME_FFI_FUNC_NEW 0x00001000
581-
#define TRACE_FRAME_FFI_FUNC_FREE 0x00002000
582-
#define TRACE_FRAME_FFI_FUNC_CAST 0x00003000
583-
#define TRACE_FRAME_FFI_FUNC_TYPEOF 0x00004000
584-
#define TRACE_FRAME_FFI_FUNC_ARRAY_TYPE 0x00005000
585-
#define TRACE_FRAME_FFI_FUNC_ADDR 0x00006000
586-
#define TRACE_FRAME_FFI_FUNC_ALIGNOF 0x00007000
587-
#define TRACE_FRAME_FFI_FUNC_SIZEOF 0x00008000
588-
#define TRACE_FRAME_FFI_FUNC_MEMCPY 0x00009000
589-
#define TRACE_FRAME_FFI_FUNC_MEMCMP 0x0000a000
590-
#define TRACE_FRAME_FFI_FUNC_MEMSET 0x0000b000
591-
#define TRACE_FRAME_FFI_FUNC_STRING 0x0000c000
592-
#define TRACE_FRAME_FFI_FUNC_IS_NULL 0x0000d000
593-
#define TRACE_FRAME_FFI_FUNC_TYPE 0x0000e000
594583

584+
#define TRACE_FRAME_FFI_FUNC_NEW 0x00000001
585+
#define TRACE_FRAME_FFI_FUNC_FREE 0x00000002
586+
#define TRACE_FRAME_FFI_FUNC_CAST 0x00000003
587+
#define TRACE_FRAME_FFI_FUNC_TYPEOF 0x00000004
588+
#define TRACE_FRAME_FFI_FUNC_ARRAY_TYPE 0x00000005
589+
#define TRACE_FRAME_FFI_FUNC_ADDR 0x00000006
590+
#define TRACE_FRAME_FFI_FUNC_ALIGNOF 0x00000007
591+
#define TRACE_FRAME_FFI_FUNC_SIZEOF 0x00000008
592+
#define TRACE_FRAME_FFI_FUNC_MEMCPY 0x00000009
593+
#define TRACE_FRAME_FFI_FUNC_MEMCMP 0x0000000a
594+
#define TRACE_FRAME_FFI_FUNC_MEMSET 0x0000000b
595+
#define TRACE_FRAME_FFI_FUNC_STRING 0x0000000c
596+
#define TRACE_FRAME_FFI_FUNC_IS_NULL 0x0000000d
597+
#define TRACE_FRAME_FFI_FUNC_TYPE 0x0000000e
598+
599+
#define TRACE_FRAME_MASK_FFI_FUNC 0x0000000f
600+
#define TRACE_FRAME_MASK_FFI_OBJ_DTOR 0x00000010
595601

596602
#define TRACE_FRAME_INIT(frame, _func, _flags, num_args) do { \
597603
zend_jit_trace_stack_frame *_frame = (frame); \
@@ -632,8 +638,11 @@ struct _zend_jit_trace_stack_frame {
632638
((frame)->_info & TRACE_FRAME_MASK_ALWAYS_RELEASE_THIS)
633639
#define TRACE_FRAME_FFI(frame) \
634640
((frame)->_info & TRACE_FRAME_MASK_FFI)
641+
635642
#define TRACE_FRAME_FFI_FUNC(frame) \
636-
((frame)->_info & TRACE_FRAME_MASK_FFI_FUNC)
643+
((frame)->ffi_info & TRACE_FRAME_MASK_FFI_FUNC)
644+
#define TRACE_FRAME_FFI_OBJ_DTOR(frame) \
645+
((frame)->ffi_info & TRACE_FRAME_MASK_FFI_OBJ_DTOR)
637646

638647
#define TRACE_FRAME_SET_UNKNOWN_NUM_ARGS(frame) do { \
639648
(frame)->_info |= (0xffffu << TRACE_FRAME_SHIFT_NUM_ARGS); \

ext/opcache/jit/zend_jit_ir_ffi.c

+11-7
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,6 @@ static int zend_jit_ffi_init_call_sym(zend_jit_ctx *jit,
110110
return 0;
111111
}
112112

113-
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
114-
// TODO: usually the object is released only after the call ???
115-
jit_GC_DELREF(jit, jit_Z_PTR(jit, op1_addr));
116-
}
117-
118113
if (type->func.abi == ZEND_FFI_ABI_FASTCALL) {
119114
*ffi_func_ref = ir_CONST_FC_FUNC(sym->addr);
120115
} else {
@@ -752,7 +747,7 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
752747
zend_jit_trace_stack_frame *call = JIT_G(current_frame)->call;
753748
zend_jit_trace_stack *stack = call->stack;
754749
zend_ffi_type *type = (zend_ffi_type*)(void*)call->call_opline;
755-
ir_ref func_ref = (intptr_t)(void*)call->ce;
750+
ir_ref func_ref = call->ffi_func_ref;
756751
uint32_t i, num_args = TRACE_FRAME_NUM_ARGS(call);;
757752
ir_type ret_type = IR_VOID;
758753
ir_ref ref = IR_UNUSED;
@@ -1251,13 +1246,22 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
12511246
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_NEW
12521247
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_CAST
12531248
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_TYPE) {
1254-
func_ref = (intptr_t)(void*)call->ce;
1249+
func_ref = call->ffi_func_ref;
12551250
if (func_ref && !IR_IS_CONST_REF(func_ref)) {
12561251
ir_ref if_not_zero = ir_IF(jit_GC_DELREF(jit, func_ref));
12571252
ir_IF_FALSE(if_not_zero);
12581253
jit_ZVAL_DTOR(jit, func_ref, MAY_BE_OBJECT, opline);
12591254
ir_MERGE_WITH_EMPTY_TRUE(if_not_zero); /* don't add to GC roots */
12601255
}
1256+
if (TRACE_FRAME_FFI_OBJ_DTOR(call)) {
1257+
ir_ref obj_ref = call->ffi_obj_ref;
1258+
1259+
ZEND_ASSERT(obj_ref && !IR_IS_CONST_REF(obj_ref));
1260+
ir_ref if_not_zero = ir_IF(jit_GC_DELREF(jit, obj_ref));
1261+
ir_IF_FALSE(if_not_zero);
1262+
jit_ZVAL_DTOR(jit, obj_ref, MAY_BE_OBJECT, opline);
1263+
ir_MERGE_WITH_EMPTY_TRUE(if_not_zero); /* don't add to GC roots */
1264+
}
12611265
}
12621266

12631267
return 1;

ext/opcache/jit/zend_jit_trace.c

+46-23
Original file line numberDiff line numberDiff line change
@@ -4299,6 +4299,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
42994299
#ifdef HAVE_FFI
43004300
zend_jit_ffi_info *ffi_info = NULL;
43014301
zend_ffi_type *frame_ffi_func_type = NULL;
4302+
uint32_t frame_ffi_info = 0;
4303+
ir_ref frame_ffi_obj_ref = IR_UNUSED;
43024304
ir_ref frame_ffi_func_ref = IR_UNUSED;
43034305
#endif
43044306

@@ -4647,6 +4649,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
46474649
frame_flags = 0;
46484650
#ifdef HAVE_FFI
46494651
frame_ffi_func_type = NULL;
4652+
frame_ffi_info = 0;
4653+
frame_ffi_obj_ref = IR_UNUSED;
46504654
frame_ffi_func_ref = IR_UNUSED;
46514655
#endif
46524656

@@ -7011,12 +7015,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
70117015
goto jit_failure;
70127016
}
70137017
// TODO: Guard for FFI::CType argument ???
7014-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_NEW;
7018+
frame_flags = TRACE_FRAME_MASK_FFI;
7019+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_NEW;
70157020
frame_ffi_func_type = type;
7021+
frame_ffi_func_ref = IR_UNUSED;
7022+
frame_ffi_obj_ref = jit_Z_PTR(jit, op1_addr);
70167023
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
7017-
frame_ffi_func_ref = jit_Z_PTR(jit, op1_addr);
7018-
} else {
7019-
frame_ffi_func_ref = IR_UNUSED;
7024+
frame_ffi_info |= TRACE_FRAME_MASK_FFI_OBJ_DTOR;
70207025
}
70217026
goto done;
70227027
}
@@ -7031,12 +7036,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
70317036
goto jit_failure;
70327037
}
70337038
// TODO: Guard for FFI::CType argument ???
7034-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_CAST;
7039+
frame_flags = TRACE_FRAME_MASK_FFI;
7040+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_CAST;
70357041
frame_ffi_func_type = type;
7042+
frame_ffi_func_ref = IR_UNUSED;
7043+
frame_ffi_obj_ref = jit_Z_PTR(jit, op1_addr);
70367044
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
7037-
frame_ffi_func_ref = jit_Z_PTR(jit, op1_addr);
7038-
} else {
7039-
frame_ffi_func_ref = IR_UNUSED;
7045+
frame_ffi_info |= TRACE_FRAME_MASK_FFI_OBJ_DTOR;
70407046
}
70417047
goto done;
70427048
}
@@ -7062,12 +7068,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
70627068
ssa_op->op1_use, -1, op1_info, op1_addr, op1_ffi_symbols, ffi_info)) {
70637069
goto jit_failure;
70647070
}
7065-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_TYPE;
7071+
frame_flags = TRACE_FRAME_MASK_FFI;
7072+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_TYPE;
70667073
frame_ffi_func_type = dcl->type;
7074+
frame_ffi_func_ref = IR_UNUSED;
7075+
frame_ffi_obj_ref = jit_Z_PTR(jit, op1_addr);
70677076
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
7068-
frame_ffi_func_ref = jit_Z_PTR(jit, op1_addr);
7069-
} else {
7070-
frame_ffi_func_ref = IR_UNUSED;
7077+
frame_ffi_info |= TRACE_FRAME_MASK_FFI_OBJ_DTOR;
70717078
}
70727079
goto done;
70737080
}
@@ -7093,6 +7100,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
70937100
frame_flags = TRACE_FRAME_MASK_FFI;
70947101
frame_ffi_func_type = ZEND_FFI_TYPE(sym->type);
70957102
frame_ffi_func_ref = ffi_func_ref;
7103+
frame_ffi_obj_ref = jit_Z_PTR(jit, op1_addr);
7104+
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
7105+
frame_ffi_info |= TRACE_FRAME_MASK_FFI_OBJ_DTOR;
7106+
}
70967107
goto done;
70977108
}
70987109
}
@@ -7130,70 +7141,80 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
71307141
if (Z_TYPE_P(zv) == IS_STRING
71317142
&& zend_string_equals_literal_ci(Z_STR_P(zv), "addr")
71327143
&& opline->extended_value == 1) {
7133-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_ADDR;
7144+
frame_flags = TRACE_FRAME_MASK_FFI;
7145+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_ADDR;
71347146
frame_ffi_func_type = NULL;
71357147
frame_ffi_func_ref = IR_UNUSED;
71367148
goto done;
71377149
} else if (Z_TYPE_P(zv) == IS_STRING
71387150
&& zend_string_equals_literal_ci(Z_STR_P(zv), "string")
71397151
&& (opline->extended_value == 1 || opline->extended_value == 2)) {
7140-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_STRING;
7152+
frame_flags = TRACE_FRAME_MASK_FFI;
7153+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_STRING;
71417154
frame_ffi_func_type = NULL;
71427155
frame_ffi_func_ref = IR_UNUSED;
71437156
goto done;
71447157
} else if (Z_TYPE_P(zv) == IS_STRING
71457158
&& zend_string_equals_literal_ci(Z_STR_P(zv), "alignof")
71467159
&& opline->extended_value == 1) {
7147-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_ALIGNOF;
7160+
frame_flags = TRACE_FRAME_MASK_FFI;
7161+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_ALIGNOF;
71487162
frame_ffi_func_type = NULL;
71497163
frame_ffi_func_ref = IR_UNUSED;
71507164
goto done;
71517165
} else if (Z_TYPE_P(zv) == IS_STRING
71527166
&& zend_string_equals_literal_ci(Z_STR_P(zv), "sizeof")
71537167
&& opline->extended_value == 1) {
7154-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_SIZEOF;
7168+
frame_flags = TRACE_FRAME_MASK_FFI;
7169+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_SIZEOF;
71557170
frame_ffi_func_type = NULL;
71567171
frame_ffi_func_ref = IR_UNUSED;
71577172
goto done;
71587173
} else if (Z_TYPE_P(zv) == IS_STRING
71597174
&& zend_string_equals_literal_ci(Z_STR_P(zv), "typeof")
71607175
&& opline->extended_value == 1) {
7161-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_TYPEOF;
7176+
frame_flags = TRACE_FRAME_MASK_FFI;
7177+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_TYPEOF;
71627178
frame_ffi_func_type = NULL;
71637179
frame_ffi_func_ref = IR_UNUSED;
71647180
goto done;
71657181
} else if (Z_TYPE_P(zv) == IS_STRING
71667182
&& zend_string_equals_literal_ci(Z_STR_P(zv), "isnull")
71677183
&& opline->extended_value == 1) {
7168-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_IS_NULL;
7184+
frame_flags = TRACE_FRAME_MASK_FFI;
7185+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_IS_NULL;
71697186
frame_ffi_func_type = NULL;
71707187
frame_ffi_func_ref = IR_UNUSED;
71717188
goto done;
71727189
} else if (Z_TYPE_P(zv) == IS_STRING
71737190
&& zend_string_equals_literal_ci(Z_STR_P(zv), "memcpy")
71747191
&& opline->extended_value == 3) {
7175-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_MEMCPY;
7192+
frame_flags = TRACE_FRAME_MASK_FFI;
7193+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_MEMCPY;
71767194
frame_ffi_func_type = NULL;
71777195
frame_ffi_func_ref = IR_UNUSED;
71787196
goto done;
71797197
} else if (Z_TYPE_P(zv) == IS_STRING
71807198
&& zend_string_equals_literal_ci(Z_STR_P(zv), "memcmp")
71817199
&& opline->extended_value == 3) {
7182-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_MEMCMP;
7200+
frame_flags = TRACE_FRAME_MASK_FFI;
7201+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_MEMCMP;
71837202
frame_ffi_func_type = NULL;
71847203
frame_ffi_func_ref = IR_UNUSED;
71857204
goto done;
71867205
} else if (Z_TYPE_P(zv) == IS_STRING
71877206
&& zend_string_equals_literal_ci(Z_STR_P(zv), "memset")
71887207
&& opline->extended_value == 3) {
7189-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_MEMSET;
7208+
frame_flags = TRACE_FRAME_MASK_FFI;
7209+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_MEMSET;
71907210
frame_ffi_func_type = NULL;
71917211
frame_ffi_func_ref = IR_UNUSED;
71927212
goto done;
71937213
} else if (Z_TYPE_P(zv) == IS_STRING
71947214
&& zend_string_equals_literal_ci(Z_STR_P(zv), "free")
71957215
&& opline->extended_value == 1) {
7196-
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_FREE;
7216+
frame_flags = TRACE_FRAME_MASK_FFI;
7217+
frame_ffi_info = TRACE_FRAME_FFI_FUNC_FREE;
71977218
frame_ffi_func_type = NULL;
71987219
frame_ffi_func_ref = IR_UNUSED;
71997220
goto done;
@@ -7854,7 +7875,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
78547875
#ifdef HAVE_FFI
78557876
if (TRACE_FRAME_FFI(call)) {
78567877
call->call_opline = (const zend_op*)(void*)frame_ffi_func_type;
7857-
call->ce = (zend_class_entry*)(intptr_t)frame_ffi_func_ref;
7878+
call->ffi_info = frame_ffi_info;
7879+
call->ffi_obj_ref = frame_ffi_obj_ref;
7880+
call->ffi_func_ref = frame_ffi_func_ref;
78587881
}
78597882
#endif
78607883
call->prev = frame->call;

0 commit comments

Comments
 (0)