ZendAccelerator.h 15 KB

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