Skip to content
Open
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
83 changes: 83 additions & 0 deletions ext/opcache/tests/gh17770_jit_file_cache_write.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
--TEST--
GH-17770: opcache.file_cache writes with JIT enabled
--SKIPIF--
<?php
@mkdir(__DIR__ . '/gh17770_cache', 0777, true);
if (ini_get('opcache.jit') === false) {
die('skip JIT is not supported');
}
?>
--EXTENSIONS--
opcache
--INI--
opcache.enable=1
opcache.enable_cli=1
opcache.jit=tracing
opcache.jit_buffer_size=16M
opcache.file_cache="{PWD}/gh17770_cache"
opcache.file_cache_consistency_checks=0
--FILE--
<?php
function removeDirRecursive(string $dir): void {
if (!is_dir($dir)) {
return;
}

$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);

foreach ($iterator as $entry) {
if ($entry->isDir()) {
@rmdir($entry->getRealPath());
} else {
@unlink($entry->getRealPath());
}
}

@rmdir($dir);
}

$cacheDir = ini_get('opcache.file_cache');
removeDirRecursive($cacheDir);
@mkdir($cacheDir, 0777, true);

$tmpPhpFile = __DIR__ . '/gh17770-opcache-target.php';
file_put_contents($tmpPhpFile, "<?php\nfunction gh17770() { return 42; }\ngh17770();\n");

@opcache_reset();
opcache_compile_file($tmpPhpFile);

$hasCacheFile = opcache_is_script_cached_in_file_cache($tmpPhpFile);

echo $hasCacheFile ? "OK\n" : "FAIL: opcache file cache is empty\n";
?>
--CLEAN--
<?php
function removeDirRecursive(string $dir): void {
if (!is_dir($dir)) {
return;
}

$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);

foreach ($iterator as $entry) {
if ($entry->isDir()) {
@rmdir($entry->getRealPath());
} else {
@unlink($entry->getRealPath());
}
}

@rmdir($dir);
}

removeDirRecursive(__DIR__ . '/gh17770_cache');
@unlink(__DIR__ . '/gh17770-opcache-target.php');
?>
--EXPECT--
OK
31 changes: 27 additions & 4 deletions ext/opcache/zend_file_cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,10 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
/* relative extended_value don't have to be changed */
break;
}
#endif
#ifdef HAVE_JIT
/* Re-normalize handlers before serializing to avoid storing JIT runtime handlers. */
ZEND_VM_SET_OPCODE_HANDLER(opline);
#endif
zend_serialize_opcode_handler(opline);
opline++;
Expand Down Expand Up @@ -1152,15 +1156,19 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm)
char *filename;
zend_file_cache_metainfo info;
void *mem, *buf;

#ifdef HAVE_JIT
/* FIXME: dump jited codes out to file cache? */
if (JIT_G(on)) {
return FAILURE;
bool orig_jit_on = JIT_G(on);

/* File cache stores bytecode/metadata only; JIT code is rebuilt at runtime. */
if (orig_jit_on) {
JIT_G(on) = 0;
}
#endif

if (ZCG(accel_directives).file_cache_read_only) {
#ifdef HAVE_JIT
JIT_G(on) = orig_jit_on;
#endif
return FAILURE;
}

Expand All @@ -1169,6 +1177,9 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm)
if (zend_file_cache_mkdir(filename, strlen(ZCG(accel_directives).file_cache)) != SUCCESS) {
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot create directory for file '%s', %s\n", filename, strerror(errno));
efree(filename);
#ifdef HAVE_JIT
JIT_G(on) = orig_jit_on;
#endif
return FAILURE;
}

Expand All @@ -1178,12 +1189,18 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm)
zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot create file '%s', %s\n", filename, strerror(errno));
}
efree(filename);
#ifdef HAVE_JIT
JIT_G(on) = orig_jit_on;
#endif
return FAILURE;
}

if (zend_file_cache_flock(fd, LOCK_EX) != 0) {
close(fd);
efree(filename);
#ifdef HAVE_JIT
JIT_G(on) = orig_jit_on;
#endif
return FAILURE;
}

Expand Down Expand Up @@ -1227,6 +1244,9 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm)
efree(mem);
zend_file_cache_unlink(filename);
efree(filename);
#ifdef HAVE_JIT
JIT_G(on) = orig_jit_on;
#endif
return FAILURE;
}

Expand All @@ -1237,6 +1257,9 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm)
}
close(fd);
efree(filename);
#ifdef HAVE_JIT
JIT_G(on) = orig_jit_on;
#endif

return SUCCESS;
}
Expand Down
Loading