Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions ext/opcache/ZendAccelerator.c
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,9 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
{
zend_persistent_script *persistent_script;
zend_op_array *op_array = NULL;
int is_should_release_outside = 0;
zend_arena *arena = NULL;
void *checkpoint;
int from_memory; /* if the script we've got is stored in SHM */

if (is_stream_path(file_handle->filename) &&
Expand All @@ -1840,7 +1843,7 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)

HANDLE_BLOCK_INTERRUPTIONS();
SHM_UNPROTECT();
persistent_script = zend_file_cache_script_load(file_handle);
persistent_script = zend_file_cache_script_load(file_handle ,&is_should_release_outside,&arena,&checkpoint);
SHM_PROTECT();
HANDLE_UNBLOCK_INTERRUPTIONS();
if (persistent_script) {
Expand Down Expand Up @@ -1871,8 +1874,11 @@ zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int type)
if (persistent_script->ping_auto_globals_mask) {
zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask);
}

return zend_accel_load_script(persistent_script, 1);
op_array = zend_accel_load_script(persistent_script, 1);
if(is_should_release_outside){
zend_arena_release(&arena, checkpoint);
}
return op_array;
}

persistent_script = opcache_compile_file(file_handle, type, NULL, &op_array);
Expand Down Expand Up @@ -1916,6 +1922,10 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
char *key = NULL;
int key_length;
int from_shared_memory; /* if the script we've got is stored in SHM */
zend_op_array *op_array = NULL;
int is_should_release_outside = 0;
zend_arena *arena = NULL;
void *checkpoint = NULL;

if (!file_handle->filename || !ZCG(accelerator_enabled)) {
/* The Accelerator is disabled, act as if without the Accelerator */
Expand Down Expand Up @@ -2100,7 +2110,7 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)

/* Check the second level cache */
if (!persistent_script && ZCG(accel_directives).file_cache) {
persistent_script = zend_file_cache_script_load(file_handle);
persistent_script = zend_file_cache_script_load(file_handle,&is_should_release_outside,&arena,&checkpoint);
}

/* If script was not found or invalidated by validate_timestamps */
Expand Down Expand Up @@ -2200,8 +2210,11 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
if (persistent_script->ping_auto_globals_mask) {
zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask);
}

return zend_accel_load_script(persistent_script, from_shared_memory);
op_array = zend_accel_load_script(persistent_script, from_shared_memory);
if(from_shared_memory && is_should_release_outside){
zend_arena_release(&arena, checkpoint);
}
return op_array;
}

#ifdef ZEND_WIN32
Expand Down
20 changes: 20 additions & 0 deletions ext/opcache/tests/bug78076.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--TEST--
Bug #78076 Opcache greatly increases memory usage.
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.file_cache="{TMP}"
opcache.file_cache_only=1
--SKIPIF--
--FILE--
<?php
$start = memory_get_usage();
for ($x = 1; $x < 10000; $x += 1) {
include("leaktest.inc");
}
$end = memory_get_usage();
var_dump($end - $start < 1000);
?>
--EXPECT--
bool(true)

2 changes: 2 additions & 0 deletions ext/opcache/tests/leaktest.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
$a='hello world';
5 changes: 4 additions & 1 deletion ext/opcache/zend_file_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1521,7 +1521,7 @@ static void zend_file_cache_unserialize(zend_persistent_script *script,
UNSERIALIZE_PTR(script->arena_mem);
}

zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle)
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle,int *is_should_release_outside,zend_arena **arena_ptr,void **checkpoint_ptr)
{
zend_string *full_path = file_handle->opened_path;
int fd;
Expand Down Expand Up @@ -1669,6 +1669,9 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
zend_map_ptr_extend(ZCSG(map_ptr_last));
} else {
use_process_mem:
*is_should_release_outside = 1;
*arena_ptr = CG(arena);
*checkpoint_ptr = checkpoint;
buf = mem;
cache_it = 0;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/zend_file_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define ZEND_FILE_CACHE_H

int zend_file_cache_script_store(zend_persistent_script *script, int in_shm);
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle);
zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handle,int *is_should_release_outside,zend_arena **arena_ptr,void **checkpoint_ptr);
void zend_file_cache_invalidate(zend_string *full_path);

#endif /* ZEND_FILE_CACHE_H */