Skip to content

Commit f786c0e

Browse files
committed
Optimize code for FETCH_THIS + INIT_METHOD_CALL/ASSIGN_OBJ_OP/etc
1 parent 0d99a56 commit f786c0e

File tree

4 files changed

+58
-30
lines changed

4 files changed

+58
-30
lines changed

ext/opcache/jit/zend_jit_disasm_x86.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,9 +399,11 @@ static int zend_jit_disasm_init(void)
399399
REGISTER_HELPER(zend_jit_find_func_helper);
400400
REGISTER_HELPER(zend_jit_find_ns_func_helper);
401401
REGISTER_HELPER(zend_jit_find_method_helper);
402+
REGISTER_HELPER(zend_jit_find_method_tmp_helper);
402403
REGISTER_HELPER(zend_jit_push_static_metod_call_frame);
403404
REGISTER_HELPER(zend_jit_push_static_metod_call_frame_tmp);
404405
REGISTER_HELPER(zend_jit_invalid_method_call);
406+
REGISTER_HELPER(zend_jit_invalid_method_call_tmp);
405407
REGISTER_HELPER(zend_jit_unref_helper);
406408
REGISTER_HELPER(zend_jit_extend_stack_helper);
407409
REGISTER_HELPER(zend_jit_int_extend_stack_helper);

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,15 @@ static ZEND_COLD void ZEND_FASTCALL zend_jit_invalid_method_call(zval *object)
107107
}
108108
zend_throw_error(NULL, "Call to a member function %s() on %s",
109109
Z_STRVAL_P(function_name), zend_zval_type_name(object));
110-
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
111-
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
112-
}
110+
}
111+
112+
static ZEND_COLD void ZEND_FASTCALL zend_jit_invalid_method_call_tmp(zval *object)
113+
{
114+
zend_execute_data *execute_data = EG(current_execute_data);
115+
const zend_op *opline = EX(opline);
116+
117+
zend_jit_invalid_method_call(object);
118+
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
113119
}
114120

115121
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_undefined_method(const zend_class_entry *ce, const zend_string *method)
@@ -136,32 +142,21 @@ static zend_function* ZEND_FASTCALL zend_jit_find_method_helper(zend_object *obj
136142
zend_execute_data *execute_data = EG(current_execute_data);
137143
const zend_op *opline = EX(opline);
138144
zend_class_entry *called_scope = obj->ce;
139-
zend_object *orig_obj = obj;
140145
zend_function *fbc;
141146

142-
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), function_name + 1);
147+
fbc = obj->handlers->get_method(obj_ptr, Z_STR_P(function_name), function_name + 1);
143148
if (UNEXPECTED(fbc == NULL)) {
144149
if (EXPECTED(!EG(exception))) {
145150
zend_undefined_method(called_scope, Z_STR_P(function_name));
146151
}
147-
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
148-
zend_objects_store_del(orig_obj);
149-
}
150152
return NULL;
151153
}
152154

153155
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
154156
zend_init_func_run_time_cache(&fbc->op_array);
155157
}
156158

157-
if (UNEXPECTED(obj != orig_obj)) {
158-
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
159-
GC_ADDREF(obj);
160-
if (GC_DELREF(orig_obj) == 0) {
161-
zend_objects_store_del(orig_obj);
162-
}
163-
}
164-
*obj_ptr = obj;
159+
if (UNEXPECTED(obj != *obj_ptr)) {
165160
return fbc;
166161
}
167162

@@ -172,6 +167,24 @@ static zend_function* ZEND_FASTCALL zend_jit_find_method_helper(zend_object *obj
172167
return fbc;
173168
}
174169

170+
static zend_function* ZEND_FASTCALL zend_jit_find_method_tmp_helper(zend_object *obj, zval *function_name, zend_object **obj_ptr)
171+
{
172+
zend_function *fbc;
173+
174+
fbc = zend_jit_find_method_helper(obj, function_name, obj_ptr);
175+
if (!fbc) {
176+
if (GC_DELREF(obj) == 0) {
177+
zend_objects_store_del(obj);
178+
}
179+
} else if (obj != *obj_ptr) {
180+
GC_ADDREF(obj);
181+
if (GC_DELREF(obj) == 0) {
182+
zend_objects_store_del(obj);
183+
}
184+
}
185+
return fbc;
186+
}
187+
175188
static zend_execute_data* ZEND_FASTCALL zend_jit_push_static_metod_call_frame(zend_object *obj, zend_function *fbc, uint32_t num_args)
176189
{
177190
zend_class_entry *scope = obj->ce;

ext/opcache/jit/zend_jit_trace.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,7 +2827,10 @@ static zend_bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ss
28272827
}
28282828

28292829
opline = ssa_opcodes[use];
2830-
if (opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG) {
2830+
if (opline->opcode == ZEND_INIT_METHOD_CALL) {
2831+
return (opline->op2_type == IS_CONST &&
2832+
Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) == IS_STRING);
2833+
} else if (opline->opcode == ZEND_FETCH_OBJ_FUNC_ARG) {
28312834
if (!JIT_G(current_frame)
28322835
|| !JIT_G(current_frame)->call
28332836
|| !JIT_G(current_frame)->call->func
@@ -2837,7 +2840,12 @@ static zend_bool zend_jit_may_delay_fetch_this(zend_ssa *ssa, const zend_op **ss
28372840
} else if (opline->opcode != ZEND_FETCH_OBJ_R
28382841
&& opline->opcode != ZEND_FETCH_OBJ_IS
28392842
&& opline->opcode != ZEND_FETCH_OBJ_W
2840-
&& opline->opcode != ZEND_ASSIGN_OBJ) {
2843+
&& opline->opcode != ZEND_ASSIGN_OBJ
2844+
&& opline->opcode != ZEND_ASSIGN_OBJ_OP
2845+
&& opline->opcode != ZEND_PRE_INC_OBJ
2846+
&& opline->opcode != ZEND_PRE_DEC_OBJ
2847+
&& opline->opcode != ZEND_POST_INC_OBJ
2848+
&& opline->opcode != ZEND_POST_DEC_OBJ) {
28412849
return 0;
28422850
}
28432851

@@ -5001,9 +5009,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50015009
op1_addr = 0;
50025010
} else {
50035011
op1_info = OP1_INFO();
5004-
if (!(op1_info & MAY_BE_OBJECT)) {
5005-
goto generic_dynamic_call;
5006-
}
50075012
op1_addr = OP1_REG_ADDR();
50085013
if (orig_op1_type != IS_UNKNOWN
50095014
&& (orig_op1_type & IS_TRACE_REFERENCE)) {

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8477,7 +8477,7 @@ typedef struct _zend_closure {
84778477
zif_handler orig_internal_handler;
84788478
} zend_closure;
84798479

8480-
static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zend_function *func, zend_bool is_closure)
8480+
static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zend_function *func, zend_bool is_closure, zend_bool use_this)
84818481
{
84828482
uint32_t used_stack;
84838483

@@ -8599,7 +8599,7 @@ static int zend_jit_push_call_frame(dasm_State **Dst, const zend_op *opline, zen
85998599
| // Z_PTR(call->This) = obj;
86008600
| mov r1, aword T1
86018601
| mov aword EX:RX->This.value.ptr, r1
8602-
if (opline->op1_type == IS_UNUSED) {
8602+
if (opline->op1_type == IS_UNUSED || use_this) {
86038603
| // call->call_info |= ZEND_CALL_HAS_THIS;
86048604
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
86058605
| mov dword EX:RX->This.u1.type_info, ZEND_CALL_HAS_THIS
@@ -9038,7 +9038,7 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
90389038
|3:
90399039
}
90409040

9041-
if (!zend_jit_push_call_frame(Dst, opline, func, 0)) {
9041+
if (!zend_jit_push_call_frame(Dst, opline, func, 0, 0)) {
90429042
return 0;
90439043
}
90449044

@@ -9116,7 +9116,11 @@ static int zend_jit_init_method_call(dasm_State **Dst,
91169116
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
91179117
}
91189118
| SET_EX_OPLINE opline, r0
9119-
| EXT_CALL zend_jit_invalid_method_call, r0
9119+
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && !use_this) {
9120+
| EXT_CALL zend_jit_invalid_method_call_tmp, r0
9121+
} else {
9122+
| EXT_CALL zend_jit_invalid_method_call, r0
9123+
}
91209124
| jmp ->exception_handler
91219125
|.code
91229126
}
@@ -9169,7 +9173,11 @@ static int zend_jit_init_method_call(dasm_State **Dst,
91699173
| push r0
91709174
|.endif
91719175
| SET_EX_OPLINE opline, r0
9172-
| EXT_CALL zend_jit_find_method_helper, r0
9176+
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && !use_this) {
9177+
| EXT_CALL zend_jit_find_method_tmp_helper, r0
9178+
} else {
9179+
| EXT_CALL zend_jit_find_method_helper, r0
9180+
}
91739181
| test r0, r0
91749182
| jz ->exception_handler
91759183
|.if not(X64)
@@ -9247,15 +9255,15 @@ static int zend_jit_init_method_call(dasm_State **Dst,
92479255
| sub r4, 12
92489256
| push opline->extended_value
92499257
|.endif
9250-
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
9258+
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR)) && !use_this) {
92519259
| EXT_CALL zend_jit_push_static_metod_call_frame_tmp, r0
92529260
} else {
92539261
| EXT_CALL zend_jit_push_static_metod_call_frame, r0
92549262
}
92559263
|.if not(X64)
92569264
| add r4, 12
92579265
|.endif
9258-
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
9266+
if ((opline->op1_type & (IS_VAR|IS_TMP_VAR) && !use_this)) {
92599267
| test r0, r0
92609268
| jz ->exception_handler
92619269
}
@@ -9268,7 +9276,7 @@ static int zend_jit_init_method_call(dasm_State **Dst,
92689276
}
92699277

92709278
if (!func || (func->common.fn_flags & ZEND_ACC_STATIC) == 0) {
9271-
if (!zend_jit_push_call_frame(Dst, opline, func, 0)) {
9279+
if (!zend_jit_push_call_frame(Dst, opline, func, 0, use_this)) {
92729280
return 0;
92739281
}
92749282
}
@@ -9366,7 +9374,7 @@ static int zend_jit_init_closure_call(dasm_State **Dst,
93669374
}
93679375
}
93689376

9369-
if (!zend_jit_push_call_frame(Dst, opline, func, 1)) {
9377+
if (!zend_jit_push_call_frame(Dst, opline, func, 1, 0)) {
93709378
return 0;
93719379
}
93729380

0 commit comments

Comments
 (0)