Skip to content

Commit cdd2493

Browse files
committed
JIT for FFI::free()
1 parent 6232403 commit cdd2493

File tree

4 files changed

+42
-13
lines changed

4 files changed

+42
-13
lines changed

ext/ffi/ffi.c

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3926,22 +3926,12 @@ ZEND_METHOD(FFI, new) /* {{{ */
39263926
}
39273927
/* }}} */
39283928

3929-
ZEND_METHOD(FFI, free) /* {{{ */
3929+
static bool zend_ffi_cdata_free(zend_ffi_cdata *cdata) /* {{{ */
39303930
{
3931-
zval *zv;
3932-
zend_ffi_cdata *cdata;
3933-
3934-
ZEND_FFI_VALIDATE_API_RESTRICTION();
3935-
ZEND_PARSE_PARAMETERS_START(1, 1)
3936-
Z_PARAM_OBJECT_OF_CLASS_EX(zv, zend_ffi_cdata_ce, 0, 1);
3937-
ZEND_PARSE_PARAMETERS_END();
3938-
3939-
cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
3940-
39413931
if (ZEND_FFI_TYPE(cdata->type)->kind == ZEND_FFI_TYPE_POINTER) {
39423932
if (!cdata->ptr) {
39433933
zend_throw_error(zend_ffi_exception_ce, "NULL pointer dereference");
3944-
RETURN_THROWS();
3934+
return false;
39453935
}
39463936
if (cdata->ptr != (void*)&cdata->ptr_holder) {
39473937
pefree(*(void**)cdata->ptr, cdata->flags & ZEND_FFI_FLAG_PERSISTENT);
@@ -3956,6 +3946,25 @@ ZEND_METHOD(FFI, free) /* {{{ */
39563946
cdata->std.handlers = &zend_ffi_cdata_free_handlers;
39573947
} else {
39583948
zend_throw_error(zend_ffi_exception_ce, "free() non a C pointer");
3949+
return false;
3950+
}
3951+
return true;
3952+
}
3953+
/* }}} */
3954+
3955+
ZEND_METHOD(FFI, free) /* {{{ */
3956+
{
3957+
zval *zv;
3958+
zend_ffi_cdata *cdata;
3959+
3960+
ZEND_FFI_VALIDATE_API_RESTRICTION();
3961+
ZEND_PARSE_PARAMETERS_START(1, 1)
3962+
Z_PARAM_OBJECT_OF_CLASS_EX(zv, zend_ffi_cdata_ce, 0, 1);
3963+
ZEND_PARSE_PARAMETERS_END();
3964+
3965+
cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
3966+
if (!zend_ffi_cdata_free(cdata)) {
3967+
RETURN_THROWS();
39593968
}
39603969
}
39613970
/* }}} */
@@ -5618,6 +5627,7 @@ ZEND_MINIT_FUNCTION(ffi)
56185627

56195628
ffi_api.cdata_create = zend_ffi_cdata_create;
56205629
ffi_api.ctype_create = zend_ffi_ctype_create;
5630+
ffi_api.cdata_free = zend_ffi_cdata_free;
56215631
ffi_api.type_print = zend_ffi_type_print;
56225632
ffi_api.is_compatible_type = zend_ffi_is_compatible_type;
56235633

ext/ffi/php_ffi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,7 @@ struct _zend_ffi_api {
421421
/* ext/ffi interface for ext/opcache */
422422
zend_ffi_cdata* (*cdata_create)(void *ptr, zend_ffi_type *type);
423423
zend_ffi_ctype* (*ctype_create)(zend_ffi_type *type);
424+
bool (*cdata_free)(zend_ffi_cdata *cdata);
424425
void (*type_print)(FILE *f, const zend_ffi_type *type);
425426
bool (*is_compatible_type)(zend_ffi_type *dst_type, zend_ffi_type *src_type);
426427

ext/opcache/jit/zend_jit_ir_ffi.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
137137
if (TRACE_FRAME_FFI_FUNC(call)) {
138138
if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_ADDR
139139
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_TYPEOF
140-
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_IS_NULL) {
140+
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_IS_NULL
141+
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_FREE) {
141142
ZEND_ASSERT(opline->op2.num == 1);
142143
ZEND_ASSERT(op1_ffi_type);
143144

@@ -667,6 +668,16 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
667668
}
668669
ref = ir_ADD_U32(ir_ZEXT_U32(ir_EQ(ref, IR_NULL)), ir_CONST_U32(IS_FALSE));
669670
jit_set_Z_TYPE_INFO_ex(jit, res_addr, ref);
671+
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_FREE) {
672+
ref = STACK_REF(stack, 0);
673+
if (STACK_FLAGS(stack, 0) & ZREG_FFI_ZVAL_DEREF) {
674+
// TODO: try to remove this dereference ???
675+
ref = zend_jit_gc_deref(jit, ref);
676+
}
677+
ir_CALL_1(IR_VOID, ir_CONST_FUNC(zend_ffi_api->cdata_free), ref);
678+
if (res_addr) {
679+
jit_set_Z_TYPE_INFO(jit, res_addr, IS_NULL);
680+
}
670681
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_STRING) {
671682
ZEND_ASSERT(num_args > 0 && STACK_TYPE(stack, 0) == IS_OBJECT);
672683
ref = STACK_REF(stack, 0);

ext/opcache/jit/zend_jit_trace.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7115,6 +7115,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
71157115
frame_ffi_func_type = NULL;
71167116
frame_ffi_func_ref = IR_UNUSED;
71177117
goto done;
7118+
} else if (Z_TYPE_P(zv) == IS_STRING
7119+
&& zend_string_equals_literal_ci(Z_STR_P(zv), "free")
7120+
&& opline->extended_value == 1) {
7121+
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_FREE;
7122+
frame_ffi_func_type = NULL;
7123+
frame_ffi_func_ref = IR_UNUSED;
7124+
goto done;
71187125
}
71197126
}
71207127
}

0 commit comments

Comments
 (0)