Skip to content

Commit 16de38b

Browse files
committed
fix realloc
1 parent c441c9e commit 16de38b

6 files changed

Lines changed: 300 additions & 155 deletions
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
--TEST--
2+
OPcache volatile cache compacts before remaining tail memory drops below 3 MiB
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.static_cache.volatile_size_mb=8
9+
--FILE--
10+
<?php
11+
12+
function build_low_memory_graph(): array
13+
{
14+
$rows = [];
15+
for ($i = 0; $i < 3500; $i++) {
16+
$rows[] = [
17+
$i,
18+
str_repeat(chr(65 + ($i % 26)), 48),
19+
[$i * 2, $i * 3],
20+
];
21+
}
22+
23+
return [
24+
'rows' => $rows,
25+
'meta' => ['kind' => 'low-memory'],
26+
];
27+
}
28+
29+
OPcache\volatile_clear();
30+
31+
var_dump(OPcache\volatile_store('low_memory_first', str_repeat('A', 1500000)));
32+
var_dump(OPcache\volatile_store('low_memory_graph', build_low_memory_graph()));
33+
var_dump(OPcache\volatile_store('low_memory_third', str_repeat('C', 1500000)));
34+
35+
OPcache\volatile_delete('low_memory_first');
36+
37+
var_dump(OPcache\volatile_store('low_memory_trigger', str_repeat('T', 1700000)));
38+
$graph = OPcache\volatile_fetch('low_memory_graph');
39+
OPcache\volatile_delete('low_memory_trigger');
40+
41+
var_dump(OPcache\volatile_store('low_memory_merged', str_repeat('M', 3200000)));
42+
var_dump($graph['rows'][123][1]);
43+
var_dump($graph['rows'][123][2][1]);
44+
var_dump($graph['meta']['kind']);
45+
var_dump(strlen(OPcache\volatile_fetch('low_memory_merged')));
46+
var_dump(strlen(OPcache\volatile_fetch('low_memory_third')));
47+
48+
?>
49+
--EXPECT--
50+
bool(true)
51+
bool(true)
52+
bool(true)
53+
bool(true)
54+
bool(true)
55+
string(48) "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"
56+
int(369)
57+
string(10) "low-memory"
58+
int(3200000)
59+
int(1500000)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
OPcache volatile cache keeps referenced shared graph blocks anchored during compaction
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.static_cache.volatile_size_mb=8
9+
--FILE--
10+
<?php
11+
12+
function build_anchored_graph(): array
13+
{
14+
$rows = [];
15+
for ($i = 0; $i < 3500; $i++) {
16+
$rows[] = [
17+
$i,
18+
str_repeat(chr(65 + ($i % 26)), 48),
19+
[$i * 2, $i * 3],
20+
];
21+
}
22+
23+
return [
24+
'rows' => $rows,
25+
'meta' => ['kind' => 'anchored'],
26+
];
27+
}
28+
29+
OPcache\volatile_clear();
30+
31+
var_dump(OPcache\volatile_store('shared_graph_anchor_first', str_repeat('A', 1500000)));
32+
var_dump(OPcache\volatile_store('shared_graph_anchor_graph', build_anchored_graph()));
33+
var_dump(OPcache\volatile_store('shared_graph_anchor_third', str_repeat('C', 1500000)));
34+
35+
$graph = OPcache\volatile_fetch('shared_graph_anchor_graph');
36+
OPcache\volatile_delete('shared_graph_anchor_first');
37+
38+
var_dump(OPcache\volatile_store('shared_graph_anchor_merged', str_repeat('M', 3200000)));
39+
var_dump($graph['rows'][123][1]);
40+
var_dump($graph['rows'][123][2][1]);
41+
var_dump($graph['meta']['kind']);
42+
var_dump(OPcache\volatile_fetch('shared_graph_anchor_merged', 'MISS'));
43+
var_dump(strlen(OPcache\volatile_fetch('shared_graph_anchor_third')));
44+
45+
?>
46+
--EXPECT--
47+
bool(true)
48+
bool(true)
49+
bool(true)
50+
bool(false)
51+
string(48) "TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT"
52+
int(369)
53+
string(8) "anchored"
54+
string(4) "MISS"
55+
int(1500000)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
--TEST--
2+
OPcache volatile cache keeps request-held shared graphs anchored during shutdown
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.enable=1
7+
opcache.enable_cli=1
8+
opcache.static_cache.volatile_size_mb=32
9+
--FILE--
10+
<?php
11+
12+
function build_shutdown_payload(string $prefix): array
13+
{
14+
$rows = [];
15+
16+
for ($i = 0; $i < 1024; $i++) {
17+
$rows[] = [
18+
'id' => $i,
19+
'text' => str_repeat($prefix, 32),
20+
'nested' => ['value' => $i * 3],
21+
];
22+
}
23+
24+
return [
25+
'name' => 'shutdown-anchor',
26+
'rows' => $rows,
27+
];
28+
}
29+
30+
OPcache\volatile_clear();
31+
32+
var_dump(OPcache\volatile_store('fragment-padding', str_repeat('P', 131072)));
33+
var_dump(OPcache\volatile_store('shutdown-anchor', build_shutdown_payload('A')));
34+
OPcache\volatile_delete('fragment-padding');
35+
36+
$_POST['shutdown-anchor'] = OPcache\volatile_fetch('shutdown-anchor');
37+
38+
echo $_POST['shutdown-anchor']['name'], "\n";
39+
echo $_POST['shutdown-anchor']['rows'][123]['text'], "\n";
40+
echo $_POST['shutdown-anchor']['rows'][123]['nested']['value'], "\n";
41+
42+
?>
43+
--EXPECT--
44+
bool(true)
45+
bool(true)
46+
shutdown-anchor
47+
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
48+
369

ext/opcache/zend_static_cache.c

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,6 @@ static zend_always_inline bool zend_opcache_static_cache_validate_api_value(zval
277277
return true;
278278
}
279279

280-
static void zend_opcache_static_cache_register_accelerator_handlers(void);
281-
282280
static void zend_opcache_static_cache_safe_direct_handlers_dtor(zval *zv)
283281
{
284282
pefree(Z_PTR_P(zv), true);
@@ -1121,29 +1119,6 @@ zend_result zend_opcache_register_functions(int module_type)
11211119
return zend_register_functions(NULL, ext_functions, NULL, module_type);
11221120
}
11231121

1124-
zend_result zend_opcache_static_cache_minit(void)
1125-
{
1126-
zend_opcache_static_cache_context *previous_context;
1127-
1128-
zend_opcache_static_cache_subsystem_disabled = false;
1129-
zend_opcache_static_cache_subsystem_failure_reason = NULL;
1130-
zend_opcache_static_cache_safe_direct_classes_marked = false;
1131-
1132-
zend_opcache_static_cache_register_classes();
1133-
zend_opcache_static_cache_safe_direct_handlers_init();
1134-
zend_opcache_static_cache_register_accelerator_handlers();
1135-
1136-
previous_context = zend_opcache_static_cache_activate_context(&zend_opcache_static_cache_volatile_context_state);
1137-
zend_opcache_static_cache_reset_storage();
1138-
1139-
zend_opcache_static_cache_activate_context(&zend_opcache_static_cache_pinned_context_state);
1140-
zend_opcache_static_cache_reset_storage();
1141-
1142-
zend_opcache_static_cache_restore_context(previous_context);
1143-
1144-
return SUCCESS;
1145-
}
1146-
11471122
static void zend_opcache_static_cache_startup(void)
11481123
{
11491124
const char *failure_reason;
@@ -1290,17 +1265,11 @@ static zend_result zend_opcache_static_cache_rinit(void)
12901265

12911266
zend_result zend_opcache_static_cache_rshutdown(void)
12921267
{
1293-
bool shared_graph_refs_released;
1294-
12951268
zend_opcache_static_cache_clear_lookup_caches();
12961269
zend_opcache_static_cache_request_shutdown();
12971270
zend_opcache_static_cache_release_request_entry_locks();
12981271
zend_opcache_static_cache_release_request_local_slots();
1299-
1300-
shared_graph_refs_released = zend_opcache_static_cache_release_request_shared_graph_refs();
1301-
if (shared_graph_refs_released) {
1302-
zend_opcache_static_cache_compact_after_request_shutdown();
1303-
}
1272+
zend_opcache_static_cache_release_request_shared_graph_refs();
13041273

13051274
EG(static_cache_class_access_active) = false;
13061275
EG(tracked_mutation_hooks_active) = false;
@@ -1326,6 +1295,29 @@ static void zend_opcache_static_cache_register_accelerator_handlers(void)
13261295
zend_accel_register_static_cache_handlers(&handlers);
13271296
}
13281297

1298+
zend_result zend_opcache_static_cache_minit(void)
1299+
{
1300+
zend_opcache_static_cache_context *previous_context;
1301+
1302+
zend_opcache_static_cache_subsystem_disabled = false;
1303+
zend_opcache_static_cache_subsystem_failure_reason = NULL;
1304+
zend_opcache_static_cache_safe_direct_classes_marked = false;
1305+
1306+
zend_opcache_static_cache_register_classes();
1307+
zend_opcache_static_cache_safe_direct_handlers_init();
1308+
zend_opcache_static_cache_register_accelerator_handlers();
1309+
1310+
previous_context = zend_opcache_static_cache_activate_context(&zend_opcache_static_cache_volatile_context_state);
1311+
zend_opcache_static_cache_reset_storage();
1312+
1313+
zend_opcache_static_cache_activate_context(&zend_opcache_static_cache_pinned_context_state);
1314+
zend_opcache_static_cache_reset_storage();
1315+
1316+
zend_opcache_static_cache_restore_context(previous_context);
1317+
1318+
return SUCCESS;
1319+
}
1320+
13291321
void zend_opcache_static_cache_invalidate_all(void)
13301322
{
13311323
zend_opcache_static_cache_invalidate_all_context(&zend_opcache_static_cache_pinned_context_state);

ext/opcache/zend_static_cache_internal.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
#define ZEND_OPCACHE_STATIC_CACHE_LOOKUP_INVALID_SLOT UINT32_MAX
8787

8888
#define ZEND_OPCACHE_STATIC_CACHE_ENTRY_LOCK_STRIPES 256U
89+
#define ZEND_OPCACHE_STATIC_CACHE_LOW_MEMORY_COMPACT_THRESHOLD (3U * 1024U * 1024U)
8990

9091
#define ZEND_OPCACHE_STATIC_CACHE_LOOKUP_EMPTY 0
9192
#define ZEND_OPCACHE_STATIC_CACHE_LOOKUP_HIT 1
@@ -421,8 +422,6 @@ bool zend_opcache_static_cache_header_init_locked(void);
421422
void zend_opcache_static_cache_free_locked(uint32_t payload_offset);
422423
uint32_t zend_opcache_static_cache_alloc_locked(size_t size, const void *source);
423424
bool zend_opcache_static_cache_compact_to_fit_locked(size_t size);
424-
bool zend_opcache_static_cache_compact_available_locked(void);
425-
void zend_opcache_static_cache_compact_after_request_shutdown(void);
426425
bool zend_opcache_static_cache_startup_storage_before_request(void);
427426
void zend_opcache_static_cache_shutdown_storage(void);
428427
void zend_opcache_static_cache_ensure_ready(void);

0 commit comments

Comments
 (0)