1 /* 2 +----------------------------------------------------------------------+ 3 | Zend OPcache | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1998-2017 The PHP Group | 6 +----------------------------------------------------------------------+ 7 | This source file is subject to version 3.01 of the PHP license, | 8 | that is bundled with this package in the file LICENSE, and is | 9 | available through the world-wide-web at the following url: | 10 | http://www.php.net/license/3_01.txt | 11 | If you did not receive a copy of the PHP license and are unable to | 12 | obtain it through the world-wide-web, please send a note to | 13 | license@php.net so we can mail you a copy immediately. | 14 +----------------------------------------------------------------------+ 15 | Authors: Andi Gutmans <andi@zend.com> | 16 | Zeev Suraski <zeev@zend.com> | 17 | Stanislav Malyshev <stas@zend.com> | 18 | Dmitry Stogov <dmitry@zend.com> | 19 +----------------------------------------------------------------------+ 20 */ 21 22 #ifndef ZEND_ACCELERATOR_H 23 #define ZEND_ACCELERATOR_H 24 25 #ifdef HAVE_CONFIG_H 26 # include <config.h> 27 #endif 28 29 #define ACCELERATOR_PRODUCT_NAME "Zend OPcache" 30 /* 2 - added Profiler support, on 20010712 */ 31 /* 3 - added support for Optimizer's encoded-only-files mode */ 32 /* 4 - works with the new Optimizer, that supports the file format with licenses */ 33 /* 5 - API 4 didn't really work with the license-enabled file format. v5 does. */ 34 /* 6 - Monitor was removed from ZendPlatform.so, to a module of its own */ 35 /* 7 - Optimizer was embedded into Accelerator */ 36 /* 8 - Standalone Open Source Zend OPcache */ 37 #define ACCELERATOR_API_NO 8 38 39 #if ZEND_WIN32 40 # include "zend_config.w32.h" 41 #else 42 #include "zend_config.h" 43 # include <sys/time.h> 44 # include <sys/resource.h> 45 #endif 46 47 #if HAVE_UNISTD_H 48 # include "unistd.h" 49 #endif 50 51 #include "zend_extensions.h" 52 #include "zend_compile.h" 53 54 #include "Optimizer/zend_optimizer.h" 55 #include "zend_accelerator_hash.h" 56 #include "zend_accelerator_debug.h" 57 58 #ifndef PHPAPI 59 # ifdef ZEND_WIN32 60 # define PHPAPI __declspec(dllimport) 61 # else 62 # define PHPAPI 63 # endif 64 #endif 65 66 #ifndef ZEND_EXT_API 67 # if WIN32|WINNT 68 # define ZEND_EXT_API __declspec(dllexport) 69 # elif defined(__GNUC__) && __GNUC__ >= 4 70 # define ZEND_EXT_API __attribute__ ((visibility("default"))) 71 # else 72 # define ZEND_EXT_API 73 # endif 74 #endif 75 76 #ifdef ZEND_WIN32 77 # ifndef MAXPATHLEN 78 # define MAXPATHLEN _MAX_PATH 79 # endif 80 # include <direct.h> 81 #else 82 # ifndef MAXPATHLEN 83 # define MAXPATHLEN 4096 84 # endif 85 # include <sys/param.h> 86 #endif 87 88 #define PHP_5_0_X_API_NO 220040412 89 #define PHP_5_1_X_API_NO 220051025 90 #define PHP_5_2_X_API_NO 220060519 91 #define PHP_5_3_X_API_NO 220090626 92 #define PHP_5_4_X_API_NO 220100525 93 #define PHP_5_5_X_API_NO 220121212 94 #define PHP_5_6_X_API_NO 220131226 95 96 /*** file locking ***/ 97 #ifndef ZEND_WIN32 98 extern int lock_file; 99 100 # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__) 101 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 102 struct flock name = {start, len, -1, type, whence} 103 # elif defined(__svr4__) 104 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 105 struct flock name = {type, whence, start, len} 106 # elif defined(__linux__) || defined(__hpux) || defined(__GNU__) 107 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 108 struct flock name = {type, whence, start, len, 0} 109 # elif defined(_AIX) 110 # if defined(_LARGE_FILES) || defined(__64BIT__) 111 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 112 struct flock name = {type, whence, 0, 0, 0, start, len } 113 # else 114 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 115 struct flock name = {type, whence, start, len} 116 # endif 117 # elif defined(HAVE_FLOCK_BSD) 118 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 119 struct flock name = {start, len, -1, type, whence} 120 # elif defined(HAVE_FLOCK_LINUX) 121 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 122 struct flock name = {type, whence, start, len} 123 # else 124 # error "Don't know how to define struct flock" 125 # endif 126 #endif 127 128 #define PZ_REFCOUNT_P(pz) (pz)->refcount__gc 129 #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount__gc = (v) 130 #define PZ_ADDREF_P(pz) ++((pz)->refcount__gc) 131 #define PZ_DELREF_P(pz) --((pz)->refcount__gc) 132 #define PZ_ISREF_P(pz) (pz)->is_ref__gc 133 #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 134 #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 135 #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref__gc = (isref) 136 137 #define DO_ALLOCA(x) do_alloca(x, use_heap) 138 #define FREE_ALLOCA(x) free_alloca(x, use_heap) 139 140 #if defined(HAVE_OPCACHE_FILE_CACHE) && defined(ZEND_WIN32) 141 # define ENABLE_FILE_CACHE_FALLBACK 1 142 #endif 143 144 #if ZEND_WIN32 145 typedef unsigned __int64 accel_time_t; 146 #else 147 typedef time_t accel_time_t; 148 #endif 149 150 typedef enum _zend_accel_restart_reason { 151 ACCEL_RESTART_OOM, /* restart because of out of memory */ 152 ACCEL_RESTART_HASH, /* restart because of hash overflow */ 153 ACCEL_RESTART_USER /* restart scheduled by opcache_reset() */ 154 } zend_accel_restart_reason; 155 156 typedef struct _zend_persistent_script { 157 zend_string *full_path; /* full real path with resolved symlinks */ 158 zend_op_array main_op_array; 159 HashTable function_table; 160 HashTable class_table; 161 zend_long compiler_halt_offset; /* position of __HALT_COMPILER or -1 */ 162 int ping_auto_globals_mask; /* which autoglobals are used by the script */ 163 accel_time_t timestamp; /* the script modification time */ 164 zend_bool corrupted; 165 zend_bool is_phar; 166 167 void *mem; /* shared memory area used by script structures */ 168 size_t size; /* size of used shared memory */ 169 void *arena_mem; /* part that should be copied into process */ 170 size_t arena_size; 171 172 /* All entries that shouldn't be counted in the ADLER32 173 * checksum must be declared in this struct 174 */ 175 struct zend_persistent_script_dynamic_members { 176 time_t last_used; 177 #ifdef ZEND_WIN32 178 LONGLONG hits; 179 #else 180 zend_ulong hits; 181 #endif 182 unsigned int memory_consumption; 183 unsigned int checksum; 184 time_t revalidate; 185 } dynamic_members; 186 } zend_persistent_script; 187 188 typedef struct _zend_accel_directives { 189 zend_long memory_consumption; 190 zend_long max_accelerated_files; 191 double max_wasted_percentage; 192 char *user_blacklist_filename; 193 zend_long consistency_checks; 194 zend_long force_restart_timeout; 195 zend_bool use_cwd; 196 zend_bool ignore_dups; 197 zend_bool validate_timestamps; 198 zend_bool revalidate_path; 199 zend_bool save_comments; 200 zend_bool fast_shutdown; 201 zend_bool protect_memory; 202 zend_bool file_override_enabled; 203 zend_bool inherited_hack; 204 zend_bool enable_cli; 205 zend_bool validate_permission; 206 #ifndef ZEND_WIN32 207 zend_bool validate_root; 208 #endif 209 zend_ulong revalidate_freq; 210 zend_ulong file_update_protection; 211 char *error_log; 212 #ifdef ZEND_WIN32 213 char *mmap_base; 214 #endif 215 char *memory_model; 216 zend_long log_verbosity_level; 217 218 zend_long optimization_level; 219 zend_long max_file_size; 220 zend_long interned_strings_buffer; 221 char *restrict_api; 222 #ifndef ZEND_WIN32 223 char *lockfile_path; 224 #endif 225 #ifdef HAVE_OPCACHE_FILE_CACHE 226 char *file_cache; 227 zend_bool file_cache_only; 228 zend_bool file_cache_consistency_checks; 229 #endif 230 #if ENABLE_FILE_CACHE_FALLBACK 231 zend_bool file_cache_fallback; 232 #endif 233 #ifdef HAVE_HUGE_CODE_PAGES 234 zend_bool huge_code_pages; 235 #endif 236 } zend_accel_directives; 237 238 typedef struct _zend_accel_globals { 239 /* copy of CG(function_table) used for compilation scripts into cache */ 240 /* initially it contains only internal functions */ 241 HashTable function_table; 242 int internal_functions_count; 243 int counted; /* the process uses shared memory */ 244 zend_bool enabled; 245 zend_bool locked; /* thread obtained exclusive lock */ 246 HashTable bind_hash; /* prototype and zval lookup table */ 247 zend_accel_directives accel_directives; 248 zend_string *cwd; /* current working directory or NULL */ 249 zend_string *include_path; /* current value of "include_path" directive */ 250 char include_path_key[32]; /* key of current "include_path" */ 251 char cwd_key[32]; /* key of current working directory */ 252 int include_path_key_len; 253 int include_path_check; 254 int cwd_key_len; 255 int cwd_check; 256 int auto_globals_mask; 257 time_t request_time; 258 time_t last_restart_time; /* used to synchronize SHM and in-process caches */ 259 char system_id[32]; 260 HashTable xlat_table; 261 #ifndef ZEND_WIN32 262 zend_ulong root_hash; 263 #endif 264 /* preallocated shared-memory block to save current script */ 265 void *mem; 266 void *arena_mem; 267 zend_persistent_script *current_persistent_script; 268 /* cache to save hash lookup on the same INCLUDE opcode */ 269 const zend_op *cache_opline; 270 zend_persistent_script *cache_persistent_script; 271 /* preallocated buffer for keys */ 272 int key_len; 273 char key[MAXPATHLEN * 8]; 274 } zend_accel_globals; 275 276 typedef struct _zend_accel_shared_globals { 277 /* Cache Data Structures */ 278 zend_ulong hits; 279 zend_ulong misses; 280 zend_ulong blacklist_misses; 281 zend_ulong oom_restarts; /* number of restarts because of out of memory */ 282 zend_ulong hash_restarts; /* number of restarts because of hash overflow */ 283 zend_ulong manual_restarts; /* number of restarts scheduled by opcache_reset() */ 284 zend_accel_hash hash; /* hash table for cached scripts */ 285 286 /* Directives & Maintenance */ 287 time_t start_time; 288 time_t last_restart_time; 289 time_t force_restart_time; 290 zend_bool accelerator_enabled; 291 zend_bool restart_pending; 292 zend_accel_restart_reason restart_reason; 293 zend_bool cache_status_before_restart; 294 #ifdef ZEND_WIN32 295 LONGLONG mem_usage; 296 LONGLONG restart_in; 297 #endif 298 zend_bool restart_in_progress; 299 /* Interned Strings Support */ 300 char *interned_strings_start; 301 char *interned_strings_top; 302 char *interned_strings_end; 303 char *interned_strings_saved_top; 304 HashTable interned_strings; 305 } zend_accel_shared_globals; 306 307 extern zend_bool accel_startup_ok; 308 #if ENABLE_FILE_CACHE_FALLBACK 309 extern zend_bool fallback_process; 310 #endif 311 312 extern zend_accel_shared_globals *accel_shared_globals; 313 #define ZCSG(element) (accel_shared_globals->element) 314 315 #ifdef ZTS 316 # define ZCG(v) ZEND_TSRMG(accel_globals_id, zend_accel_globals *, v) 317 extern int accel_globals_id; 318 # ifdef COMPILE_DL_OPCACHE 319 ZEND_TSRMLS_CACHE_EXTERN() 320 # endif 321 #else 322 # define ZCG(v) (accel_globals.v) 323 extern zend_accel_globals accel_globals; 324 #endif 325 326 extern char *zps_api_failure_reason; 327 328 void accel_shutdown(void); 329 int accel_post_deactivate(void); 330 void zend_accel_schedule_restart(zend_accel_restart_reason reason); 331 void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason); 332 accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_t *size); 333 int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle); 334 int validate_timestamp_and_record_ex(zend_persistent_script *persistent_script, zend_file_handle *file_handle); 335 int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force); 336 int zend_accel_script_optimize(zend_persistent_script *persistent_script); 337 int accelerator_shm_read_lock(void); 338 void accelerator_shm_read_unlock(void); 339 340 char *accel_make_persistent_key(const char *path, int path_length, int *key_len); 341 zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type); 342 343 #if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED) 344 # define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145 345 #endif 346 347 #define ZEND_DECLARE_INHERITED_CLASS_DELAYED_FLAG 0x80 348 349 #define IS_ACCEL_INTERNED(str) \ 350 ((char*)(str) >= ZCSG(interned_strings_start) && (char*)(str) < ZCSG(interned_strings_end)) 351 352 zend_string *accel_new_interned_string(zend_string *str); 353 354 # define ZEND_RESULT_TYPE(opline) (opline)->result_type 355 # define ZEND_RESULT(opline) (opline)->result 356 # define ZEND_OP1_TYPE(opline) (opline)->op1_type 357 # define ZEND_OP1(opline) (opline)->op1 358 # define ZEND_OP1_CONST(opline) (*(opline)->op1.zv) 359 # define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant] 360 # define ZEND_OP2_TYPE(opline) (opline)->op2_type 361 # define ZEND_OP2(opline) (opline)->op2 362 # define ZEND_OP2_CONST(opline) (*(opline)->op2.zv) 363 # define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant] 364 # define ZEND_DONE_PASS_TWO(op_array) (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0) 365 # define ZEND_CE_FILENAME(ce) (ce)->info.user.filename 366 # define ZEND_CE_DOC_COMMENT(ce) (ce)->info.user.doc_comment 367 # define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->info.user.doc_comment_len 368 369 #endif /* ZEND_ACCELERATOR_H */ 370