Skip to content

Commit 721742c

Browse files
committed
JIT to write to FFI variables
1 parent 42c5f6e commit 721742c

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15054,6 +15054,40 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
1505415054

1505515055
return 1;
1505615056
}
15057+
15058+
static int zend_jit_ffi_assign_sym(zend_jit_ctx *jit,
15059+
const zend_op *opline,
15060+
const zend_op_array *op_array,
15061+
zend_ssa *ssa,
15062+
const zend_ssa_op *ssa_op,
15063+
uint32_t op1_info,
15064+
zend_jit_addr op1_addr,
15065+
bool on_this,
15066+
bool delayed_fetch_this,
15067+
zend_ffi_symbol *sym,
15068+
uint32_t val_info,
15069+
zend_jit_addr val_addr,
15070+
zend_jit_addr val_def_addr,
15071+
zend_jit_addr res_addr,
15072+
HashTable *op1_ffi_symbols,
15073+
zend_ffi_type *val_ffi_type,
15074+
zend_jit_ffi_info *ffi_info)
15075+
{
15076+
zend_ffi_type *sym_type = ZEND_FFI_TYPE(sym->type);
15077+
15078+
if (!zend_jit_ffi_symbols_guard(jit, opline, ssa, ssa_op->op1_use, ssa_op->op1_def, op1_addr, op1_ffi_symbols, ffi_info)) {
15079+
return 0;
15080+
}
15081+
15082+
ir_ref ptr = ir_CONST_ADDR(sym->addr);
15083+
if (!zend_jit_ffi_write(jit, sym_type, ptr, val_info, val_addr, val_ffi_type)) {
15084+
return 0;
15085+
}
15086+
15087+
ZEND_ASSERT(!res_addr);
15088+
15089+
return 1;
15090+
}
1505715091
#endif
1505815092

1505915093
static int zend_jit_assign_obj(zend_jit_ctx *jit,
@@ -15442,6 +15476,36 @@ static int zend_jit_ffi_assign_obj_op(zend_jit_ctx *jit,
1544215476

1544315477
return 1;
1544415478
}
15479+
15480+
static int zend_jit_ffi_assign_sym_op(zend_jit_ctx *jit,
15481+
const zend_op *opline,
15482+
const zend_op_array *op_array,
15483+
zend_ssa *ssa,
15484+
const zend_ssa_op *ssa_op,
15485+
uint32_t op1_info,
15486+
zend_jit_addr op1_addr,
15487+
bool on_this,
15488+
bool delayed_fetch_this,
15489+
zend_ffi_symbol *sym,
15490+
uint32_t val_info,
15491+
zend_jit_addr val_addr,
15492+
HashTable *op1_ffi_symbols,
15493+
zend_jit_ffi_info *ffi_info)
15494+
{
15495+
zend_ffi_type *sym_type = ZEND_FFI_TYPE(sym->type);
15496+
15497+
if (!zend_jit_ffi_symbols_guard(jit, opline, ssa, ssa_op->op1_use, ssa_op->op1_def, op1_addr, op1_ffi_symbols, ffi_info)) {
15498+
return 0;
15499+
}
15500+
15501+
ir_ref ptr = ir_CONST_ADDR(sym->addr);
15502+
if (!zend_jit_ffi_assign_op_helper(jit, opline, opline->extended_value,
15503+
sym_type, ptr, val_info, val_addr)) {
15504+
return 0;
15505+
}
15506+
15507+
return 1;
15508+
}
1544515509
#endif
1544615510

1544715511
static int zend_jit_assign_obj_op(zend_jit_ctx *jit,

ext/opcache/jit/zend_jit_trace.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4926,6 +4926,23 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
49264926
}
49274927
goto done;
49284928
}
4929+
} else if (op1_ffi_symbols) {
4930+
zend_ffi_symbol *sym = zend_hash_find_ptr(op1_ffi_symbols,
4931+
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
4932+
if (sym
4933+
&& sym->kind == ZEND_FFI_SYM_VAR
4934+
&& zend_jit_ffi_compatible(sym->type, op1_data_info, op3_ffi_type)) {
4935+
if (!ffi_info) {
4936+
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
4937+
}
4938+
if (!zend_jit_ffi_assign_sym_op(&ctx, opline, op_array, ssa, ssa_op,
4939+
op1_info, op1_addr, on_this, delayed_fetch_this, sym,
4940+
op1_data_info, OP1_DATA_REG_ADDR(),
4941+
op1_ffi_symbols, ffi_info)) {
4942+
goto jit_failure;
4943+
}
4944+
goto done;
4945+
}
49294946
}
49304947
#endif
49314948
if (!zend_jit_assign_obj_op(&ctx, opline, op_array, ssa, ssa_op,
@@ -5037,6 +5054,29 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50375054
}
50385055
goto done;
50395056
}
5057+
} else if (op1_ffi_symbols) {
5058+
zend_ffi_symbol *sym = zend_hash_find_ptr(op1_ffi_symbols,
5059+
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
5060+
if (sym
5061+
&& sym->kind == ZEND_FFI_SYM_VAR
5062+
&& zend_jit_ffi_compatible(sym->type, op1_data_info, op3_ffi_type)) {
5063+
if (!ffi_info) {
5064+
ffi_info = zend_arena_calloc(&CG(arena), ssa->vars_count, sizeof(zend_jit_ffi_info));
5065+
}
5066+
if (!zend_jit_ffi_assign_sym(&ctx, opline, op_array, ssa, ssa_op,
5067+
op1_info, op1_addr, on_this, delayed_fetch_this, sym,
5068+
op1_data_info, OP1_DATA_REG_ADDR(), OP1_DATA_DEF_REG_ADDR(),
5069+
(opline->result_type != IS_UNUSED) ? RES_REG_ADDR() : 0,
5070+
op1_ffi_symbols, op3_ffi_type, ffi_info)) {
5071+
goto jit_failure;
5072+
}
5073+
if ((opline+1)->op1_type == IS_CV
5074+
&& (ssa_op+1)->op1_def >= 0
5075+
&& ssa->vars[(ssa_op+1)->op1_def].alias == NO_ALIAS) {
5076+
ssa->var_info[(ssa_op+1)->op1_def].guarded_reference = ssa->var_info[(ssa_op+1)->op1_use].guarded_reference;
5077+
}
5078+
goto done;
5079+
}
50405080
}
50415081
#endif
50425082
if (!zend_jit_assign_obj(&ctx, opline, op_array, ssa, ssa_op,

0 commit comments

Comments
 (0)