php-src/ext/opcache/zend_shared_alloc.c

674 lines
18 KiB
C
Raw Normal View History

2013-02-13 12:26:47 +00:00
/*
+----------------------------------------------------------------------+
| Zend OPcache |
2013-02-13 12:26:47 +00:00
+----------------------------------------------------------------------+
2019-02-05 07:33:28 +00:00
| Copyright (c) The PHP Group |
2013-02-13 12:26:47 +00:00
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| https://www.php.net/license/3_01.txt |
2013-02-13 12:26:47 +00:00
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
2018-11-01 16:30:28 +00:00
| Authors: Andi Gutmans <andi@php.net> |
| Zeev Suraski <zeev@php.net> |
2013-02-13 12:26:47 +00:00
| Stanislav Malyshev <stas@zend.com> |
2018-11-01 16:30:28 +00:00
| Dmitry Stogov <dmitry@php.net> |
2013-02-13 12:26:47 +00:00
+----------------------------------------------------------------------+
*/
#if defined(__linux__) && defined(HAVE_MEMFD_CREATE)
# ifndef _GNU_SOURCE
# define _GNU_SOURCE
# endif
# include <sys/mman.h>
#endif
2013-02-13 12:26:47 +00:00
#include <errno.h>
#include "ZendAccelerator.h"
#include "zend_shared_alloc.h"
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <fcntl.h>
#ifndef ZEND_WIN32
# include <sys/types.h>
# include <signal.h>
# include <sys/stat.h>
# include <stdio.h>
#endif
#ifdef HAVE_MPROTECT
# include "sys/mman.h"
#endif
#define SEM_FILENAME_PREFIX ".ZendSem."
#define S_H(s) g_shared_alloc_handler->s
/* True globals */
/* old/new mapping. We can use true global even for ZTS because its usage
is wrapped with exclusive lock anyway */
static const zend_shared_memory_handlers *g_shared_alloc_handler = NULL;
static const char *g_shared_model;
/* pointer to globals allocated in SHM and shared across processes */
2024-08-26 12:54:36 +00:00
ZEND_EXT_API zend_smm_shared_globals *smm_shared_globals;
2013-02-13 12:26:47 +00:00
#ifndef ZEND_WIN32
2013-02-15 11:08:51 +00:00
#ifdef ZTS
static MUTEX_T zts_lock;
#endif
int lock_file = -1;
static char lockfile_name[MAXPATHLEN];
2013-02-13 12:26:47 +00:00
#endif
static const zend_shared_memory_handler_entry handler_table[] = {
#ifdef USE_MMAP
2013-02-13 12:26:47 +00:00
{ "mmap", &zend_alloc_mmap_handlers },
#endif
#ifdef USE_SHM
2013-02-13 12:26:47 +00:00
{ "shm", &zend_alloc_shm_handlers },
#endif
#ifdef USE_SHM_OPEN
2013-02-13 12:26:47 +00:00
{ "posix", &zend_alloc_posix_handlers },
#endif
#ifdef ZEND_WIN32
{ "win32", &zend_alloc_win32_handlers },
#endif
{ NULL, NULL}
};
#ifndef ZEND_WIN32
void zend_shared_alloc_create_lock(char *lockfile_path)
2013-02-13 12:26:47 +00:00
{
int val;
2013-02-15 11:08:51 +00:00
#ifdef ZTS
2021-06-29 08:04:10 +00:00
zts_lock = tsrm_mutex_alloc();
2013-02-15 11:08:51 +00:00
#endif
#if defined(__linux__) && defined(HAVE_MEMFD_CREATE)
/* on Linux, we can use a memfd instead of a "real" file, so
* we can do this without a writable filesystem and without
* needing to clean up */
/* note: FreeBSD has memfd_create(), too, but fcntl(F_SETLKW)
* on it fails with EBADF, therefore we use this only on
* Linux */
lock_file = memfd_create("opcache_lock", MFD_CLOEXEC);
if (lock_file >= 0)
return;
#endif
#ifdef O_TMPFILE
lock_file = open(lockfile_path, O_RDWR | O_TMPFILE | O_EXCL | O_CLOEXEC, 0666);
/* lack of O_TMPFILE support results in many possible errors
* use it only when open returns a non-negative integer */
if (lock_file >= 0) {
return;
}
#endif
snprintf(lockfile_name, sizeof(lockfile_name), "%s/%sXXXXXX", lockfile_path, SEM_FILENAME_PREFIX);
2013-02-13 12:26:47 +00:00
lock_file = mkstemp(lockfile_name);
if (lock_file == -1) {
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Unable to create opcache lock file in %s: %s (%d)", lockfile_path, strerror(errno), errno);
2013-02-13 12:26:47 +00:00
}
fchmod(lock_file, 0666);
2013-02-13 12:26:47 +00:00
val = fcntl(lock_file, F_GETFD, 0);
val |= FD_CLOEXEC;
fcntl(lock_file, F_SETFD, val);
unlink(lockfile_name);
}
#endif
static void no_memory_bailout(size_t allocate_size, const char *error)
2013-02-13 12:26:47 +00:00
{
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Unable to allocate shared memory segment of %zu bytes: %s: %s (%d)", allocate_size, error?error:"unknown", strerror(errno), errno );
2013-02-13 12:26:47 +00:00
}
static void copy_shared_segments(void *to, void *from, int count, int size)
{
zend_shared_segment **shared_segments_v = (zend_shared_segment **)to;
void *shared_segments_to_p = ((char *)to + count*(sizeof(void *)));
void *shared_segments_from_p = from;
int i;
2013-02-22 06:56:05 +00:00
for (i = 0; i < count; i++) {
2013-02-13 12:26:47 +00:00
shared_segments_v[i] = shared_segments_to_p;
memcpy(shared_segments_to_p, shared_segments_from_p, size);
shared_segments_to_p = ((char *)shared_segments_to_p + size);
shared_segments_from_p = ((char *)shared_segments_from_p + size);
}
}
static int zend_shared_alloc_try(const zend_shared_memory_handler_entry *he, size_t requested_size, zend_shared_segment ***shared_segments_p, int *shared_segments_count, const char **error_in)
2013-02-13 12:26:47 +00:00
{
int res;
g_shared_alloc_handler = he->handler;
g_shared_model = he->name;
ZSMMG(shared_segments) = NULL;
ZSMMG(shared_segments_count) = 0;
res = S_H(create_segments)(requested_size, shared_segments_p, shared_segments_count, error_in);
2013-02-22 06:56:05 +00:00
if (res) {
2013-02-13 12:26:47 +00:00
/* this model works! */
return res;
}
2013-02-22 06:56:05 +00:00
if (*shared_segments_p) {
2013-02-13 12:26:47 +00:00
int i;
/* cleanup */
2013-02-22 06:56:05 +00:00
for (i = 0; i < *shared_segments_count; i++) {
if ((*shared_segments_p)[i]->p && (*shared_segments_p)[i]->p != (void *)-1) {
2013-02-13 12:26:47 +00:00
S_H(detach_segment)((*shared_segments_p)[i]);
}
}
free(*shared_segments_p);
*shared_segments_p = NULL;
}
g_shared_alloc_handler = NULL;
return ALLOC_FAILURE;
}
2019-04-01 07:27:11 +00:00
int zend_shared_alloc_startup(size_t requested_size, size_t reserved_size)
2013-02-13 12:26:47 +00:00
{
zend_shared_segment **tmp_shared_segments;
size_t shared_segments_array_size;
zend_smm_shared_globals tmp_shared_globals, *p_tmp_shared_globals;
const char *error_in = NULL;
2013-02-13 12:26:47 +00:00
const zend_shared_memory_handler_entry *he;
int res = ALLOC_FAILURE;
2019-04-01 07:27:11 +00:00
int i;
2013-02-13 12:26:47 +00:00
/* shared_free must be valid before we call zend_shared_alloc()
* - make it temporarily point to a local variable
*/
smm_shared_globals = &tmp_shared_globals;
2019-04-01 07:27:11 +00:00
ZSMMG(shared_free) = requested_size - reserved_size; /* goes to tmp_shared_globals.shared_free */
2013-02-13 12:26:47 +00:00
#ifndef ZEND_WIN32
zend_shared_alloc_create_lock(ZCG(accel_directives).lockfile_path);
#else
2013-02-13 12:26:47 +00:00
zend_shared_alloc_create_lock();
#endif
2013-02-13 12:26:47 +00:00
2013-02-22 06:56:05 +00:00
if (ZCG(accel_directives).memory_model && ZCG(accel_directives).memory_model[0]) {
const char *model = ZCG(accel_directives).memory_model;
2013-02-13 12:26:47 +00:00
/* "cgi" is really "shm"... */
2013-02-22 06:56:05 +00:00
if (strncmp(ZCG(accel_directives).memory_model, "cgi", sizeof("cgi")) == 0) {
2013-02-13 12:26:47 +00:00
model = "shm";
}
2013-02-22 06:56:05 +00:00
for (he = handler_table; he->name; he++) {
if (strcmp(model, he->name) == 0) {
res = zend_shared_alloc_try(he, requested_size, &ZSMMG(shared_segments), &ZSMMG(shared_segments_count), &error_in);
if (res) {
2013-02-13 12:26:47 +00:00
/* this model works! */
break;
2013-02-13 12:26:47 +00:00
}
}
}
}
2013-02-22 06:56:05 +00:00
if (res == FAILED_REATTACHED) {
2013-02-13 12:26:47 +00:00
smm_shared_globals = NULL;
return res;
}
#if ENABLE_FILE_CACHE_FALLBACK
if (ALLOC_FALLBACK == res) {
smm_shared_globals = NULL;
return ALLOC_FALLBACK;
}
#endif
2013-02-13 12:26:47 +00:00
2013-02-22 06:56:05 +00:00
if (!g_shared_alloc_handler) {
2013-02-13 12:26:47 +00:00
/* try memory handlers in order */
2013-02-22 06:56:05 +00:00
for (he = handler_table; he->name; he++) {
res = zend_shared_alloc_try(he, requested_size, &ZSMMG(shared_segments), &ZSMMG(shared_segments_count), &error_in);
if (res) {
2013-02-13 12:26:47 +00:00
/* this model works! */
break;
}
}
}
2013-02-22 06:56:05 +00:00
if (!g_shared_alloc_handler) {
2013-02-13 12:26:47 +00:00
no_memory_bailout(requested_size, error_in);
return ALLOC_FAILURE;
}
2013-02-22 06:56:05 +00:00
if (res == SUCCESSFULLY_REATTACHED) {
2013-02-13 12:26:47 +00:00
return res;
}
#if ENABLE_FILE_CACHE_FALLBACK
if (ALLOC_FALLBACK == res) {
smm_shared_globals = NULL;
return ALLOC_FALLBACK;
}
#endif
2013-02-13 12:26:47 +00:00
2019-04-01 07:27:11 +00:00
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
ZSMMG(shared_segments)[i]->end = ZSMMG(shared_segments)[i]->size;
}
2013-02-22 06:56:05 +00:00
shared_segments_array_size = ZSMMG(shared_segments_count) * S_H(segment_type_size)();
2013-02-13 12:26:47 +00:00
/* move shared_segments and shared_free to shared memory */
ZCG(locked) = 1; /* no need to perform a real lock at this point */
2019-04-01 07:27:11 +00:00
2013-02-13 12:26:47 +00:00
p_tmp_shared_globals = (zend_smm_shared_globals *) zend_shared_alloc(sizeof(zend_smm_shared_globals));
if (!p_tmp_shared_globals) {
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Insufficient shared memory!");
2017-06-25 21:24:23 +00:00
return ALLOC_FAILURE;
}
memset(p_tmp_shared_globals, 0, sizeof(zend_smm_shared_globals));
2013-02-13 12:26:47 +00:00
2013-02-22 06:56:05 +00:00
tmp_shared_segments = zend_shared_alloc(shared_segments_array_size + ZSMMG(shared_segments_count) * sizeof(void *));
if (!tmp_shared_segments) {
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Insufficient shared memory!");
2017-06-25 21:24:23 +00:00
return ALLOC_FAILURE;
}
2013-02-13 12:26:47 +00:00
copy_shared_segments(tmp_shared_segments, ZSMMG(shared_segments)[0], ZSMMG(shared_segments_count), S_H(segment_type_size)());
*p_tmp_shared_globals = tmp_shared_globals;
smm_shared_globals = p_tmp_shared_globals;
free(ZSMMG(shared_segments));
ZSMMG(shared_segments) = tmp_shared_segments;
ZSMMG(shared_memory_state).positions = (size_t *)zend_shared_alloc(sizeof(size_t) * ZSMMG(shared_segments_count));
if (!ZSMMG(shared_memory_state).positions) {
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Insufficient shared memory!");
2017-06-25 21:24:23 +00:00
return ALLOC_FAILURE;
}
2019-04-01 07:27:11 +00:00
if (reserved_size) {
i = ZSMMG(shared_segments_count) - 1;
if (ZSMMG(shared_segments)[i]->size - ZSMMG(shared_segments)[i]->pos >= reserved_size) {
ZSMMG(shared_segments)[i]->end = ZSMMG(shared_segments)[i]->size - reserved_size;
ZSMMG(reserved) = (char*)ZSMMG(shared_segments)[i]->p + ZSMMG(shared_segments)[i]->end;
ZSMMG(reserved_size) = reserved_size;
} else {
zend_accel_error_noreturn(ACCEL_LOG_FATAL, "Insufficient shared memory!");
2019-04-01 07:27:11 +00:00
return ALLOC_FAILURE;
}
}
ZCG(locked) = 0;
2013-02-13 12:26:47 +00:00
return res;
}
void zend_shared_alloc_shutdown(void)
{
zend_shared_segment **tmp_shared_segments;
2018-10-25 16:24:39 +00:00
zend_shared_segment *shared_segments_buf[16];
2013-02-13 12:26:47 +00:00
size_t shared_segments_array_size;
zend_smm_shared_globals tmp_shared_globals;
int i;
tmp_shared_globals = *smm_shared_globals;
smm_shared_globals = &tmp_shared_globals;
2013-02-22 06:56:05 +00:00
shared_segments_array_size = ZSMMG(shared_segments_count) * (S_H(segment_type_size)() + sizeof(void *));
2018-10-25 16:24:39 +00:00
if (shared_segments_array_size > 16) {
tmp_shared_segments = malloc(shared_segments_array_size);
} else {
tmp_shared_segments = shared_segments_buf;
}
2013-02-13 12:26:47 +00:00
copy_shared_segments(tmp_shared_segments, ZSMMG(shared_segments)[0], ZSMMG(shared_segments_count), S_H(segment_type_size)());
ZSMMG(shared_segments) = tmp_shared_segments;
2013-02-22 06:56:05 +00:00
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
2013-02-13 12:26:47 +00:00
S_H(detach_segment)(ZSMMG(shared_segments)[i]);
}
2018-10-25 16:24:39 +00:00
if (shared_segments_array_size > 16) {
free(ZSMMG(shared_segments));
}
2013-02-13 12:26:47 +00:00
ZSMMG(shared_segments) = NULL;
g_shared_alloc_handler = NULL;
#ifndef ZEND_WIN32
close(lock_file);
# ifdef ZTS
tsrm_mutex_free(zts_lock);
# endif
2013-02-13 12:26:47 +00:00
#endif
}
2013-03-15 07:49:33 +00:00
static size_t zend_shared_alloc_get_largest_free_block(void)
{
int i;
size_t largest_block_size = 0;
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
2019-04-01 07:27:11 +00:00
size_t block_size = ZSMMG(shared_segments)[i]->end - ZSMMG(shared_segments)[i]->pos;
2013-03-15 07:49:33 +00:00
if (block_size>largest_block_size) {
largest_block_size = block_size;
}
}
return largest_block_size;
}
#define MIN_FREE_MEMORY 64*1024
2013-02-19 14:04:40 +00:00
#define SHARED_ALLOC_FAILED() do { \
zend_accel_error(ACCEL_LOG_WARNING, "Not enough free shared space to allocate %zu bytes (%zu bytes free)", size, ZSMMG(shared_free)); \
2013-03-15 07:49:33 +00:00
if (zend_shared_alloc_get_largest_free_block() < MIN_FREE_MEMORY) { \
ZSMMG(memory_exhausted) = 1; \
2013-03-15 07:49:33 +00:00
} \
2013-02-19 14:04:40 +00:00
} while (0)
2013-02-13 12:26:47 +00:00
void *zend_shared_alloc(size_t size)
{
int i;
size_t block_size = ZEND_ALIGNED_SIZE(size);
#if 1
if (!ZCG(locked)) {
ZEND_ASSERT(0 && "Shared memory lock not obtained");
zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Shared memory lock not obtained");
}
#endif
2013-02-13 12:26:47 +00:00
if (block_size > ZSMMG(shared_free)) { /* No hope to find a big-enough block */
SHARED_ALLOC_FAILED();
return NULL;
}
2013-02-22 06:56:05 +00:00
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
2019-04-01 07:27:11 +00:00
if (ZSMMG(shared_segments)[i]->end - ZSMMG(shared_segments)[i]->pos >= block_size) { /* found a valid block */
void *retval = (void *) (((char *) ZSMMG(shared_segments)[i]->p) + ZSMMG(shared_segments)[i]->pos);
2013-02-13 12:26:47 +00:00
ZSMMG(shared_segments)[i]->pos += block_size;
ZSMMG(shared_free) -= block_size;
ZEND_ASSERT(((uintptr_t)retval & 0x7) == 0); /* should be 8 byte aligned */
2013-02-13 12:26:47 +00:00
return retval;
}
}
SHARED_ALLOC_FAILED();
return NULL;
}
static zend_always_inline zend_ulong zend_rotr3(zend_ulong key)
{
return (key >> 3) | (key << ((sizeof(key) * 8) - 3));
}
2013-02-13 12:26:47 +00:00
int zend_shared_memdup_size(void *source, size_t size)
{
2014-03-28 19:34:49 +00:00
void *old_p;
zend_ulong key = (zend_ulong)source;
2013-02-13 12:26:47 +00:00
key = zend_rotr3(key);
if ((old_p = zend_hash_index_find_ptr(&ZCG(xlat_table), key)) != NULL) {
2013-02-13 12:26:47 +00:00
/* we already duplicated this pointer */
return 0;
}
zend_hash_index_add_new_ptr(&ZCG(xlat_table), key, source);
2013-02-13 12:26:47 +00:00
return ZEND_ALIGNED_SIZE(size);
}
static zend_always_inline void *_zend_shared_memdup(void *source, size_t size, bool get_xlat, bool set_xlat, bool free_source)
2013-02-13 12:26:47 +00:00
{
2014-03-28 19:34:49 +00:00
void *old_p, *retval;
zend_ulong key;
if (get_xlat) {
key = (zend_ulong)source;
key = zend_rotr3(key);
if ((old_p = zend_hash_index_find_ptr(&ZCG(xlat_table), key)) != NULL) {
/* we already duplicated this pointer */
return old_p;
}
2013-02-13 12:26:47 +00:00
}
retval = ZCG(mem);
ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
2013-02-13 12:26:47 +00:00
memcpy(retval, source, size);
if (set_xlat) {
if (!get_xlat) {
key = (zend_ulong)source;
key = zend_rotr3(key);
}
zend_hash_index_add_new_ptr(&ZCG(xlat_table), key, retval);
}
2013-02-13 12:26:47 +00:00
if (free_source) {
efree(source);
2013-02-13 12:26:47 +00:00
}
return retval;
}
void *zend_shared_memdup_get_put_free(void *source, size_t size)
{
return _zend_shared_memdup(source, size, true, true, true);
}
void *zend_shared_memdup_put_free(void *source, size_t size)
{
return _zend_shared_memdup(source, size, false, true, true);
}
void *zend_shared_memdup_free(void *source, size_t size)
{
return _zend_shared_memdup(source, size, false, false, true);
}
void *zend_shared_memdup_get_put(void *source, size_t size)
{
return _zend_shared_memdup(source, size, true, true, false);
}
void *zend_shared_memdup_put(void *source, size_t size)
{
return _zend_shared_memdup(source, size, false, true, false);
}
void *zend_shared_memdup(void *source, size_t size)
{
return _zend_shared_memdup(source, size, false, false, false);
}
2014-12-13 22:06:14 +00:00
void zend_shared_alloc_safe_unlock(void)
2013-02-13 12:26:47 +00:00
{
if (ZCG(locked)) {
2014-12-13 22:06:14 +00:00
zend_shared_alloc_unlock();
2013-02-13 12:26:47 +00:00
}
}
2014-12-13 22:06:14 +00:00
void zend_shared_alloc_lock(void)
2013-02-13 12:26:47 +00:00
{
ZEND_ASSERT(!ZCG(locked));
2013-02-13 12:26:47 +00:00
#ifndef ZEND_WIN32
struct flock mem_write_lock;
mem_write_lock.l_type = F_WRLCK;
mem_write_lock.l_whence = SEEK_SET;
mem_write_lock.l_start = 0;
mem_write_lock.l_len = 1;
2013-02-15 11:08:51 +00:00
#ifdef ZTS
tsrm_mutex_lock(zts_lock);
#endif
2013-02-13 12:26:47 +00:00
#if 0
/* this will happen once per process, and will un-globalize mem_write_lock */
if (mem_write_lock.l_pid == -1) {
mem_write_lock.l_pid = getpid();
}
#endif
while (1) {
if (fcntl(lock_file, F_SETLKW, &mem_write_lock) == -1) {
if (errno == EINTR) {
continue;
}
zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Cannot create lock - %s (%d)", strerror(errno), errno);
2013-02-13 12:26:47 +00:00
}
break;
}
#else
zend_shared_alloc_lock_win32();
#endif
ZCG(locked) = 1;
2013-02-13 12:26:47 +00:00
}
2014-12-13 22:06:14 +00:00
void zend_shared_alloc_unlock(void)
2013-02-13 12:26:47 +00:00
{
ZEND_ASSERT(ZCG(locked));
#ifndef ZEND_WIN32
struct flock mem_write_unlock;
mem_write_unlock.l_type = F_UNLCK;
mem_write_unlock.l_whence = SEEK_SET;
mem_write_unlock.l_start = 0;
mem_write_unlock.l_len = 1;
#endif
ZCG(locked) = 0;
2013-02-13 12:26:47 +00:00
#ifndef ZEND_WIN32
if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) {
zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno);
2013-02-13 12:26:47 +00:00
}
2013-02-15 11:08:51 +00:00
#ifdef ZTS
tsrm_mutex_unlock(zts_lock);
#endif
2013-02-13 12:26:47 +00:00
#else
zend_shared_alloc_unlock_win32();
#endif
}
void zend_shared_alloc_init_xlat_table(void)
{
/* Prepare translation table */
zend_hash_init(&ZCG(xlat_table), 128, NULL, NULL, 0);
}
void zend_shared_alloc_destroy_xlat_table(void)
{
/* Destroy translation table */
zend_hash_destroy(&ZCG(xlat_table));
}
2013-02-13 12:26:47 +00:00
void zend_shared_alloc_clear_xlat_table(void)
{
zend_hash_clean(&ZCG(xlat_table));
2013-02-13 12:26:47 +00:00
}
Immutable clases and op_arrays. Squashed commit of the following: commit cd0c36c3f943849e5b97a8dbe2dd029fbeab3df9 Merge: 4740dabb84 ad6738e886 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 14:43:38 2018 +0300 Merge branch 'master' into immutable * master: Remove the "auto" encoding Fixed bug #77025 Add vtbls for EUC-TW encoding commit 4740dabb843c6d4f7f866b4a2456073c9eaf4c77 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 14:12:28 2018 +0300 Reverted back ce->iterator_funcs_ptr. Initialize ce->iterator_funcs_ptr fields in immutable classes. commit ad7a78b253be970db70c2251e66f9297d8e7f829 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:46:30 2018 +0300 Added comment commit 0276ea51875bab37be01a4dc5e5a047c5698c571 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:42:43 2018 +0300 Added type cast commit c63fc5d5f19c58498108d1698055b2b442227eb3 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:36:51 2018 +0300 Moved static class members initialization into the proper place. commit b945548e9306b1826c881918858b5e5aa3eb3002 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:21:03 2018 +0300 Removed redundand assertion commit d5a41088401814c829847db212488f8aae39bcd2 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:19:13 2018 +0300 Removed duplicate code commit 8dadca8864e66de70a24bdf1181bcf7dd8fb27d7 Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 11:05:43 2018 +0300 Hide offset encoding magic in ZEND_MAP_PTR_IS_OFFSET(), ZEND_MAP_PTR_OFFSET2PTR() and ZEND_MAP_PTR_PTR2OFFSET() macros. commit 9ef07c88bd76801e2d4fbfeab3ebfd6e6a67ac5f Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 10:48:29 2018 +0300 typo commit a06f0f3d3aba53e766046221ee44fb9720389ecc Merge: 94099586ec 3412345ffe Author: Dmitry Stogov <dmitry@zend.com> Date: Wed Oct 17 10:47:07 2018 +0300 Merge branch 'master' into immutable * master: Remove unused variable makefile_am_files Classify object handlers are required/optional Add support for getting SKIP_TAGSTART and SKIP_WHITE options Remove some obsolete config_vars.mk occurrences Remove bsd_converted from .gitignore Remove configuration parser and scanners ignores Remove obsolete buildconf.stamp from .gitignore [ci skip] Add magicdata.patch exception to .gitignore Remove outdated ext/spl/examples items from .gitignore Remove unused test.inc in ext/iconv/tests commit 94099586ec599117581ca01c15b1f6c5f749e23a Author: Dmitry Stogov <dmitry@zend.com> Date: Mon Oct 15 23:34:01 2018 +0300 Immutable clases and op_arrays
2018-10-17 12:52:50 +00:00
uint32_t zend_shared_alloc_checkpoint_xlat_table(void)
{
return ZCG(xlat_table).nNumUsed;
}
void zend_shared_alloc_restore_xlat_table(uint32_t checkpoint)
{
zend_hash_discard(&ZCG(xlat_table), checkpoint);
}
void zend_shared_alloc_register_xlat_entry(const void *key_pointer, const void *value)
2013-02-13 12:26:47 +00:00
{
zend_ulong key = (zend_ulong)key_pointer;
key = zend_rotr3(key);
zend_hash_index_add_new_ptr(&ZCG(xlat_table), key, (void*)value);
2013-02-13 12:26:47 +00:00
}
void *zend_shared_alloc_get_xlat_entry(const void *key_pointer)
2013-02-13 12:26:47 +00:00
{
2014-03-28 19:34:49 +00:00
void *retval;
zend_ulong key = (zend_ulong)key_pointer;
2013-02-13 12:26:47 +00:00
key = zend_rotr3(key);
if ((retval = zend_hash_index_find_ptr(&ZCG(xlat_table), key)) == NULL) {
2013-02-13 12:26:47 +00:00
return NULL;
}
2014-03-28 19:34:49 +00:00
return retval;
2013-02-13 12:26:47 +00:00
}
size_t zend_shared_alloc_get_free_memory(void)
{
return ZSMMG(shared_free);
}
void zend_shared_alloc_save_state(void)
{
int i;
2013-02-22 06:56:05 +00:00
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
2013-02-13 12:26:47 +00:00
ZSMMG(shared_memory_state).positions[i] = ZSMMG(shared_segments)[i]->pos;
}
ZSMMG(shared_memory_state).shared_free = ZSMMG(shared_free);
}
void zend_shared_alloc_restore_state(void)
{
int i;
2013-02-22 06:56:05 +00:00
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
2013-02-13 12:26:47 +00:00
ZSMMG(shared_segments)[i]->pos = ZSMMG(shared_memory_state).positions[i];
}
ZSMMG(shared_free) = ZSMMG(shared_memory_state).shared_free;
ZSMMG(memory_exhausted) = 0;
ZSMMG(wasted_shared_memory) = 0;
}
2013-02-25 12:06:38 +00:00
const char *zend_accel_get_shared_model(void)
2013-02-13 12:26:47 +00:00
{
return g_shared_model;
}
void zend_accel_shared_protect(bool protected)
2013-02-13 12:26:47 +00:00
{
#ifdef HAVE_MPROTECT
int i;
if (!smm_shared_globals) {
return;
}
const int mode = protected ? PROT_READ : PROT_READ|PROT_WRITE;
2013-02-13 12:26:47 +00:00
2013-02-22 06:56:05 +00:00
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
2019-04-01 07:27:11 +00:00
mprotect(ZSMMG(shared_segments)[i]->p, ZSMMG(shared_segments)[i]->end, mode);
2013-02-13 12:26:47 +00:00
}
#elif defined(ZEND_WIN32)
int i;
if (!smm_shared_globals) {
return;
}
const int mode = protected ? PAGE_READONLY : PAGE_READWRITE;
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
DWORD oldProtect;
if (!VirtualProtect(ZSMMG(shared_segments)[i]->p, ZSMMG(shared_segments)[i]->end, mode, &oldProtect)) {
zend_accel_error_noreturn(ACCEL_LOG_ERROR, "Failed to protect memory");
}
}
2013-02-13 12:26:47 +00:00
#endif
}
bool zend_accel_in_shm(void *ptr)
{
int i;
2016-02-28 03:50:06 +00:00
if (!smm_shared_globals) {
return false;
2016-02-28 03:50:06 +00:00
}
for (i = 0; i < ZSMMG(shared_segments_count); i++) {
if ((char*)ptr >= (char*)ZSMMG(shared_segments)[i]->p &&
2019-04-01 07:27:11 +00:00
(char*)ptr < (char*)ZSMMG(shared_segments)[i]->p + ZSMMG(shared_segments)[i]->end) {
return true;
}
}
return false;
}