1 /* 2 +----------------------------------------------------------------------+ 3 | Zend OPcache | 4 +----------------------------------------------------------------------+ 5 | Copyright (c) 1998-2015 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 97 /*** file locking ***/ 98 #ifndef ZEND_WIN32 99 extern int lock_file; 100 101 # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__) 102 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 103 struct flock name = {start, len, -1, type, whence} 104 # elif defined(__svr4__) 105 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 106 struct flock name = {type, whence, start, len} 107 # elif defined(__linux__) || defined(__hpux) || defined(__GNU__) 108 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 109 struct flock name = {type, whence, start, len, 0} 110 # elif defined(_AIX) 111 # if defined(_LARGE_FILES) || defined(__64BIT__) 112 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 113 struct flock name = {type, whence, 0, 0, 0, start, len } 114 # else 115 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 116 struct flock name = {type, whence, start, len} 117 # endif 118 # elif defined(HAVE_FLOCK_BSD) 119 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 120 struct flock name = {start, len, -1, type, whence} 121 # elif defined(HAVE_FLOCK_LINUX) 122 # define FLOCK_STRUCTURE(name, type, whence, start, len) \ 123 struct flock name = {type, whence, start, len} 124 # else 125 # error "Don't know how to define struct flock" 126 # endif 127 #endif 128 129 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO 130 #define Z_REFCOUNT_P(pz) (pz)->refcount 131 #define Z_SET_REFCOUNT_P(pz, v) (pz)->refcount = (v) 132 #define Z_ADDREF_P(pz) ++((pz)->refcount) 133 #define Z_DELREF_P(pz) --((pz)->refcount) 134 #define Z_ISREF_P(pz) (pz)->is_ref 135 #define Z_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 136 #define Z_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 137 #define Z_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = (isref) 138 #define PZ_REFCOUNT_P(pz) (pz)->refcount 139 #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount = (v) 140 #define PZ_ADDREF_P(pz) ++((pz)->refcount) 141 #define PZ_DELREF_P(pz) --((pz)->refcount) 142 #define PZ_ISREF_P(pz) (pz)->is_ref 143 #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 144 #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 145 #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = (isref) 146 #else 147 #define PZ_REFCOUNT_P(pz) (pz)->refcount__gc 148 #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount__gc = (v) 149 #define PZ_ADDREF_P(pz) ++((pz)->refcount__gc) 150 #define PZ_DELREF_P(pz) --((pz)->refcount__gc) 151 #define PZ_ISREF_P(pz) (pz)->is_ref__gc 152 #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1) 153 #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0) 154 #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref__gc = (isref) 155 #endif 156 157 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO 158 # ifdef ALLOCA_FLAG 159 #define DO_ALLOCA(x) do_alloca_with_limit(x, use_heap) 160 #define FREE_ALLOCA(x) free_alloca_with_limit(x, use_heap) 161 # else 162 #define ALLOCA_FLAG(x) 163 #define DO_ALLOCA(x) do_alloca(x) 164 #define FREE_ALLOCA(x) free_alloca(x) 165 # endif 166 #else 167 #define DO_ALLOCA(x) do_alloca(x, use_heap) 168 #define FREE_ALLOCA(x) free_alloca(x, use_heap) 169 #endif 170 171 172 #if ZEND_WIN32 173 typedef unsigned __int64 accel_time_t; 174 #else 175 typedef time_t accel_time_t; 176 #endif 177 178 typedef enum _zend_accel_restart_reason { 179 ACCEL_RESTART_OOM, /* restart because of out of memory */ 180 ACCEL_RESTART_HASH, /* restart because of hash overflow */ 181 ACCEL_RESTART_USER /* restart scheduled by opcache_reset() */ 182 } zend_accel_restart_reason; 183 184 typedef struct _zend_persistent_script { 185 ulong hash_value; 186 char *full_path; /* full real path with resolved symlinks */ 187 unsigned int full_path_len; 188 zend_op_array main_op_array; 189 HashTable function_table; 190 HashTable class_table; 191 long compiler_halt_offset; /* position of __HALT_COMPILER or -1 */ 192 int ping_auto_globals_mask; /* which autoglobals are used by the script */ 193 accel_time_t timestamp; /* the script modification time */ 194 zend_bool corrupted; 195 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO 196 zend_uint early_binding; /* the linked list of delayed declarations */ 197 #endif 198 199 void *mem; /* shared memory area used by script structures */ 200 size_t size; /* size of used shared memory */ 201 202 /* All entries that shouldn't be counted in the ADLER32 203 * checksum must be declared in this struct 204 */ 205 struct zend_persistent_script_dynamic_members { 206 time_t last_used; 207 ulong hits; 208 unsigned int memory_consumption; 209 unsigned int checksum; 210 time_t revalidate; 211 } dynamic_members; 212 } zend_persistent_script; 213 214 typedef struct _zend_accel_directives { 215 long memory_consumption; 216 long max_accelerated_files; 217 double max_wasted_percentage; 218 char *user_blacklist_filename; 219 long consistency_checks; 220 long force_restart_timeout; 221 zend_bool use_cwd; 222 zend_bool ignore_dups; 223 zend_bool validate_timestamps; 224 zend_bool revalidate_path; 225 zend_bool save_comments; 226 zend_bool load_comments; 227 zend_bool fast_shutdown; 228 zend_bool protect_memory; 229 zend_bool file_override_enabled; 230 zend_bool inherited_hack; 231 zend_bool enable_cli; 232 unsigned long revalidate_freq; 233 unsigned long file_update_protection; 234 char *error_log; 235 #ifdef ZEND_WIN32 236 char *mmap_base; 237 #endif 238 char *memory_model; 239 long log_verbosity_level; 240 241 long optimization_level; 242 long max_file_size; 243 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO 244 long interned_strings_buffer; 245 #endif 246 char *restrict_api; 247 } zend_accel_directives; 248 249 typedef struct _zend_accel_globals { 250 /* copy of CG(function_table) used for compilation scripts into cache */ 251 /* initially it contains only internal functions */ 252 HashTable function_table; 253 int internal_functions_count; 254 int counted; /* the process uses shared memory */ 255 zend_bool enabled; 256 zend_bool locked; /* thread obtained exclusive lock */ 257 HashTable bind_hash; /* prototype and zval lookup table */ 258 zend_accel_directives accel_directives; 259 char *cwd; /* current working directory or NULL */ 260 int cwd_len; /* "cwd" string length */ 261 char *include_path_key; /* one letter key of current "include_path" */ 262 char *include_path; /* current section of "include_path" directive */ 263 int include_path_len; /* "include_path" string length */ 264 int include_path_check; 265 time_t request_time; 266 /* preallocated shared-memory block to save current script */ 267 void *mem; 268 /* cache to save hash lookup on the same INCLUDE opcode */ 269 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 unsigned long hits; 279 unsigned long misses; 280 unsigned long blacklist_misses; 281 unsigned long oom_restarts; /* number of restarts because of out of memory */ 282 unsigned long hash_restarts; /* number of restarts because of hash overflow */ 283 unsigned long manual_restarts; /* number of restarts scheduled by opcache_reset() */ 284 zend_accel_hash hash; /* hash table for cached scripts */ 285 zend_accel_hash include_paths; /* used "include_path" values */ 286 287 /* Directives & Maintenance */ 288 time_t start_time; 289 time_t last_restart_time; 290 time_t force_restart_time; 291 zend_bool accelerator_enabled; 292 zend_bool restart_pending; 293 zend_accel_restart_reason restart_reason; 294 zend_bool cache_status_before_restart; 295 #ifdef ZEND_WIN32 296 unsigned long mem_usage; 297 unsigned long restart_in; 298 #endif 299 zend_bool restart_in_progress; 300 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO 301 /* Interned Strings Support */ 302 char *interned_strings_start; 303 char *interned_strings_top; 304 char *interned_strings_end; 305 HashTable interned_strings; 306 struct { 307 Bucket **arBuckets; 308 Bucket *pListHead; 309 Bucket *pListTail; 310 char *top; 311 } interned_strings_saved_state; 312 #endif 313 } zend_accel_shared_globals; 314 315 extern zend_bool accel_startup_ok; 316 317 extern zend_accel_shared_globals *accel_shared_globals; 318 #define ZCSG(element) (accel_shared_globals->element) 319 320 #ifdef ZTS 321 # define ZCG(v) TSRMG(accel_globals_id, zend_accel_globals *, v) 322 extern int accel_globals_id; 323 #else 324 # define ZCG(v) (accel_globals.v) 325 extern zend_accel_globals accel_globals; 326 #endif 327 328 extern char *zps_api_failure_reason; 329 330 void accel_shutdown(TSRMLS_D); 331 void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC); 332 void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC); 333 int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC); 334 int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC); 335 int accelerator_shm_read_lock(TSRMLS_D); 336 void accelerator_shm_read_unlock(TSRMLS_D); 337 338 char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC); 339 zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC); 340 341 #if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED) 342 # define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145 343 #endif 344 345 #define ZEND_DECLARE_INHERITED_CLASS_DELAYED_FLAG 0x80 346 347 #if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO 348 349 const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC); 350 351 # define interned_free(s) do { \ 352 if (!IS_INTERNED(s)) { \ 353 free(s); \ 354 } \ 355 } while (0) 356 # define interned_efree(s) do { \ 357 if (!IS_INTERNED(s)) { \ 358 efree(s); \ 359 } \ 360 } while (0) 361 # define interned_estrndup(s, n) \ 362 (IS_INTERNED(s) ? (s) : estrndup(s, n)) 363 # define ZEND_RESULT_TYPE(opline) (opline)->result_type 364 # define ZEND_RESULT(opline) (opline)->result 365 # define ZEND_OP1_TYPE(opline) (opline)->op1_type 366 # define ZEND_OP1(opline) (opline)->op1 367 # define ZEND_OP1_CONST(opline) (*(opline)->op1.zv) 368 # define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant].constant 369 # define ZEND_OP2_TYPE(opline) (opline)->op2_type 370 # define ZEND_OP2(opline) (opline)->op2 371 # define ZEND_OP2_CONST(opline) (*(opline)->op2.zv) 372 # define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant].constant 373 # define ZEND_DONE_PASS_TWO(op_array) (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0) 374 # define ZEND_CE_FILENAME(ce) (ce)->info.user.filename 375 # define ZEND_CE_DOC_COMMENT(ce) (ce)->info.user.doc_comment 376 # define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->info.user.doc_comment_len 377 #else 378 # define IS_INTERNED(s) 0 379 # define interned_free(s) free(s) 380 # define interned_efree(s) efree(s) 381 # define interned_estrndup(s, n) estrndup(s, n) 382 # define ZEND_RESULT_TYPE(opline) (opline)->result.op_type 383 # define ZEND_RESULT(opline) (opline)->result.u 384 # define ZEND_OP1_TYPE(opline) (opline)->op1.op_type 385 # define ZEND_OP1(opline) (opline)->op1.u 386 # define ZEND_OP1_CONST(opline) (opline)->op1.u.constant 387 # define ZEND_OP1_LITERAL(opline) (opline)->op1.u.constant 388 # define ZEND_OP2_TYPE(opline) (opline)->op2.op_type 389 # define ZEND_OP2(opline) (opline)->op2.u 390 # define ZEND_OP2_CONST(opline) (opline)->op2.u.constant 391 # define ZEND_OP2_LITERAL(opline) (opline)->op2.u.constant 392 # define ZEND_DONE_PASS_TWO(op_array) ((op_array)->done_pass_two != 0) 393 # define ZEND_CE_FILENAME(ce) (ce)->filename 394 # define ZEND_CE_DOC_COMMENT(ce) (ce)->doc_comment 395 # define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->doc_comment_len 396 #endif 397 398 #endif /* ZEND_ACCELERATOR_H */ 399