mirror of
https://github.com/php/php-src.git
synced 2026-03-31 20:53:00 +02:00
Trampoline cleanup
This commit is contained in:
@@ -211,7 +211,8 @@ typedef enum _zend_jit_trace_stop {
|
||||
#define ZEND_JIT_EXIT_FREE_OP1 (1<<5)
|
||||
#define ZEND_JIT_EXIT_FREE_OP2 (1<<6)
|
||||
#define ZEND_JIT_EXIT_PACKED_GUARD (1<<7)
|
||||
#define ZEND_JIT_EXIT_DYNAMIC_CALL (1<<8) /* exit because of polymorphic INTI_DYNAMIC_CALL call */
|
||||
#define ZEND_JIT_EXIT_CLOSURE_CALL (1<<8) /* exit because of polymorphic INIT_DYNAMIC_CALL call */
|
||||
#define ZEND_JIT_EXIT_METHOD_CALL (1<<9) /* exit because of polymorphic INIT_METHOD_CALL call */
|
||||
|
||||
typedef union _zend_op_trace_info {
|
||||
zend_op dummy; /* the size of this structure must be the same as zend_op */
|
||||
|
||||
@@ -6640,7 +6640,7 @@ static void zend_jit_dump_exit_info(zend_jit_trace_info *t)
|
||||
if (t->exit_info[i].flags & ZEND_JIT_EXIT_RESTORE_CALL) {
|
||||
fprintf(stderr, "/CALL");
|
||||
}
|
||||
if (t->exit_info[i].flags & (ZEND_JIT_EXIT_POLYMORPHISM|ZEND_JIT_EXIT_DYNAMIC_CALL)) {
|
||||
if (t->exit_info[i].flags & (ZEND_JIT_EXIT_POLYMORPHISM|ZEND_JIT_EXIT_METHOD_CALL|ZEND_JIT_EXIT_CLOSURE_CALL)) {
|
||||
fprintf(stderr, "/POLY");
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
if (JIT_G(max_polymorphic_calls) > 0) {
|
||||
if ((zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_DYNAMIC_CALL)
|
||||
if ((zend_jit_traces[parent_num].exit_info[exit_num].flags & (ZEND_JIT_EXIT_METHOD_CALL|ZEND_JIT_EXIT_CLOSURE_CALL))
|
||||
|| ((zend_jit_traces[parent_num].exit_info[exit_num].flags & ZEND_JIT_EXIT_POLYMORPHISM)
|
||||
&& EX(call))) {
|
||||
if (zend_jit_traces[parent_num].polymorphism >= JIT_G(max_polymorphic_calls) - 1) {
|
||||
is_megamorphic = zend_jit_traces[parent_num].exit_info[exit_num].flags &
|
||||
(ZEND_JIT_EXIT_DYNAMIC_CALL | ZEND_JIT_EXIT_POLYMORPHISM);
|
||||
(ZEND_JIT_EXIT_METHOD_CALL | ZEND_JIT_EXIT_CLOSURE_CALL | ZEND_JIT_EXIT_POLYMORPHISM);
|
||||
} else if (!zend_jit_traces[parent_num].polymorphism) {
|
||||
polymorphism = 1;
|
||||
} else if (exit_num == 0) {
|
||||
@@ -7249,6 +7249,16 @@ int ZEND_FASTCALL zend_jit_trace_exit(uint32_t exit_num, zend_jit_registers_buf
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (t->exit_info[exit_num].flags & ZEND_JIT_EXIT_METHOD_CALL) {
|
||||
zend_function *func = (zend_function*)regs->r[0];
|
||||
|
||||
if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
|
||||
zend_string_release_ex(func->common.function_name, 0);
|
||||
zend_free_trampoline(func);
|
||||
EX(opline) = opline;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set VM opline to continue interpretation */
|
||||
EX(opline) = opline;
|
||||
|
||||
@@ -928,7 +928,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
|
||||
if (JIT_G(max_polymorphic_calls) == 0
|
||||
&& zend_jit_may_be_polymorphic_call(opline - 1)) {
|
||||
func = NULL;
|
||||
} else if (is_megamorphic == ZEND_JIT_EXIT_DYNAMIC_CALL
|
||||
} else if ((is_megamorphic == ZEND_JIT_EXIT_METHOD_CALL
|
||||
|| is_megamorphic == ZEND_JIT_EXIT_CLOSURE_CALL)
|
||||
&& trace_buffer[1].opline == opline - 1) {
|
||||
func = NULL;
|
||||
}
|
||||
|
||||
@@ -9348,7 +9348,7 @@ static int zend_jit_init_method_call(dasm_State **Dst,
|
||||
int32_t exit_point;
|
||||
const void *exit_addr;
|
||||
|
||||
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_DYNAMIC_CALL);
|
||||
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_METHOD_CALL);
|
||||
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
|
||||
if (!exit_addr) {
|
||||
return 0;
|
||||
@@ -9500,7 +9500,7 @@ static int zend_jit_init_closure_call(dasm_State **Dst,
|
||||
|
||||
func = (zend_function*)trace->func;
|
||||
opcodes = func->op_array.opcodes;
|
||||
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_DYNAMIC_CALL);
|
||||
exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_CLOSURE_CALL);
|
||||
exit_addr = zend_jit_trace_get_exit_addr(exit_point);
|
||||
if (!exit_addr) {
|
||||
return 0;
|
||||
|
||||
34
ext/opcache/tests/jit/trampoline_001.phpt
Normal file
34
ext/opcache/tests/jit/trampoline_001.phpt
Normal file
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
JIT: trampoline cleanup
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.file_update_protection=0
|
||||
opcache.jit_buffer_size=1M
|
||||
opcache.jit=tracing
|
||||
--SKIPIF--
|
||||
<?php require_once('skipif.inc'); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class A {
|
||||
}
|
||||
class B extends A {
|
||||
function foo() {
|
||||
echo "B";
|
||||
}
|
||||
}
|
||||
class C extends A {
|
||||
function __call($name, $argd) {
|
||||
echo "C";
|
||||
}
|
||||
}
|
||||
$b = new B;
|
||||
$c = new C;
|
||||
$a = [$b, $b, $b, $c, $c, $c];
|
||||
foreach ($a as $x) {
|
||||
$x->foo();
|
||||
}
|
||||
echo "\n";
|
||||
?>
|
||||
--EXPECT--
|
||||
BBBCCC
|
||||
Reference in New Issue
Block a user