Skip to content

Commit 19b1e8c

Browse files
committed
Avoid repeatable FFI type guards (no LICM yet)
1 parent 49f86a7 commit 19b1e8c

File tree

3 files changed

+65
-15
lines changed

3 files changed

+65
-15
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@
4444

4545
#if HAVE_FFI
4646
# include "ext/ffi/php_ffi.h"
47+
48+
# define FFI_TYPE_GUARD (1<<0)
49+
50+
typedef struct zend_jit_ffi_info {
51+
zend_ffi_type *type;
52+
uint32_t info;
53+
} zend_jit_ffi_info;
4754
#endif
4855

4956
#ifdef HAVE_PTHREAD_JIT_WRITE_PROTECT_NP

ext/opcache/jit/zend_jit_ir.c

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12505,7 +12505,8 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
1250512505
zend_ssa_range *op2_range,
1250612506
uint32_t res_info,
1250712507
zend_jit_addr res_addr,
12508-
zend_ffi_type *op1_ffi_type)
12508+
zend_ffi_type *op1_ffi_type,
12509+
zend_jit_ffi_info *ffi_info)
1250912510
{
1251012511
uint32_t res_type;
1251112512
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
@@ -12524,9 +12525,15 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
1252412525
}
1252512526
}
1252612527

12527-
// TODO: ffi type guard ???
12528-
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
12529-
return 0;
12528+
if (ffi_info
12529+
&& ssa_op->op1_use >= 0
12530+
&& (ffi_info[ssa_op->op1_use].type != op1_ffi_type
12531+
|| (ffi_info[ssa_op->op1_use].info & FFI_TYPE_GUARD))) {
12532+
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
12533+
return 0;
12534+
}
12535+
ffi_info[ssa_op->op1_use].info &= ~FFI_TYPE_GUARD;
12536+
ffi_info[ssa_op->op1_use].type = op1_ffi_type;
1253012537
}
1253112538

1253212539
if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
@@ -13283,7 +13290,8 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
1328313290
zend_jit_addr op3_addr,
1328413291
zend_jit_addr op3_def_addr,
1328513292
zend_jit_addr res_addr,
13286-
zend_ffi_type *op1_ffi_type)
13293+
zend_ffi_type *op1_ffi_type,
13294+
zend_jit_ffi_info *ffi_info)
1328713295
{
1328813296
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
1328913297
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
@@ -13306,9 +13314,19 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
1330613314
}
1330713315
}
1330813316

13309-
// TODO: ffi type guard ???
13310-
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
13311-
return 0;
13317+
if (ffi_info
13318+
&& ssa_op->op1_use >= 0
13319+
&& (ffi_info[ssa_op->op1_use].type != op1_ffi_type
13320+
|| (ffi_info[ssa_op->op1_use].info & FFI_TYPE_GUARD))) {
13321+
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
13322+
return 0;
13323+
}
13324+
ffi_info[ssa_op->op1_use].info &= ~FFI_TYPE_GUARD;
13325+
ffi_info[ssa_op->op1_use].type = op1_ffi_type;
13326+
if (ssa_op->op1_def >= 0) {
13327+
ffi_info[ssa_op->op1_def].info &= ~FFI_TYPE_GUARD;
13328+
ffi_info[ssa_op->op1_def].type = op1_ffi_type;
13329+
}
1331213330
}
1331313331

1331413332
if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
@@ -13797,7 +13815,8 @@ static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
1379713815
uint32_t op1_data_info,
1379813816
zend_jit_addr op3_addr,
1379913817
zend_ssa_range *op1_data_range,
13800-
zend_ffi_type *op1_ffi_type)
13818+
zend_ffi_type *op1_ffi_type,
13819+
zend_jit_ffi_info *ffi_info)
1380113820
{
1380213821
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
1380313822
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
@@ -13820,9 +13839,19 @@ static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
1382013839
}
1382113840
}
1382213841

13823-
// TODO: ffi type guard ???
13824-
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
13825-
return 0;
13842+
if (ffi_info
13843+
&& ssa_op->op1_use >= 0
13844+
&& (ffi_info[ssa_op->op1_use].type != op1_ffi_type
13845+
|| (ffi_info[ssa_op->op1_use].info & FFI_TYPE_GUARD))) {
13846+
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
13847+
return 0;
13848+
}
13849+
ffi_info[ssa_op->op1_use].info &= ~FFI_TYPE_GUARD;
13850+
ffi_info[ssa_op->op1_use].type = op1_ffi_type;
13851+
if (ssa_op->op1_def >= 0) {
13852+
ffi_info[ssa_op->op1_def].info &= ~FFI_TYPE_GUARD;
13853+
ffi_info[ssa_op->op1_def].type = op1_ffi_type;
13854+
}
1382613855
}
1382713856

1382813857
if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4035,6 +4035,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
40354035
int checked_stack;
40364036
int peek_checked_stack;
40374037
uint32_t frame_flags = 0;
4038+
#ifdef HAVE_FFI
4039+
zend_jit_ffi_info *ffi_info = NULL;
4040+
#endif
40384041

40394042
JIT_G(current_trace) = trace_buffer;
40404043

@@ -4691,11 +4694,15 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
46914694
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
46924695
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
46934696
&& op2_info == MAY_BE_LONG) {
4697+
if (!ffi_info) {
4698+
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
4699+
}
46944700
if (!zend_jit_ffi_assign_dim_op(&ctx, opline, ssa, ssa_op,
46954701
op1_info, op1_def_info, op1_addr,
46964702
op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
46974703
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
4698-
op1_data_info, OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(), op1_ffi_type)) {
4704+
op1_data_info, OP1_DATA_REG_ADDR(), OP1_DATA_RANGE(),
4705+
op1_ffi_type, ffi_info)) {
46994706
goto jit_failure;
47004707
}
47014708
} else
@@ -5024,14 +5031,17 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50245031
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
50255032
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
50265033
&& op2_info == MAY_BE_LONG) {
5034+
if (!ffi_info) {
5035+
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
5036+
}
50275037
if (!zend_jit_ffi_assign_dim(&ctx, opline, ssa, ssa_op,
50285038
op1_info, op1_addr,
50295039
op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
50305040
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
50315041
op1_data_info, OP1_DATA_REG_ADDR(),
50325042
(ctx.ra && (ssa_op+1)->op1_def >= 0) ? OP1_DATA_DEF_REG_ADDR() : 0,
50335043
(opline->result_type != IS_UNUSED) ? RES_REG_ADDR() : 0,
5034-
op1_ffi_type)) {
5044+
op1_ffi_type, ffi_info)) {
50355045
goto jit_failure;
50365046
}
50375047
} else
@@ -5827,10 +5837,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
58275837
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
58285838
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
58295839
&& op2_info == MAY_BE_LONG) {
5840+
if (!ffi_info) {
5841+
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
5842+
}
58305843
if (!zend_jit_ffi_fetch_dim_read(&ctx, opline, ssa, ssa_op,
58315844
op1_info, op1_addr, avoid_refcounting,
58325845
op2_info, OP2_REG_ADDR(), OP2_RANGE(),
5833-
res_info, RES_REG_ADDR(), op1_ffi_type)) {
5846+
res_info, RES_REG_ADDR(),
5847+
op1_ffi_type, ffi_info)) {
58345848
goto jit_failure;
58355849
}
58365850
} else

0 commit comments

Comments
 (0)