Skip to content

Commit 3ffd530

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 8e93eb2 commit 3ffd530

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
@@ -802,6 +802,7 @@ zend_class_entry *zend_optimizer_get_class_entry(
802802
ce = zend_hash_find_ptr(CG(class_table), lcname);
803803
if (ce
804804
&& (ce->type == ZEND_INTERNAL_CLASS
805+
|| (ce->ce_flags & ZEND_ACC_PRELOADED)
805806
|| (op_array && ce->info.user.filename == op_array->filename))) {
806807
return ce;
807808
}
@@ -846,11 +847,9 @@ const zend_class_constant *zend_fetch_class_const_info(
846847
} else {
847848
zend_class_entry *tmp = zend_hash_find_ptr(EG(class_table), Z_STR_P(op1 + 1));
848849
if (tmp != NULL) {
849-
if (tmp->type == ZEND_INTERNAL_CLASS) {
850-
ce = tmp;
851-
} else if (tmp->type == ZEND_USER_CLASS
852-
&& tmp->info.user.filename
853-
&& tmp->info.user.filename == op_array->filename) {
850+
if (tmp->type == ZEND_INTERNAL_CLASS
851+
|| (tmp->ce_flags & ZEND_ACC_PRELOADED)
852+
|| (tmp->info.user.filename && tmp->info.user.filename == op_array->filename)) {
854853
ce = tmp;
855854
}
856855
}
@@ -902,9 +901,9 @@ zend_function *zend_optimizer_get_called_func(
902901
} else if ((func = zend_hash_find_ptr(EG(function_table), function_name)) != NULL) {
903902
if (func->type == ZEND_INTERNAL_FUNCTION) {
904903
return func;
905-
} else if (func->type == ZEND_USER_FUNCTION &&
906-
func->op_array.filename &&
907-
func->op_array.filename == op_array->filename) {
904+
} else if (func->type == ZEND_USER_FUNCTION
905+
&& ((func->op_array.fn_flags & ZEND_ACC_PRELOADED)
906+
|| (func->op_array.filename && func->op_array.filename == op_array->filename))) {
908907
return func;
909908
}
910909
}
@@ -920,9 +919,9 @@ zend_function *zend_optimizer_get_called_func(
920919
} else if ((func = zend_hash_find_ptr(EG(function_table), Z_STR_P(function_name))) != NULL) {
921920
if (func->type == ZEND_INTERNAL_FUNCTION) {
922921
return func;
923-
} else if (func->type == ZEND_USER_FUNCTION &&
924-
func->op_array.filename &&
925-
func->op_array.filename == op_array->filename) {
922+
} else if (func->type == ZEND_USER_FUNCTION
923+
&& ((func->op_array.fn_flags & ZEND_ACC_PRELOADED)
924+
|| (func->op_array.filename && func->op_array.filename == op_array->filename))) {
926925
return func;
927926
}
928927
}
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)