1 /* 2 +----------------------------------------------------------------------+ 3 | Zend OPcache | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1998-2016 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 #define PHP_ZENDOPCACHE_VERSION "7.0.6-dev" 31 #define ACCELERATOR_VERSION PHP_ZENDOPCACHE_VERSION 32 /* 2 - added Profiler support, on 20010712 */ 33 /* 3 - added support for Optimizer's encoded-only-files mode */ 34 /* 4 - works with the new Optimizer, that supports the file format with licenses */ 35 /* 5 - API 4 didn't really work with the license-enabled file format. v5 does. */ 36 /* 6 - Monitor was removed from ZendPlatform.so, to a module of its own */ 37 /* 7 - Optimizer was embedded into Accelerator */ 38 /* 8 - Standalone Open Source Zend OPcache */ 39 #define ACCELERATOR_API_NO 8 40 41 #if ZEND_WIN32 42 # include "zend_config.w32.h" 43 #else 44 #include "zend_config.h" 45 # include <sys/time.h> 46 # include <sys/resource.h> 47 #endif 48 49 #if HAVE_UNISTD_H 50 # include "unistd.h" 51 #endif 52 53 #include "zend_extensions.h" 54 #include "zend_compile.h" 55 56 #include "Optimizer/zend_optimizer.h" 57 #include "zend_accelerator_hash.h" 58 #include "zend_accelerator_debug.h" 59 60 #ifndef PHPAPI 61 # ifdef ZEND_WIN32 62 # define PHPAPI __declspec(dllimport) 63 # else 64 # define PHPAPI 65 # endif 66 #endif 67 68 #ifndef ZEND_EXT_API 69 # if WIN32|WINNT 70 # define ZEND_EXT_API __declspec(dllexport) 71 # elif defined(__GNUC__) && __GNUC__ >= 4 72 # define ZEND_EXT_API __attribute__ ((visibility("default"))) 73 # else 74 # define ZEND_EXT_API 75 # endif 76 #endif 77 78 #ifdef ZEND_WIN32 79 # ifndef MAXPATHLEN 80 # define MAXPATHLEN _MAX_PATH 81 # endif 82 # include <direct.h> 83 #else 84 # ifndef MAXPATHLEN 85 # define MAXPATHLEN 4096 86 # endif 87 # include <sys/param.h> 88 #endif 89 90 #define PHP_5_0_X_API_NO 220040412 91 #define PHP_5_1_X_API_NO 220051025 92 #define PHP_5_2_X_API_NO 220060519 93 #define PHP_5_3_X_API_NO 220090626 94 #define PHP_5_4_X_API_NO 220100525 95 #define PHP_5_5_X_API_NO 220121212 96 #define PHP_5_6_X_API_NO 220131226 97 98 /*** file locking ***/ 99 #ifndef ZEND_WIN32 100 extern int lock_file; 101 102 # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__) 103 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 104 struct flock name = {start, len, -1, type, whence} 105 # elif defined(__svr4__) 106 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 107 struct flock name = {type, whence, start, len} 108 # elif defined(__linux__) || defined(__hpux) || defined(__GNU__) 109 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 110 struct flock name = {type, whence, start, len, 0} 111 # elif defined(_AIX) 112 # if defined(_LARGE_FILES) || defined(__64BIT__) 113 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 114 struct flock name = {type, whence, 0, 0, 0, start, len } 115 # else 116 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 117 struct flock name = {type, whence, start, len} 118 # endif 119 # elif defined(HAVE_FLOCK_BSD) 120 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 121 struct flock name = {start, len, -1, type, whence} 122 # elif defined(HAVE_FLOCK_LINUX) 123 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 124 struct flock name = {type, whence, start, len} 125 # else 126 # error "Don't know how to define struct flock" 127 # endif 128 #endif 129 130 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO 131 #define Z_REFCOUNT_P(pz) (pz)->refcount 132 #define Z_SET_REFCOUNT_P(pz, v) (pz)->refcount = (v) 133 #define Z_ADDREF_P(pz) ++((pz)->refcount) 134 #define Z_DELREF_P(pz) --((pz)->refcount) 135 #define Z_ISREF_P(pz) (pz)->is_ref 136 #define Z_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 137 #define Z_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 138 #define Z_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = (isref) 139 #define PZ_REFCOUNT_P(pz) (pz)->refcount 140 #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount = (v) 141 #define PZ_ADDREF_P(pz) ++((pz)->refcount) 142 #define PZ_DELREF_P(pz) --((pz)->refcount) 143 #define PZ_ISREF_P(pz) (pz)->is_ref 144 #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 145 #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 146 #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = (isref) 147 #else 148 #define PZ_REFCOUNT_P(pz) (pz)->refcount__gc 149 #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount__gc = (v) 150 #define PZ_ADDREF_P(pz) ++((pz)->refcount__gc) 151 #define PZ_DELREF_P(pz) --((pz)->refcount__gc) 152 #define PZ_ISREF_P(pz) (pz)->is_ref__gc 153 #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 154 #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 155 #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref__gc = (isref) 156 #endif 157 158 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO 159 # ifdef ALLOCA_FLAG 160 #define DO_ALLOCA(x) do_alloca_with_limit(x, use_heap) 161 #define FREE_ALLOCA(x) free_alloca_with_limit(x, use_heap) 162 # else 163 #define ALLOCA_FLAG(x) 164 #define DO_ALLOCA(x) do_alloca(x) 165 #define FREE_ALLOCA(x) free_alloca(x) 166 # endif 167 #else 168 #define DO_ALLOCA(x) do_alloca(x, use_heap) 169 #define FREE_ALLOCA(x) free_alloca(x, use_heap) 170 #endif 171 172 173 #if ZEND_WIN32 174 typedef unsigned __int64 accel_time_t; 175 #else 176 typedef time_t accel_time_t; 177 #endif 178 179 typedef enum _zend_accel_restart_reason { 180 ACCEL_RESTART_OOM, /* restart because of out of memory */ 181 ACCEL_RESTART_HASH, /* restart because of hash overflow */ 182 ACCEL_RESTART_USER /* restart scheduled by opcache_reset() */ 183 } zend_accel_restart_reason; 184 185 typedef struct _zend_persistent_script { 186 ulong hash_value; 187 char *full_path; /* full real path with resolved symlinks */ 188 unsigned int full_path_len; 189 zend_op_array main_op_array; 190 HashTable function_table; 191 HashTable class_table; 192 long compiler_halt_offset; /* position of __HALT_COMPILER or -1 */ 193 int ping_auto_globals_mask; /* which autoglobals are used by the script */ 194 accel_time_t timestamp; /* the script modification time */ 195 zend_bool corrupted; 196 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO 197 zend_uint early_binding; /* the linked list of delayed declarations */ 198 #endif 199 200 void *mem; /* shared memory area used by script structures */ 201 size_t size; /* size of used shared memory */ 202 203 /* All entries that shouldn't be counted in the ADLER32 204 * checksum must be declared in this struct 205 */ 206 struct zend_persistent_script_dynamic_members { 207 time_t last_used; 208 ulong hits; 209 unsigned int memory_consumption; 210 unsigned int checksum; 211 time_t revalidate; 212 } dynamic_members; 213 } zend_persistent_script; 214 215 typedef struct _zend_accel_directives { 216 long memory_consumption; 217 long max_accelerated_files; 218 double max_wasted_percentage; 219 char *user_blacklist_filename; 220 long consistency_checks; 221 long force_restart_timeout; 222 zend_bool use_cwd; 223 zend_bool ignore_dups; 224 zend_bool validate_timestamps; 225 zend_bool revalidate_path; 226 zend_bool save_comments; 227 zend_bool load_comments; 228 zend_bool fast_shutdown; 229 zend_bool protect_memory; 230 zend_bool file_override_enabled; 231 zend_bool inherited_hack; 232 zend_bool enable_cli; 233 zend_bool validate_permission; 234 #ifndef ZEND_WIN32 235 zend_bool validate_root; 236 #endif 237 unsigned long revalidate_freq; 238 unsigned long file_update_protection; 239 char *error_log; 240 #ifdef ZEND_WIN32 241 char *mmap_base; 242 #endif 243 char *memory_model; 244 long log_verbosity_level; 245 246 long optimization_level; 247 long max_file_size; 248 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO 249 long interned_strings_buffer; 250 #endif 251 char *restrict_api; 252 } zend_accel_directives; 253 254 typedef struct _zend_accel_globals { 255 /* copy of CG(function_table) used for compilation scripts into cache */ 256 /* initially it contains only internal functions */ 257 HashTable function_table; 258 int internal_functions_count; 259 int counted; /* the process uses shared memory */ 260 zend_bool enabled; 261 zend_bool locked; /* thread obtained exclusive lock */ 262 HashTable bind_hash; /* prototype and zval lookup table */ 263 zend_accel_directives accel_directives; 264 char *cwd; /* current working directory or NULL */ 265 int cwd_len; /* "cwd" string length */ 266 char *include_path_key; /* one letter key of current "include_path" */ 267 char *include_path; /* current section of "include_path" directive */ 268 int include_path_len; /* "include_path" string length */ 269 int include_path_check; 270 time_t request_time; 271 #ifndef ZEND_WIN32 272 unsigned long root_hash; 273 #endif 274 /* preallocated shared-memory block to save current script */ 275 void *mem; 276 /* cache to save hash lookup on the same INCLUDE opcode */ 277 zend_op *cache_opline; 278 zend_persistent_script *cache_persistent_script; 279 /* preallocated buffer for keys */ 280 int key_len; 281 char key[MAXPATHLEN * 8]; 282 } zend_accel_globals; 283 284 typedef struct _zend_accel_shared_globals { 285 /* Cache Data Structures */ 286 unsigned long hits; 287 unsigned long misses; 288 unsigned long blacklist_misses; 289 unsigned long oom_restarts; /* number of restarts because of out of memory */ 290 unsigned long hash_restarts; /* number of restarts because of hash overflow */ 291 unsigned long manual_restarts; /* number of restarts scheduled by opcache_reset() */ 292 zend_accel_hash hash; /* hash table for cached scripts */ 293 zend_accel_hash include_paths; /* used "include_path" values */ 294 295 /* Directives & Maintenance */ 296 time_t start_time; 297 time_t last_restart_time; 298 time_t force_restart_time; 299 zend_bool accelerator_enabled; 300 zend_bool restart_pending; 301 zend_accel_restart_reason restart_reason; 302 zend_bool cache_status_before_restart; 303 #ifdef ZEND_WIN32 304 unsigned long mem_usage; 305 unsigned long restart_in; 306 #endif 307 zend_bool restart_in_progress; 308 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO 309 /* Interned Strings Support */ 310 char *interned_strings_start; 311 char *interned_strings_top; 312 char *interned_strings_end; 313 HashTable interned_strings; 314 struct { 315 Bucket **arBuckets; 316 Bucket *pListHead; 317 Bucket *pListTail; 318 char *top; 319 } interned_strings_saved_state; 320 #endif 321 } zend_accel_shared_globals; 322 323 extern zend_bool accel_startup_ok; 324 325 extern zend_accel_shared_globals *accel_shared_globals; 326 #define ZCSG(element) (accel_shared_globals->element) 327 328 #ifdef ZTS 329 # define ZCG(v) TSRMG(accel_globals_id, zend_accel_globals *, v) 330 extern int accel_globals_id; 331 #else 332 # define ZCG(v) (accel_globals.v) 333 extern zend_accel_globals accel_globals; 334 #endif 335 336 extern char *zps_api_failure_reason; 337 338 void accel_shutdown(TSRMLS_D); 339 void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC); 340 void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC); 341 int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC); 342 int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC); 343 int zend_accel_script_optimize(zend_persistent_script *persistent_script TSRMLS_DC); 344 int accelerator_shm_read_lock(TSRMLS_D); 345 void accelerator_shm_read_unlock(TSRMLS_D); 346 347 char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC); 348 zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); 349 350 #if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED) 351 # define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145 352 #endif 353 354 #define ZEND_DECLARE_INHERITED_CLASS_DELAYED_FLAG 0x80 355 356 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO 357 358 const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC); 359 360 # define interned_free(s) do { \ 361 if (!IS_INTERNED(s)) { \ 362 free(s); \ 363 } \ 364 } while (0) 365 # define interned_efree(s) do { \ 366 if (!IS_INTERNED(s)) { \ 367 efree(s); \ 368 } \ 369 } while (0) 370 # define interned_estrndup(s, n) \ 371 (IS_INTERNED(s) ? (s) : estrndup(s, n)) 372 # define ZEND_RESULT_TYPE(opline) (opline)->result_type 373 # define ZEND_RESULT(opline) (opline)->result 374 # define ZEND_OP1_TYPE(opline) (opline)->op1_type 375 # define ZEND_OP1(opline) (opline)->op1 376 # define ZEND_OP1_CONST(opline) (*(opline)->op1.zv) 377 # define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant].constant 378 # define ZEND_OP2_TYPE(opline) (opline)->op2_type 379 # define ZEND_OP2(opline) (opline)->op2 380 # define ZEND_OP2_CONST(opline) (*(opline)->op2.zv) 381 # define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant].constant 382 # define ZEND_DONE_PASS_TWO(op_array) (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0) 383 # define ZEND_CE_FILENAME(ce) (ce)->info.user.filename 384 # define ZEND_CE_DOC_COMMENT(ce) (ce)->info.user.doc_comment 385 # define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->info.user.doc_comment_len 386 #else 387 # define IS_INTERNED(s) 0 388 # define interned_free(s) free(s) 389 # define interned_efree(s) efree(s) 390 # define interned_estrndup(s, n) estrndup(s, n) 391 # define ZEND_RESULT_TYPE(opline) (opline)->result.op_type 392 # define ZEND_RESULT(opline) (opline)->result.u 393 # define ZEND_OP1_TYPE(opline) (opline)->op1.op_type 394 # define ZEND_OP1(opline) (opline)->op1.u 395 # define ZEND_OP1_CONST(opline) (opline)->op1.u.constant 396 # define ZEND_OP1_LITERAL(opline) (opline)->op1.u.constant 397 # define ZEND_OP2_TYPE(opline) (opline)->op2.op_type 398 # define ZEND_OP2(opline) (opline)->op2.u 399 # define ZEND_OP2_CONST(opline) (opline)->op2.u.constant 400 # define ZEND_OP2_LITERAL(opline) (opline)->op2.u.constant 401 # define ZEND_DONE_PASS_TWO(op_array) ((op_array)->done_pass_two != 0) 402 # define ZEND_CE_FILENAME(ce) (ce)->filename 403 # define ZEND_CE_DOC_COMMENT(ce) (ce)->doc_comment 404 # define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->doc_comment_len 405 #endif 406 407 #endif /* ZEND_ACCELERATOR_H */ 408