Skip to content

Commit ee3f932

Browse files
committed
Fix GH-11715: opcache.interned_strings_buffer either has no effect or opcache_get_status() / phpinfo() is wrong
There are a couple of oddities. 1) The interned strings buffer comprises the whole hashtable datastructure. Therefore, it seems that the interned strings buffer size is the size of only said table. However, in the current code it also includes the size of the zend_accel_shared_globals. 2) ZCSG(interned_strings).end is computed starting from the accelerator globals struct itself. I would expect it to start from the part where the interned strings table starts. 3) When computing the used size, it is done using ZCSG(interned_strings).end - ZCSG(interned_strings).start. However, this does not include the uin32_t slots array because ZCSG(interned_strings).start pointers after that array. This patch corrrects these 3 points. Closes GH-11717.
1 parent 11d6bea commit ee3f932

File tree

4 files changed

+28
-5
lines changed

4 files changed

+28
-5
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ PHP NEWS
55
- FFI:
66
. Fix leaking definitions when using FFI::cdef()->new(...). (ilutov)
77

8+
- Opcache:
9+
. Fixed bug GH-11715 (opcache.interned_strings_buffer either has no effect or
10+
opcache_get_status() / phpinfo() is wrong). (nielsdos)
11+
812
03 Aug 2023, PHP 8.1.22
913

1014
- Build:

ext/opcache/ZendAccelerator.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2856,7 +2856,7 @@ static int zend_accel_init_shm(void)
28562856
zend_shared_alloc_lock();
28572857

28582858
if (ZCG(accel_directives).interned_strings_buffer) {
2859-
accel_shared_globals = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024));
2859+
accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024));
28602860
} else {
28612861
/* Make sure there is always at least one interned string hash slot,
28622862
* so the table can be queried unconditionally. */
@@ -2893,7 +2893,7 @@ static int zend_accel_init_shm(void)
28932893
ZCSG(interned_strings).top =
28942894
ZCSG(interned_strings).start;
28952895
ZCSG(interned_strings).end =
2896-
(zend_string*)((char*)accel_shared_globals +
2896+
(zend_string*)((char*)(accel_shared_globals + 1) + /* table data is stored after accel_shared_globals */
28972897
ZCG(accel_directives).interned_strings_buffer * 1024 * 1024);
28982898
ZCSG(interned_strings).saved_top = NULL;
28992899

ext/opcache/tests/gh11715.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
GH-11715 (opcache.interned_strings_buffer either has no effect or opcache_get_status() / phpinfo() is wrong)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.interned_strings_buffer=16
9+
--FILE--
10+
<?php
11+
12+
$info = opcache_get_status()['interned_strings_usage'];
13+
var_dump($info['used_memory'] + $info['free_memory']);
14+
var_dump($info['buffer_size']);
15+
16+
?>
17+
--EXPECT--
18+
int(16777216)
19+
int(16777216)

ext/opcache/zend_accelerator_module.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS)
487487
snprintf(buf, sizeof(buf), "%zu", ZSMMG(wasted_shared_memory));
488488
php_info_print_table_row(2, "Wasted memory", buf);
489489
if (ZCSG(interned_strings).start && ZCSG(interned_strings).end) {
490-
snprintf(buf, sizeof(buf), "%zu", (size_t)((char*)ZCSG(interned_strings).top - (char*)ZCSG(interned_strings).start));
490+
snprintf(buf, sizeof(buf), "%zu", (size_t)((char*)ZCSG(interned_strings).top - (char*)(accel_shared_globals + 1)));
491491
php_info_print_table_row(2, "Interned Strings Used memory", buf);
492492
snprintf(buf, sizeof(buf), "%zu", (size_t)((char*)ZCSG(interned_strings).end - (char*)ZCSG(interned_strings).top));
493493
php_info_print_table_row(2, "Interned Strings Free memory", buf);
@@ -628,8 +628,8 @@ ZEND_FUNCTION(opcache_get_status)
628628
zval interned_strings_usage;
629629

630630
array_init(&interned_strings_usage);
631-
add_assoc_long(&interned_strings_usage, "buffer_size", (char*)ZCSG(interned_strings).end - (char*)ZCSG(interned_strings).start);
632-
add_assoc_long(&interned_strings_usage, "used_memory", (char*)ZCSG(interned_strings).top - (char*)ZCSG(interned_strings).start);
631+
add_assoc_long(&interned_strings_usage, "buffer_size", (char*)ZCSG(interned_strings).end - (char*)(accel_shared_globals + 1));
632+
add_assoc_long(&interned_strings_usage, "used_memory", (char*)ZCSG(interned_strings).top - (char*)(accel_shared_globals + 1));
633633
add_assoc_long(&interned_strings_usage, "free_memory", (char*)ZCSG(interned_strings).end - (char*)ZCSG(interned_strings).top);
634634
add_assoc_long(&interned_strings_usage, "number_of_strings", ZCSG(interned_strings).nNumOfElements);
635635
add_assoc_zval(return_value, "interned_strings_usage", &interned_strings_usage);

0 commit comments

Comments
 (0)