Skip to content

Commit cab0e7f

Browse files
committed
Implement fast-path static property access in JIT
This is common for OOP applications, in particularly noticed in the Laravel framework.
1 parent b16c873 commit cab0e7f

3 files changed

Lines changed: 23 additions & 3 deletions

File tree

‎ext/opcache/jit/zend_jit.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2527,7 +2527,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
25272527
&& (opline->op2_type == IS_CONST
25282528
|| (opline->op2_type == IS_UNUSED
25292529
&& ((opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
2530-
|| (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT))))) {
2530+
|| (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT
2531+
|| (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_STATIC))))) {
25312532
break;
25322533
}
25332534
if (!zend_jit_fetch_static_prop(&ctx, opline, op_array)) {

‎ext/opcache/jit/zend_jit_ir.c‎

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16339,11 +16339,14 @@ static int zend_jit_fetch_static_prop(zend_jit_ctx *jit, const zend_op *opline,
1633916339
uint32_t cache_slot = opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS;
1634016340
uint32_t flags;
1634116341
ir_ref ref, ref2, if_cached, fast_path, cold_path, prop_info_ref, if_typed, if_def;
16342+
ir_ref slow_inputs = IR_UNUSED;
1634216343
int fetch_type;
1634316344
zend_property_info *known_prop_info = NULL;
1634416345
zend_class_entry *ce;
16346+
bool is_static = opline->op2_type == IS_UNUSED
16347+
&& (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_STATIC;
1634516348

16346-
ce = zend_get_known_class(op_array, opline, opline->op2_type, opline->op2);
16349+
ce = is_static ? NULL : zend_get_known_class(op_array, opline, opline->op2_type, opline->op2);
1634716350
if (ce) {
1634816351
zval *zv = RT_CONSTANT(opline, opline->op1);
1634916352
zend_string *prop_name;
@@ -16386,6 +16389,17 @@ static int zend_jit_fetch_static_prop(zend_jit_ctx *jit, const zend_op *opline,
1638616389
default: ZEND_UNREACHABLE();
1638716390
}
1638816391

16392+
if (is_static) {
16393+
/* The cache slot is polymorphic on the called scope. */
16394+
// JIT: if (CACHED_PTR(cache_slot) == called_scope)
16395+
ir_ref if_scope = ir_IF(ir_EQ(
16396+
ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_EX(run_time_cache)), cache_slot)),
16397+
jit_called_scope(jit, op_array)));
16398+
ir_IF_FALSE_cold(if_scope);
16399+
ir_END_list(slow_inputs);
16400+
ir_IF_TRUE(if_scope);
16401+
}
16402+
1638916403
// JIT: result = CACHED_PTR(cache_slot + sizeof(void *));
1639016404
ref = ir_LOAD_A(
1639116405
ir_ADD_OFFSET(ir_LOAD_A(jit_EX(run_time_cache)), cache_slot + sizeof(void*)));
@@ -16461,6 +16475,10 @@ static int zend_jit_fetch_static_prop(zend_jit_ctx *jit, const zend_op *opline,
1646116475
fast_path = ir_END();
1646216476

1646316477
ir_IF_FALSE_cold(if_cached);
16478+
if (slow_inputs) {
16479+
ir_END_list(slow_inputs);
16480+
ir_MERGE_list(slow_inputs);
16481+
}
1646416482
jit_SET_EX_OPLINE(jit, opline);
1646516483
ref2 = ir_CALL_2(IR_ADDR, ir_CONST_FC_FUNC(zend_fetch_static_property), jit_FP(jit), ir_CONST_I32(fetch_type));
1646616484
zend_jit_check_exception_undef_result(jit, opline);

‎ext/opcache/jit/zend_jit_trace.c‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6172,7 +6172,8 @@ static zend_vm_opcode_handler_t zend_jit_trace(zend_jit_trace_rec *trace_buffer,
61726172
&& (opline->op2_type == IS_CONST
61736173
|| (opline->op2_type == IS_UNUSED
61746174
&& ((opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF
6175-
|| (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT))))) {
6175+
|| (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT
6176+
|| (opline->op2.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_STATIC))))) {
61766177
break;
61776178
}
61786179
if (!zend_jit_fetch_static_prop(&ctx, opline, op_array)) {

0 commit comments

Comments
 (0)