root/ext/opcache/ZendAccelerator.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


/*
   +----------------------------------------------------------------------+
   | Zend OPcache                                                         |
   +----------------------------------------------------------------------+
   | Copyright (c) 1998-2015 The PHP Group                                |
   +----------------------------------------------------------------------+
   | 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:           |
   | http://www.php.net/license/3_01.txt                                  |
   | 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.               |
   +----------------------------------------------------------------------+
   | Authors: Andi Gutmans <andi@zend.com>                                |
   |          Zeev Suraski <zeev@zend.com>                                |
   |          Stanislav Malyshev <stas@zend.com>                          |
   |          Dmitry Stogov <dmitry@zend.com>                             |
   +----------------------------------------------------------------------+
*/

#ifndef ZEND_ACCELERATOR_H
#define ZEND_ACCELERATOR_H

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#define ACCELERATOR_PRODUCT_NAME        "Zend OPcache"
#define PHP_ZENDOPCACHE_VERSION "7.0.6-dev"
#define ACCELERATOR_VERSION PHP_ZENDOPCACHE_VERSION
/* 2 - added Profiler support, on 20010712 */
/* 3 - added support for Optimizer's encoded-only-files mode */
/* 4 - works with the new Optimizer, that supports the file format with licenses */
/* 5 - API 4 didn't really work with the license-enabled file format.  v5 does. */
/* 6 - Monitor was removed from ZendPlatform.so, to a module of its own */
/* 7 - Optimizer was embedded into Accelerator */
/* 8 - Standalone Open Source Zend OPcache */
#define ACCELERATOR_API_NO 8

#if ZEND_WIN32
# include "zend_config.w32.h"
#else
#include "zend_config.h"
# include <sys/time.h>
# include <sys/resource.h>
#endif

#if HAVE_UNISTD_H
# include "unistd.h"
#endif

#include "zend_extensions.h"
#include "zend_compile.h"

#include "Optimizer/zend_optimizer.h"
#include "zend_accelerator_hash.h"
#include "zend_accelerator_debug.h"

#ifndef PHPAPI
# ifdef ZEND_WIN32
#  define PHPAPI __declspec(dllimport)
# else
#  define PHPAPI
# endif
#endif

#ifndef ZEND_EXT_API
# if WIN32|WINNT
#  define ZEND_EXT_API __declspec(dllexport)
# elif defined(__GNUC__) && __GNUC__ >= 4
#  define ZEND_EXT_API __attribute__ ((visibility("default")))
# else
#  define ZEND_EXT_API
# endif
#endif

#ifdef ZEND_WIN32
# ifndef MAXPATHLEN
#  define MAXPATHLEN     _MAX_PATH
# endif
# include <direct.h>
#else
# ifndef MAXPATHLEN
#  define MAXPATHLEN     4096
# endif
# include <sys/param.h>
#endif

#define PHP_5_0_X_API_NO                220040412
#define PHP_5_1_X_API_NO                220051025
#define PHP_5_2_X_API_NO                220060519
#define PHP_5_3_X_API_NO                220090626
#define PHP_5_4_X_API_NO                220100525
#define PHP_5_5_X_API_NO                220121212
#define PHP_5_6_X_API_NO                220131226

/*** file locking ***/
#ifndef ZEND_WIN32
extern int lock_file;

# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__)
#  define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {start, len, -1, type, whence}
# elif defined(__svr4__)
#  define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {type, whence, start, len}
# elif defined(__linux__) || defined(__hpux) || defined(__GNU__)
#  define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {type, whence, start, len, 0}
# elif defined(_AIX)
#  if defined(_LARGE_FILES) || defined(__64BIT__)
#   define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {type, whence, 0, 0, 0, start, len }
#  else
#   define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {type, whence, start, len}
#  endif
# elif defined(HAVE_FLOCK_BSD)
#  define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {start, len, -1, type, whence}
# elif defined(HAVE_FLOCK_LINUX)
#  define FLOCK_STRUCTURE(name, type, whence, start, len) \
                struct flock name = {type, whence, start, len}
# else
#  error "Don't know how to define struct flock"
# endif
#endif

#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
        #define Z_REFCOUNT_P(pz)                                (pz)->refcount
        #define Z_SET_REFCOUNT_P(pz, v)                 (pz)->refcount = (v)
        #define Z_ADDREF_P(pz)                                  ++((pz)->refcount)
        #define Z_DELREF_P(pz)                                  --((pz)->refcount)
        #define Z_ISREF_P(pz)                                   (pz)->is_ref
        #define Z_SET_ISREF_P(pz)                               Z_SET_ISREF_TO_P(pz, 1)
        #define Z_UNSET_ISREF_P(pz)                             Z_SET_ISREF_TO_P(pz, 0)
        #define Z_SET_ISREF_TO_P(pz, isref)             (pz)->is_ref = (isref)
        #define PZ_REFCOUNT_P(pz)                               (pz)->refcount
        #define PZ_SET_REFCOUNT_P(pz, v)                (pz)->refcount = (v)
        #define PZ_ADDREF_P(pz)                                 ++((pz)->refcount)
        #define PZ_DELREF_P(pz)                                 --((pz)->refcount)
        #define PZ_ISREF_P(pz)                                  (pz)->is_ref
        #define PZ_SET_ISREF_P(pz)                              Z_SET_ISREF_TO_P(pz, 1)
        #define PZ_UNSET_ISREF_P(pz)                    Z_SET_ISREF_TO_P(pz, 0)
        #define PZ_SET_ISREF_TO_P(pz, isref)    (pz)->is_ref = (isref)
#else
        #define PZ_REFCOUNT_P(pz)                               (pz)->refcount__gc
        #define PZ_SET_REFCOUNT_P(pz, v)                (pz)->refcount__gc = (v)
        #define PZ_ADDREF_P(pz)                                 ++((pz)->refcount__gc)
        #define PZ_DELREF_P(pz)                                 --((pz)->refcount__gc)
        #define PZ_ISREF_P(pz)                                  (pz)->is_ref__gc
        #define PZ_SET_ISREF_P(pz)                              Z_SET_ISREF_TO_P(pz, 1)
        #define PZ_UNSET_ISREF_P(pz)                    Z_SET_ISREF_TO_P(pz, 0)
        #define PZ_SET_ISREF_TO_P(pz, isref)    (pz)->is_ref__gc = (isref)
#endif

#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
# ifdef ALLOCA_FLAG
        #define DO_ALLOCA(x)    do_alloca_with_limit(x, use_heap)
        #define FREE_ALLOCA(x)  free_alloca_with_limit(x, use_heap)
# else
        #define ALLOCA_FLAG(x)
        #define DO_ALLOCA(x)    do_alloca(x)
        #define FREE_ALLOCA(x)  free_alloca(x)
# endif
#else
        #define DO_ALLOCA(x)    do_alloca(x, use_heap)
        #define FREE_ALLOCA(x)  free_alloca(x, use_heap)
#endif


#if ZEND_WIN32
typedef unsigned __int64 accel_time_t;
#else
typedef time_t accel_time_t;
#endif

typedef enum _zend_accel_restart_reason {
        ACCEL_RESTART_OOM,    /* restart because of out of memory */
        ACCEL_RESTART_HASH,   /* restart because of hash overflow */
        ACCEL_RESTART_USER    /* restart scheduled by opcache_reset() */
} zend_accel_restart_reason;

typedef struct _zend_persistent_script {
        ulong          hash_value;
        char          *full_path;              /* full real path with resolved symlinks */
        unsigned int   full_path_len;
        zend_op_array  main_op_array;
        HashTable      function_table;
        HashTable      class_table;
        long           compiler_halt_offset;   /* position of __HALT_COMPILER or -1 */
        int            ping_auto_globals_mask; /* which autoglobals are used by the script */
        accel_time_t   timestamp;              /* the script modification time */
        zend_bool      corrupted;
#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
        zend_uint      early_binding;          /* the linked list of delayed declarations */
#endif

        void          *mem;                    /* shared memory area used by script structures */
        size_t         size;                   /* size of used shared memory */

        /* All entries that shouldn't be counted in the ADLER32
         * checksum must be declared in this struct
         */
        struct zend_persistent_script_dynamic_members {
                time_t       last_used;
                ulong        hits;
                unsigned int memory_consumption;
                unsigned int checksum;
                time_t       revalidate;
        } dynamic_members;
} zend_persistent_script;

typedef struct _zend_accel_directives {
        long           memory_consumption;
        long           max_accelerated_files;
        double         max_wasted_percentage;
        char          *user_blacklist_filename;
        long           consistency_checks;
        long           force_restart_timeout;
        zend_bool      use_cwd;
        zend_bool      ignore_dups;
        zend_bool      validate_timestamps;
        zend_bool      revalidate_path;
        zend_bool      save_comments;
        zend_bool      load_comments;
        zend_bool      fast_shutdown;
        zend_bool      protect_memory;
        zend_bool      file_override_enabled;
        zend_bool      inherited_hack;
        zend_bool      enable_cli;
        unsigned long  revalidate_freq;
        unsigned long  file_update_protection;
        char          *error_log;
#ifdef ZEND_WIN32
        char          *mmap_base;
#endif
        char          *memory_model;
        long           log_verbosity_level;

        long           optimization_level;
        long           max_file_size;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
        long           interned_strings_buffer;
#endif
        char          *restrict_api;
} zend_accel_directives;

typedef struct _zend_accel_globals {
    /* copy of CG(function_table) used for compilation scripts into cache */
    /* initially it contains only internal functions */
        HashTable               function_table;
        int                     internal_functions_count;
        int                     counted;   /* the process uses shared memory */
        zend_bool               enabled;
        zend_bool               locked;    /* thread obtained exclusive lock */
        HashTable               bind_hash; /* prototype and zval lookup table */
        zend_accel_directives   accel_directives;
        char                   *cwd;              /* current working directory or NULL */
        int                     cwd_len;          /* "cwd" string length */
        char                   *include_path_key; /* one letter key of current "include_path" */
        char                   *include_path;     /* current section of "include_path" directive */
        int                     include_path_len; /* "include_path" string length */
        int                     include_path_check;
        time_t                  request_time;
        /* preallocated shared-memory block to save current script */
        void                   *mem;
        /* cache to save hash lookup on the same INCLUDE opcode */
        zend_op                *cache_opline;
        zend_persistent_script *cache_persistent_script;
        /* preallocated buffer for keys */
        int                     key_len;
        char                    key[MAXPATHLEN * 8];
} zend_accel_globals;

typedef struct _zend_accel_shared_globals {
        /* Cache Data Structures */
        unsigned long   hits;
        unsigned long   misses;
        unsigned long   blacklist_misses;
        unsigned long   oom_restarts;     /* number of restarts because of out of memory */
        unsigned long   hash_restarts;    /* number of restarts because of hash overflow */
        unsigned long   manual_restarts;  /* number of restarts scheduled by opcache_reset() */
        zend_accel_hash hash;             /* hash table for cached scripts */
        zend_accel_hash include_paths;    /* used "include_path" values    */

        /* Directives & Maintenance */
        time_t          start_time;
        time_t          last_restart_time;
        time_t          force_restart_time;
        zend_bool       accelerator_enabled;
        zend_bool       restart_pending;
        zend_accel_restart_reason restart_reason;
        zend_bool       cache_status_before_restart;
#ifdef ZEND_WIN32
    unsigned long   mem_usage;
    unsigned long   restart_in;
#endif
        zend_bool       restart_in_progress;
#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
        /* Interned Strings Support */
        char           *interned_strings_start;
        char           *interned_strings_top;
        char           *interned_strings_end;
        HashTable       interned_strings;
        struct {
                Bucket **arBuckets;
                Bucket  *pListHead;
                Bucket  *pListTail;
                char    *top;
        } interned_strings_saved_state;
#endif
} zend_accel_shared_globals;

extern zend_bool accel_startup_ok;

extern zend_accel_shared_globals *accel_shared_globals;
#define ZCSG(element)   (accel_shared_globals->element)

#ifdef ZTS
# define ZCG(v) TSRMG(accel_globals_id, zend_accel_globals *, v)
extern int accel_globals_id;
#else
# define ZCG(v) (accel_globals.v)
extern zend_accel_globals accel_globals;
#endif

extern char *zps_api_failure_reason;

void accel_shutdown(TSRMLS_D);
void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC);
void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC);
int  validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC);
int  zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC);
int  zend_accel_script_optimize(zend_persistent_script *persistent_script TSRMLS_DC);
int  accelerator_shm_read_lock(TSRMLS_D);
void accelerator_shm_read_unlock(TSRMLS_D);

char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC);
zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);

#if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED)
# define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145
#endif

#define ZEND_DECLARE_INHERITED_CLASS_DELAYED_FLAG 0x80

#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO

const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC);

# define interned_free(s) do { \
                if (!IS_INTERNED(s)) { \
                        free(s); \
                } \
        } while (0)
# define interned_efree(s) do { \
                if (!IS_INTERNED(s)) { \
                        efree(s); \
                } \
        } while (0)
# define interned_estrndup(s, n) \
        (IS_INTERNED(s) ? (s) : estrndup(s, n))
# define ZEND_RESULT_TYPE(opline)       (opline)->result_type
# define ZEND_RESULT(opline)            (opline)->result
# define ZEND_OP1_TYPE(opline)          (opline)->op1_type
# define ZEND_OP1(opline)                       (opline)->op1
# define ZEND_OP1_CONST(opline)         (*(opline)->op1.zv)
# define ZEND_OP1_LITERAL(opline)       (op_array)->literals[(opline)->op1.constant].constant
# define ZEND_OP2_TYPE(opline)          (opline)->op2_type
# define ZEND_OP2(opline)                       (opline)->op2
# define ZEND_OP2_CONST(opline)         (*(opline)->op2.zv)
# define ZEND_OP2_LITERAL(opline)       (op_array)->literals[(opline)->op2.constant].constant
# define ZEND_DONE_PASS_TWO(op_array)   (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0)
# define ZEND_CE_FILENAME(ce)                   (ce)->info.user.filename
# define ZEND_CE_DOC_COMMENT(ce)        (ce)->info.user.doc_comment
# define ZEND_CE_DOC_COMMENT_LEN(ce)    (ce)->info.user.doc_comment_len
#else
# define IS_INTERNED(s)                         0
# define interned_free(s)                       free(s)
# define interned_efree(s)                      efree(s)
# define interned_estrndup(s, n)        estrndup(s, n)
# define ZEND_RESULT_TYPE(opline)       (opline)->result.op_type
# define ZEND_RESULT(opline)            (opline)->result.u
# define ZEND_OP1_TYPE(opline)          (opline)->op1.op_type
# define ZEND_OP1(opline)                       (opline)->op1.u
# define ZEND_OP1_CONST(opline)         (opline)->op1.u.constant
# define ZEND_OP1_LITERAL(opline)       (opline)->op1.u.constant
# define ZEND_OP2_TYPE(opline)          (opline)->op2.op_type
# define ZEND_OP2(opline)                       (opline)->op2.u
# define ZEND_OP2_CONST(opline)         (opline)->op2.u.constant
# define ZEND_OP2_LITERAL(opline)       (opline)->op2.u.constant
# define ZEND_DONE_PASS_TWO(op_array)   ((op_array)->done_pass_two != 0)
# define ZEND_CE_FILENAME(ce)                   (ce)->filename
# define ZEND_CE_DOC_COMMENT(ce)        (ce)->doc_comment
# define ZEND_CE_DOC_COMMENT_LEN(ce)    (ce)->doc_comment_len
#endif

#endif /* ZEND_ACCELERATOR_H */

/* [<][>][^][v][top][bottom][index][help] */