Skip to content

Commit 64dc79f

Browse files
committed
Trampoline cleanup
1 parent 7bbed18 commit 64dc79f

File tree

5 files changed

+53
-7
lines changed

5 files changed

+53
-7
lines changed

ext/opcache/jit/zend_jit_internal.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ typedef enum _zend_jit_trace_stop {
211211
#define ZEND_JIT_EXIT_FREE_OP1 (1<<5)
212212
#define ZEND_JIT_EXIT_FREE_OP2 (1<<6)
213213
#define ZEND_JIT_EXIT_PACKED_GUARD (1<<7)
214-
#define ZEND_JIT_EXIT_DYNAMIC_CALL (1<<8) /* exit because of polymorphic INTI_DYNAMIC_CALL call */
214+
#define ZEND_JIT_EXIT_CLOSURE_CALL (1<<8) /* exit because of polymorphic INIT_DYNAMIC_CALL call */
215+
#define ZEND_JIT_EXIT_METHOD_CALL (1<<9) /* exit because of polymorphic INIT_METHOD_CALL call */
215216

216217
typedef union _zend_op_trace_info {
217218
zend_op dummy; /* the size of this structure must be the same as zend_op */

ext/opcache/jit/zend_jit_trace.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6640,7 +6640,7 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t)
66406640
if (t->exit_info[i].flags & ZEND_JIT_EXIT_RESTORE_CALL) {
66416641
fprintf(stderr, "/CALL");
66426642
}
6643-
if (t->exit_info[i].flags & (ZEND_JIT_EXIT_POLYMORPHISM|ZEND_JIT_EXIT_DYNAMIC_CALL)) {
6643+
if (t->exit_info[i].flags & (ZEND_JIT_EXIT_POLYMORPHISM|ZEND_JIT_EXIT_METHOD_CALL|ZEND_JIT_EXIT_CLOSURE_CALL)) {
66446644
fprintf(stderr, "/POLY");
66456645
}
66466646
if (t->exit_info[i].flags & ZEND_JIT_EXIT_FREE_OP1) {
@@ -7043,12 +7043,12 @@ int ZEND_FASTCALL zend_jit_trace_hot_side(zend_execute_data *execute_data, uint3
70437043
}
70447044

70457045
if (JIT_G(max_polymorphic_calls) > 0) {
7046-
if ((zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_DYNAMIC_CALL)
7046+
if ((zend_jit_traces[parent_num].exit_info[exit_num].flags & (ZEND_JIT_EXIT_METHOD_CALL|ZEND_JIT_EXIT_CLOSURE_CALL))
70477047
|| ((zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_POLYMORPHISM)
70487048
&& EX(call))) {
70497049
if (zend_jit_traces[parent_num].polymorphism >= JIT_G(max_polymorphic_calls) - 1) {
70507050
is_megamorphic = zend_jit_traces[parent_num].exit_info[exit_num].flags &
7051-
(ZEND_JIT_EXIT_DYNAMIC_CALL | ZEND_JIT_EXIT_POLYMORPHISM);
7051+
(ZEND_JIT_EXIT_METHOD_CALL | ZEND_JIT_EXIT_CLOSURE_CALL | ZEND_JIT_EXIT_POLYMORPHISM);
70527052
} else if (!zend_jit_traces[parent_num].polymorphism) {
70537053
polymorphism = 1;
70547054
} else if (exit_num == 0) {
@@ -7249,6 +7249,16 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf
72497249
return 1;
72507250
}
72517251
}
7252+
if (t->exit_info[exit_num].flags & ZEND_JIT_EXIT_METHOD_CALL) {
7253+
zend_function *func = (zend_function*)regs->r[0];
7254+
7255+
if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
7256+
zend_string_release_ex(func->common.function_name, 0);
7257+
zend_free_trampoline(func);
7258+
EX(opline) = opline;
7259+
return 1;
7260+
}
7261+
}
72527262

72537263
/* Set VM opline to continue interpretation */
72547264
EX(opline) = opline;

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -928,7 +928,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
928928
if (JIT_G(max_polymorphic_calls) == 0
929929
&& zend_jit_may_be_polymorphic_call(opline - 1)) {
930930
func = NULL;
931-
} else if (is_megamorphic == ZEND_JIT_EXIT_DYNAMIC_CALL
931+
} else if ((is_megamorphic == ZEND_JIT_EXIT_METHOD_CALL
932+
|| is_megamorphic == ZEND_JIT_EXIT_CLOSURE_CALL)
932933
&& trace_buffer[1].opline == opline - 1) {
933934
func = NULL;
934935
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9348,7 +9348,7 @@ static int zend_jit_init_method_call(dasm_State **Dst,
93489348
int32_t exit_point;
93499349
const void *exit_addr;
93509350

9351-
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_DYNAMIC_CALL);
9351+
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_METHOD_CALL);
93529352
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
93539353
if (!exit_addr) {
93549354
return 0;
@@ -9500,7 +9500,7 @@ static int zend_jit_init_closure_call(dasm_State **Dst,
95009500

95019501
func = (zend_function*)trace->func;
95029502
opcodes = func->op_array.opcodes;
9503-
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_DYNAMIC_CALL);
9503+
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_CLOSURE_CALL);
95049504
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
95059505
if (!exit_addr) {
95069506
return 0;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
JIT: trampoline cleanup
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.jit=tracing
9+
--SKIPIF--
10+
<?php require_once('skipif.inc'); ?>
11+
--FILE--
12+
<?php
13+
class A {
14+
}
15+
class B extends A {
16+
function foo() {
17+
echo "B";
18+
}
19+
}
20+
class C extends A {
21+
function __call($name, $argd) {
22+
echo "C";
23+
}
24+
}
25+
$b = new B;
26+
$c = new C;
27+
$a = [$b, $b, $b, $c, $c, $c];
28+
foreach ($a as $x) {
29+
$x->foo();
30+
}
31+
echo "\n";
32+
?>
33+
--EXPECT--
34+
BBBCCC

0 commit comments

Comments
 (0)