Skip to content

Commit 982cafa

Browse files
committed
Allow optimizer to depend on preloaded symbols
It is safe for the optimizer to rely on preloaded symbols. This can occur when compiling non-preloaded files, referencing preloaded ones.
1 parent 82479e8 commit 982cafa

File tree

3 files changed

+58
-11
lines changed

3 files changed

+58
-11
lines changed

Zend/Optimizer/zend_optimizer.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,7 @@ zend_class_entry *zend_optimizer_get_class_entry(
803803
ce = zend_hash_find_ptr(CG(class_table), lcname);
804804
if (ce
805805
&& (ce->type == ZEND_INTERNAL_CLASS
806+
|| (ce->ce_flags & ZEND_ACC_PRELOADED)
806807
|| (op_array && ce->info.user.filename == op_array->filename))) {
807808
return ce;
808809
}
@@ -847,11 +848,9 @@ const zend_class_constant *zend_fetch_class_const_info(
847848
} else {
848849
zend_class_entry *tmp = zend_hash_find_ptr(EG(class_table), Z_STR_P(op1 + 1));
849850
if (tmp != NULL) {
850-
if (tmp->type == ZEND_INTERNAL_CLASS) {
851-
ce = tmp;
852-
} else if (tmp->type == ZEND_USER_CLASS
853-
&& tmp->info.user.filename
854-
&& tmp->info.user.filename == op_array->filename) {
851+
if (tmp->type == ZEND_INTERNAL_CLASS
852+
|| (tmp->ce_flags & ZEND_ACC_PRELOADED)
853+
|| (tmp->info.user.filename && tmp->info.user.filename == op_array->filename)) {
855854
ce = tmp;
856855
}
857856
}
@@ -903,9 +902,9 @@ zend_function *zend_optimizer_get_called_func(
903902
} else if ((func = zend_hash_find_ptr(EG(function_table), function_name)) != NULL) {
904903
if (func->type == ZEND_INTERNAL_FUNCTION) {
905904
return func;
906-
} else if (func->type == ZEND_USER_FUNCTION &&
907-
func->op_array.filename &&
908-
func->op_array.filename == op_array->filename) {
905+
} else if (func->type == ZEND_USER_FUNCTION
906+
&& ((func->op_array.fn_flags & ZEND_ACC_PRELOADED)
907+
|| (func->op_array.filename && func->op_array.filename == op_array->filename))) {
909908
return func;
910909
}
911910
}
@@ -921,9 +920,9 @@ zend_function *zend_optimizer_get_called_func(
921920
} else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(function_name))) != NULL) {
922921
if (func->type == ZEND_INTERNAL_FUNCTION) {
923922
return func;
924-
} else if (func->type == ZEND_USER_FUNCTION &&
925-
func->op_array.filename &&
926-
func->op_array.filename == op_array->filename) {
923+
} else if (func->type == ZEND_USER_FUNCTION
924+
&& ((func->op_array.fn_flags & ZEND_ACC_PRELOADED)
925+
|| (func->op_array.filename && func->op_array.filename == op_array->filename))) {
927926
return func;
928927
}
929928
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
function foo() {
4+
return 42;
5+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
--TEST--
2+
Optimizer may rely on preloaded symbols
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.preload={PWD}/preload_optimizer.inc
7+
opcache.opt_debug_level=0x20000
8+
--EXTENSIONS--
9+
opcache
10+
--SKIPIF--
11+
<?php
12+
if (PHP_OS_FAMILY == 'Windows') die('skip Preloading is not supported on Windows');
13+
?>
14+
--FILE--
15+
<?php
16+
echo foo();
17+
?>
18+
--EXPECTF--
19+
$_main:
20+
; (lines=1, args=0, vars=0, tmps=%d)
21+
; (after optimizer)
22+
; $PRELOAD$:0-0
23+
0000 RETURN null
24+
25+
foo:
26+
; (lines=1, args=0, vars=0, tmps=%d)
27+
; (after optimizer)
28+
; %spreload_optimizer.inc:3-5
29+
0000 RETURN int(42)
30+
31+
$_main:
32+
; (lines=1, args=0, vars=0, tmps=%d)
33+
; (after optimizer)
34+
; %spreload_optimizer.inc:1-6
35+
0000 RETURN int(1)
36+
37+
$_main:
38+
; (lines=2, args=0, vars=0, tmps=%d)
39+
; (after optimizer)
40+
; %spreload_optimizer.php:1-4
41+
0000 ECHO string("42")
42+
0001 RETURN int(1)
43+
42

0 commit comments

Comments
 (0)