Skip to content

Commit 6596e6e

Browse files
committed
JIT/FFI cleanup arguments
1 parent 6f89d0e commit 6596e6e

File tree

2 files changed

+86
-11
lines changed

2 files changed

+86
-11
lines changed

ext/opcache/jit/zend_jit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ void zend_jit_restart(void);
182182
#define ZREG_ZVAL_ADDREF (4<<4)
183183
#define ZREG_THIS (5<<4)
184184

185+
#define ZREG_FFI_PTR_LOAD (1<<3)
186+
#define ZREG_FFI_ZVAL_DTOR (1<<4)
187+
185188
#define ZREG_NONE -1
186189

187190
#endif /* HAVE_JIT_H */

ext/opcache/jit/zend_jit_ir_ffi.c

Lines changed: 83 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,7 @@ static int zend_jit_ffi_init_call_obj(zend_jit_ctx *jit,
9393
return 0;
9494
}
9595

96-
*ffi_func_ref = ir_LOAD_A(jit_FFI_CDATA_PTR(jit, obj_ref));
97-
if (type->func.abi == ZEND_FFI_ABI_FASTCALL) {
98-
*ffi_func_ref = ir_CAST_FC_FUNC(*ffi_func_ref);
99-
}
96+
*ffi_func_ref = obj_ref;
10097

10198
return 1;
10299
}
@@ -115,6 +112,8 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
115112
zend_jit_trace_stack *stack = call->stack;
116113
zend_ffi_type *type = (zend_ffi_type*)(void*)call->call_opline;
117114
ir_ref ref = IR_UNUSED;
115+
uint8_t arg_type = IS_UNDEF;
116+
uint8_t arg_flags = 0;
118117

119118
ZEND_ASSERT(type->kind == ZEND_FFI_TYPE_FUNC);
120119
if (type->attr & ZEND_FFI_ATTR_VARIADIC) {
@@ -233,16 +232,28 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
233232
case ZEND_FFI_TYPE_POINTER:
234233
if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING
235234
&& ZEND_FFI_TYPE(type->pointer.type)->kind == ZEND_FFI_TYPE_CHAR) {
236-
ref = ir_ADD_OFFSET(jit_Z_PTR(jit, op1_addr), offsetof(zend_string, val));
235+
arg_type = IS_STRING;
236+
ref = jit_Z_PTR(jit, op1_addr);
237+
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
238+
arg_flags |= ZREG_FFI_ZVAL_DTOR;
239+
}
237240
} else if (op1_ffi_type
238241
&& op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER
239242
&& ZEND_FFI_TYPE(type->pointer.type) == ZEND_FFI_TYPE(op1_ffi_type->pointer.type)) {
240-
ref = jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, op1_addr));
241-
ref = ir_LOAD_A(ref); // TODO: is this always necessary ???
243+
arg_type = IS_OBJECT;
244+
ref = jit_Z_PTR(jit, op1_addr);
245+
arg_flags |= ZREG_FFI_PTR_LOAD;
246+
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
247+
arg_flags |= ZREG_FFI_ZVAL_DTOR;
248+
}
242249
} else if (op1_ffi_type
243250
&& op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY
244251
&& ZEND_FFI_TYPE(type->pointer.type) == ZEND_FFI_TYPE(op1_ffi_type->array.type)) {
245-
ref = jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, op1_addr));
252+
arg_type = IS_OBJECT;
253+
ref = jit_Z_PTR(jit, op1_addr);
254+
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
255+
arg_flags |= ZREG_FFI_ZVAL_DTOR;
256+
}
246257
} else {
247258
ZEND_UNREACHABLE();
248259
}
@@ -264,13 +275,18 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
264275
} else if (op1_info == MAY_BE_DOUBLE) {
265276
ref = jit_Z_DVAL(jit, op1_addr);
266277
} else if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_STRING) {
267-
ref = ir_ADD_OFFSET(jit_Z_PTR(jit, op1_addr), offsetof(zend_string, val));
278+
arg_type = IS_STRING;
279+
ref = jit_Z_PTR(jit, op1_addr);
280+
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
281+
arg_flags |= ZREG_FFI_ZVAL_DTOR;
282+
}
268283
} else {
269284
ZEND_UNREACHABLE();
270285
}
271286
}
272287

273-
SET_STACK_REF(stack, opline->op2.num - 1, ref);
288+
SET_STACK_TYPE(stack, opline->op2.num - 1, arg_type, 0);
289+
SET_STACK_REF_EX(stack, opline->op2.num - 1, ref, arg_flags);
274290

275291
return 1;
276292
}
@@ -340,13 +356,31 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
340356
ZEND_UNREACHABLE();
341357
}
342358

359+
if (!IR_IS_CONST_REF(func_ref)) {
360+
func_ref = ir_LOAD_A(jit_FFI_CDATA_PTR(jit, func_ref));
361+
if (type->func.abi == ZEND_FFI_ABI_FASTCALL) {
362+
func_ref = ir_CAST_FC_FUNC(func_ref);
363+
}
364+
}
365+
343366
num_args = TRACE_FRAME_NUM_ARGS(call);
344367
if (num_args) {
345368
ir_ref *args = alloca(sizeof(ir_ref) * num_args);
346369
zend_jit_trace_stack *stack = call->stack;
347370

348371
for (i = 0; i < num_args; i++) {
349-
args[i] = STACK_REF(stack, i);
372+
uint8_t type = STACK_TYPE(stack, i);
373+
ir_ref ref = STACK_REF(stack, i);
374+
375+
if (type == IS_STRING) {
376+
ref = ir_ADD_OFFSET(ref, offsetof(zend_string, val));
377+
} else if (type == IS_OBJECT) {
378+
ref = jit_FFI_CDATA_PTR(jit, ref);
379+
if (STACK_FLAGS(stack, i) & ZREG_FFI_PTR_LOAD) {
380+
ref = ir_LOAD_A(ref);
381+
}
382+
}
383+
args[i] = ref;
350384
}
351385
ref = ir_CALL_N(ret_type, func_ref, num_args, args);
352386
} else {
@@ -443,6 +477,44 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
443477
}
444478
}
445479

480+
if (num_args) {
481+
zend_jit_trace_stack *stack = call->stack;
482+
483+
for (i = 0; i < num_args; i++) {
484+
if (STACK_FLAGS(stack, i) & ZREG_FFI_ZVAL_DTOR) {
485+
uint8_t type = STACK_TYPE(stack, i);
486+
ir_ref ref = STACK_REF(stack, i);
487+
488+
if (type == IS_STRING) {
489+
ir_ref if_interned = ir_IF(ir_AND_U32(
490+
ir_LOAD_U32(ir_ADD_OFFSET(ref, offsetof(zend_refcounted, gc.u.type_info))),
491+
ir_CONST_U32(IS_STR_INTERNED)));
492+
ir_IF_FALSE(if_interned);
493+
ir_ref if_not_zero = ir_IF(jit_GC_DELREF(jit, ref));
494+
ir_IF_FALSE(if_not_zero);
495+
jit_ZVAL_DTOR(jit, ref, MAY_BE_STRING, opline);
496+
ir_MERGE_WITH_EMPTY_TRUE(if_not_zero);
497+
ir_MERGE_WITH_EMPTY_TRUE(if_interned);
498+
} else if (type == IS_OBJECT) {
499+
ir_ref if_not_zero = ir_IF(jit_GC_DELREF(jit, ref));
500+
ir_IF_FALSE(if_not_zero);
501+
jit_ZVAL_DTOR(jit, ref, MAY_BE_OBJECT, opline);
502+
ir_MERGE_WITH_EMPTY_TRUE(if_not_zero); /* don't add to GC roots */
503+
} else {
504+
ZEND_ASSERT(0);
505+
}
506+
}
507+
}
508+
}
509+
510+
func_ref = (intptr_t)(void*)call->ce;
511+
if (!IR_IS_CONST_REF(func_ref)) {
512+
ir_ref if_not_zero = ir_IF(jit_GC_DELREF(jit, func_ref));
513+
ir_IF_FALSE(if_not_zero);
514+
jit_ZVAL_DTOR(jit, func_ref, MAY_BE_OBJECT, opline);
515+
ir_MERGE_WITH_EMPTY_TRUE(if_not_zero); /* don't add to GC roots */
516+
}
517+
446518
return 1;
447519
}
448520

0 commit comments

Comments
 (0)