Changeset 311
- Timestamp:
- 2006-12-09T17:27:03+01:00 (7 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
-
graph (added)
-
graph/cached_compile.dot (added)
-
processor/dispatch.m4 (modified) (1 diff)
-
processor/head.m4 (modified) (11 diffs)
-
processor/main.m4 (modified) (2 diffs)
-
processor/processor.m4 (modified) (7 diffs)
-
xcache.c (modified) (33 diffs)
-
xcache.h (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/processor/dispatch.m4
r1 r311 23 23 , `$1', `xc_entry_type_t', `PROC_INT(`$2', `d', `$1')' 24 24 , `$1', `xc_hash_value_t', `PROC_INT(`$2', `lu', `$1')' 25 , `$1', `xc_md5sum_t', `/* is copying enough? */COPY(`$2')' 25 26 , `', `', `m4_errprint(`Unknown type "$1"')' 26 27 ) -
trunk/processor/head.m4
r300 r311 65 65 zend_bool reference; /* enable if to deal with reference */ 66 66 zend_bool have_references; 67 const xc_entry_t *xce_src; 68 const xc_entry_t *xce_dst; 67 const xc_entry_data_php_t *php_src; 68 const xc_entry_data_php_t *php_dst; 69 const xc_cache_t *cache; 69 70 const zend_class_entry *cache_ce; 70 71 zend_uint cache_class_num; … … 186 187 static zend_ulong xc_get_class_num(xc_processor_t *processor, zend_class_entry *ce) { 187 188 zend_ulong i; 188 const xc_entry_ t *xce = processor->xce_src;189 const xc_entry_data_php_t *php = processor->php_src; 189 190 zend_class_entry *ceptr; 190 191 … … 192 193 return processor->cache_class_num; 193 194 } 194 for (i = 0; i < xce->data.php->classinfo_cnt; i ++) {195 ceptr = CestToCePtr( xce->data.php->classinfos[i].cest);195 for (i = 0; i < php->classinfo_cnt; i ++) { 196 ceptr = CestToCePtr(php->classinfos[i].cest); 196 197 if (ZCEP_REFCOUNT_PTR(ceptr) == ZCEP_REFCOUNT_PTR(ce)) { 197 198 processor->cache_ce = ceptr; … … 209 210 /* must be parent or currrent class */ 210 211 assert(class_num <= processor->active_class_num); 211 return CestToCePtr(processor-> xce_dst->data.php->classinfos[class_num - 1].cest);212 return CestToCePtr(processor->php_dst->classinfos[class_num - 1].cest); 212 213 } 213 214 #endif … … 275 276 /* }}} */ 276 277 dnl ================ export API 277 /* export: xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC); :export {{{ */ 278 xc_entry_t *xc_processor_store_xc_entry_t(xc_entry_t *src TSRMLS_DC) { 279 xc_entry_t *dst; 278 define(`DEFINE_STORE_API', ` 279 /* export: $1 *xc_processor_store_$1($1 *src TSRMLS_DC); :export {{{ */ 280 $1 *xc_processor_store_$1($1 *src TSRMLS_DC) { 281 $1 *dst; 280 282 xc_processor_t processor; 281 283 282 284 memset(&processor, 0, sizeof(processor)); 283 285 processor.reference = 1; 286 processor.cache = src->cache; 284 287 285 288 IFASSERT(`xc_stack_init(&processor.allocsizes);') … … 295 298 processor.size = ALIGN(processor.size + sizeof(src[0])); 296 299 297 xc_calc_ xc_entry_t(&processor, src TSRMLS_CC);300 xc_calc_$1(&processor, src TSRMLS_CC); 298 301 if (processor.reference) { 299 302 zend_hash_destroy(&processor.zvalptrs); … … 302 305 } 303 306 src->size = processor.size; 304 src->have_references = processor.have_references; 307 ifelse(`$1', `xc_entry_t', ` 308 src->data.var->have_references = processor.have_references; 309 ', ` 310 src->have_references = processor.have_references; 311 ') 305 312 306 313 IFASSERT(`xc_stack_reverse(&processor.allocsizes);') … … 314 321 315 322 /* mem :) */ 316 processor.p = (char *) src->cache->mem->handlers->malloc(src->cache->mem, processor.size);323 processor.p = (char *) processor.cache->mem->handlers->malloc(processor.cache->mem, processor.size); 317 324 if (processor.p == NULL) { 318 325 dst = NULL; … … 323 330 324 331 /* allocate */ 325 dst = ( xc_entry_t*) processor.p;332 dst = ($1 *) processor.p; 326 333 processor.p = (char *) ALIGN(processor.p + sizeof(dst[0])); 327 334 328 xc_store_ xc_entry_t(&processor, dst, src TSRMLS_CC);335 xc_store_$1(&processor, dst, src TSRMLS_CC); 329 336 IFASSERT(` { 330 337 int real = processor.p - oldp; … … 348 355 } 349 356 /* }}} */ 350 /* export: xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *src, zend_bool readonly_protection TSRMLS_DC); :export {{{ */ 351 xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *src, zend_bool readonly_protection TSRMLS_DC) { 357 ') 358 DEFINE_STORE_API(`xc_entry_t') 359 DEFINE_STORE_API(`xc_entry_data_php_t') 360 /* export: xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *src TSRMLS_DC); :export {{{ */ 361 xc_entry_t *xc_processor_restore_xc_entry_t(xc_entry_t *dst, const xc_entry_t *src TSRMLS_DC) { 362 xc_processor_t processor; 363 364 memset(&processor, 0, sizeof(processor)); 365 xc_restore_xc_entry_t(&processor, dst, src TSRMLS_CC); 366 367 return dst; 368 } 369 /* }}} */ 370 /* export: xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC); :export {{{ */ 371 xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC) { 352 372 xc_processor_t processor; 353 373 354 374 memset(&processor, 0, sizeof(processor)); 355 375 processor.readonly_protection = readonly_protection; 376 /* this function is used for php data only */ 356 377 if (src->have_references) { 357 378 processor.reference = 1; … … 361 382 zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0); 362 383 } 363 xc_restore_xc_entry_ t(&processor, dst, src TSRMLS_CC);384 xc_restore_xc_entry_data_php_t(&processor, dst, src TSRMLS_CC); 364 385 if (processor.reference) { 365 386 zend_hash_destroy(&processor.zvalptrs); -
trunk/processor/main.m4
r307 r311 136 136 define(`FIXPOINTER', `FIXPOINTER_EX(`$1', `dst->$2')') 137 137 define(`FIXPOINTER_EX', `IFSTORE(` 138 $2 = ($1 *) processor-> xce_src->cache->shm->handlers->to_readonly(processor->xce_src->cache->shm, (char *)$2);138 $2 = ($1 *) processor->cache->shm->handlers->to_readonly(processor->cache->shm, (char *)$2); 139 139 ')') 140 140 define(`UNFIXPOINTER', `UNFIXPOINTER_EX(`$1', `dst->$2')') 141 141 define(`UNFIXPOINTER_EX', `IFSTORE(` 142 $2 = ($1 *) processor-> xce_src->cache->shm->handlers->to_readwrite(processor->xce_src->cache->shm, (char *)$2);142 $2 = ($1 *) processor->cache->shm->handlers->to_readwrite(processor->cache->shm, (char *)$2); 143 143 ')') 144 144 dnl }}} 145 145 dnl {{{ COPY 146 146 define(`COPY', `IFNOTMEMCPY(`IFCOPY(`dst->$1 = src->$1;')')DONE(`$1')') 147 dnl }}} 148 dnl {{{ COPYPOINTER 149 define(`COPYPOINTER', `COPY(`$1')') 150 dnl }}} 151 dnl {{{ COPYARRAY 152 define(`COPYARRAY', `IFNOTMEMCPY(`IFCOPY(`memcpy(dst->$1, src->$1, sizeof(dst->$1));')')DONE(`$1')') 147 153 dnl }}} 148 154 dnl {{{ SETNULL_EX … … 223 229 EXPORT(`xc_funcinfo_t') 224 230 EXPORT(`xc_entry_t') 231 EXPORT(`xc_entry_data_php_t') 225 232 EXPORT(`zval') 226 233 -
trunk/processor/processor.m4
r310 r311 479 479 dnl readonly_protection=on 480 480 dnl main op_array && have early binding 481 if (!processor->readonly_protection && !(src == processor-> xce_src->data.php->op_array && processor->xce_src->data.php->have_early_binding)) {481 if (!processor->readonly_protection && !(src == processor->php_src->op_array && processor->php_src->have_early_binding)) { 482 482 /* really fast shallow copy */ 483 483 memcpy(dst, src, sizeof(src[0])); … … 719 719 zend_uint i; 720 720 721 #ifdef HAVE_INODE 722 DISPATCH(int, device) 723 DISPATCH(int, inode) 724 #endif 721 IFCOPY(` 722 processor->php_dst = dst; 723 processor->php_src = src; 724 ') 725 726 DISPATCH(xc_hash_value_t, hvalue) 727 /* skip */ 728 DONE(next) 729 COPY(cache) 730 DISPATCH(xc_md5sum_t, md5) 731 DISPATCH(zend_ulong, refcount) 732 725 733 DISPATCH(size_t, sourcesize) 726 727 DISPATCH( time_t, mtime)734 DISPATCH(zend_ulong, hits) 735 DISPATCH(size_t, size) 728 736 729 737 STRUCT_P(zend_op_array, op_array) … … 750 758 DISPATCH(zend_bool, have_early_binding) 751 759 popdef(`BEFORE_LOOP') 760 DISPATCH(zend_bool, have_references) 752 761 ') 753 762 dnl }}} … … 755 764 IFDPRINT(`INDENT()`'fprintf(stderr, "zval:value");') 756 765 STRUCT_P_EX(zval_ptr, dst->value, src->value, `value', `', `&') 766 DISPATCH(zend_bool, have_references) 757 767 DONE(value) 758 768 ') … … 760 770 dnl {{{ xc_entry_t 761 771 DEF_STRUCT_P_FUNC(`xc_entry_t', , ` 762 IFCOPY(`763 processor->xce_dst = dst;764 processor->xce_src = src;765 ')766 772 DISPATCH(xc_entry_type_t, type) 767 773 DISPATCH(size_t, size) … … 809 815 switch (src->type) { 810 816 case XC_TYPE_PHP: 811 STRUCT_P(xc_entry_data_php_t, data.php)817 IFCALCCOPY(`DONE(data.php)', `STRUCT_P(xc_entry_data_php_t, data.php)') 812 818 break; 819 813 820 case XC_TYPE_VAR: 814 821 STRUCT_P(xc_entry_data_var_t, data.var) 815 822 break; 823 816 824 default: 817 825 assert(0); … … 820 828 DONE(data) 821 829 dnl }}} 822 DISPATCH(zend_bool, have_references) 830 DISPATCH(time_t, mtime) 831 #ifdef HAVE_INODE 832 DISPATCH(int, device) 833 DISPATCH(int, inode) 834 #endif 823 835 ') 824 836 dnl }}} -
trunk/xcache.c
r307 r311 106 106 /* any function in *_dmz is only safe be called within locked(single thread) area */ 107 107 108 static void xc_php_add_dmz(xc_entry_data_php_t *php) /* {{{ */ 109 { 110 xc_entry_data_php_t **head = &(php->cache->phps[php->hvalue]); 111 php->next = *head; 112 *head = php; 113 php->cache->phps_count ++; 114 } 115 /* }}} */ 116 static xc_entry_data_php_t *xc_php_store_dmz(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */ 117 { 118 xc_entry_data_php_t *stored_php; 119 120 php->hits = 0; 121 php->refcount = 0; 122 stored_php = xc_processor_store_xc_entry_data_php_t(php TSRMLS_CC); 123 if (stored_php) { 124 xc_php_add_dmz(stored_php); 125 return stored_php; 126 } 127 else { 128 php->cache->ooms ++; 129 return NULL; 130 } 131 } 132 /* }}} */ 133 static xc_entry_data_php_t *xc_php_find_dmz(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */ 134 { 135 xc_entry_data_php_t *p; 136 for (p = php->cache->phps[php->hvalue]; p; p = p->next) { 137 if (memcmp(php->md5, p->md5, sizeof(php->md5)) == 0) { 138 p->hits ++; 139 return p; 140 } 141 } 142 return NULL; 143 } 144 /* }}} */ 145 static void xc_php_free_dmz(xc_entry_data_php_t *php) /* {{{ */ 146 { 147 php->cache->mem->handlers->free(php->cache->mem, (xc_entry_data_php_t *)php); 148 } 149 /* }}} */ 150 static void xc_php_remove_dmz(xc_entry_data_php_t *php) /* {{{ */ 151 { 152 if (-- php->refcount == 0) { 153 xc_entry_data_php_t **pp = &(php->cache->phps[php->hvalue]); 154 xc_entry_data_php_t *p; 155 for (p = *pp; p; pp = &(p->next), p = p->next) { 156 if (memcmp(php->md5, p->md5, sizeof(php->md5)) == 0) { 157 /* unlink */ 158 *pp = p->next; 159 xc_php_free_dmz(php); 160 return; 161 } 162 } 163 assert(0); 164 } 165 } 166 /* }}} */ 167 108 168 static inline int xc_entry_equal_dmz(xc_entry_t *a, xc_entry_t *b) /* {{{ */ 109 169 { … … 117 177 #ifdef HAVE_INODE 118 178 do { 119 xc_entry_data_php_t *ap = a->data.php; 120 xc_entry_data_php_t *bp = b->data.php; 121 if (ap->inode) { 122 return ap->inode == bp->inode 123 && ap->device == bp->device; 179 if (a->inode) { 180 return a->inode == b->inode 181 && a->device == b->device; 124 182 } 125 183 } while(0); … … 150 208 } 151 209 /* }}} */ 152 static void xc_entry_free_real_dmz(volatile xc_entry_t *xce) /* {{{ */153 {154 xce->cache->mem->handlers->free(xce->cache->mem, (xc_entry_t *)xce);155 }156 /* }}} */157 210 static void xc_entry_add_dmz(xc_entry_t *xce) /* {{{ */ 158 211 { … … 179 232 return NULL; 180 233 } 234 } 235 /* }}} */ 236 static void xc_entry_free_real_dmz(volatile xc_entry_t *xce) /* {{{ */ 237 { 238 if (xce->type == XC_TYPE_PHP) { 239 xc_php_remove_dmz(xce->data.php); 240 } 241 xce->cache->mem->handlers->free(xce->cache->mem, (xc_entry_t *)xce); 181 242 } 182 243 /* }}} */ … … 216 277 for (p = xce->cache->entries[xce->hvalue]; p; p = p->next) { 217 278 if (xc_entry_equal_dmz(xce, p)) { 218 if (p->type == XC_TYPE_VAR || /* PHP */ p-> data.php->mtime == xce->data.php->mtime) {279 if (p->type == XC_TYPE_VAR || /* PHP */ p->mtime == xce->mtime) { 219 280 p->hits ++; 220 281 p->atime = XG(request_time); … … 474 535 add_assoc_long_ex(ei, ZEND_STRS("sourcesize"), php->sourcesize); 475 536 #ifdef HAVE_INODE 476 add_assoc_long_ex(ei, ZEND_STRS("device"), php->device);477 add_assoc_long_ex(ei, ZEND_STRS("inode"), php->inode);478 #endif 479 add_assoc_long_ex(ei, ZEND_STRS("mtime"), php->mtime);537 add_assoc_long_ex(ei, ZEND_STRS("device"), entry->device); 538 add_assoc_long_ex(ei, ZEND_STRS("inode"), entry->inode); 539 #endif 540 add_assoc_long_ex(ei, ZEND_STRS("mtime"), entry->mtime); 480 541 481 542 #ifdef HAVE_XCACHE_CONSTANT … … 644 705 if (VCWD_STAT(filepath, pbuf) == 0) { 645 706 free_alloca(paths); 646 return 0;707 return FAILURE; 647 708 } 648 709 } … … 650 711 free_alloca(paths); 651 712 652 return 1;713 return SUCCESS; 653 714 } 654 715 /* }}} */ … … 656 717 #define HASH(i) (i) 657 718 #define HASH_USTR_L(t, s, l) HASH(zend_u_inline_hash_func(t, s, (l + 1) * sizeof(UChar))) 658 #define HASH_STR_L(s, l) HASH(zend_inline_hash_func(s, l + 1)) 719 #define HASH_STR_S(s, l) HASH(zend_inline_hash_func(s, l)) 720 #define HASH_STR_L(s, l) HASH_STR_S(s, l + 1) 659 721 #define HASH_STR(s) HASH_STR_L(s, strlen(s) + 1) 660 722 #define HASH_NUM(n) HASH(n) … … 669 731 { 670 732 #ifdef HAVE_INODE 671 if (xce-> data.php->inode) {672 return HASH(xce->d ata.php->device + xce->data.php->inode);733 if (xce->inode) { 734 return HASH(xce->device + xce->inode); 673 735 } 674 736 #endif … … 685 747 686 748 if (!filename || !SG(request_info).path_translated) { 687 return 0;749 return FAILURE; 688 750 } 689 751 … … 703 765 if (IS_ABSOLUTE_PATH(filename, strlen(filename))) { 704 766 if (VCWD_STAT(filename, pbuf) != 0) { 705 return 0;767 return FAILURE; 706 768 } 707 769 goto stat_done; … … 719 781 720 782 if (VCWD_STAT(filename, pbuf) != 0) { 721 return 0;783 return FAILURE; 722 784 } 723 785 goto stat_done; … … 726 788 727 789 /* use include_path */ 728 if (xc_stat(filename, PG(include_path), pbuf TSRMLS_CC) != 0) {729 return 0;790 if (xc_stat(filename, PG(include_path), pbuf TSRMLS_CC) != SUCCESS) { 791 return FAILURE; 730 792 } 731 793 … … 734 796 stat_done: 735 797 if (XG(request_time) - pbuf->st_mtime < 2 && !xc_test) { 736 return 0;737 } 738 739 php->mtime = pbuf->st_mtime;798 return FAILURE; 799 } 800 801 xce->mtime = pbuf->st_mtime; 740 802 #ifdef HAVE_INODE 741 php->device = pbuf->st_dev;742 php->inode = pbuf->st_ino;803 xce->device = pbuf->st_dev; 804 xce->inode = pbuf->st_ino; 743 805 #endif 744 806 php->sourcesize = pbuf->st_size; 745 807 } 746 808 else { /* XG(inode) */ 747 php->mtime = 0;809 xce->mtime = 0; 748 810 #ifdef HAVE_INODE 749 php->device = 0;750 php->inode = 0;811 xce->device = 0; 812 xce->inode = 0; 751 813 #endif 752 814 php->sourcesize = 0; … … 754 816 755 817 #ifdef HAVE_INODE 756 if (! php->inode)818 if (!xce->inode) 757 819 #endif 758 820 { … … 760 822 filename = expand_filepath(filename, opened_path_buffer TSRMLS_CC); 761 823 if (filename == NULL) { 762 return 0;824 return FAILURE; 763 825 } 764 826 } … … 775 837 776 838 xce->type = XC_TYPE_PHP; 777 return 1; 839 return SUCCESS; 840 } 841 /* }}} */ 842 static inline xc_hash_value_t xc_php_hash_md5(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */ 843 { 844 return HASH_STR_S(php->md5, sizeof(php->md5)); 845 } 846 /* }}} */ 847 static int xc_entry_init_key_php_md5(xc_entry_data_php_t *php, xc_entry_t *xce TSRMLS_DC) /* {{{ */ 848 { 849 unsigned char buf[1024]; 850 PHP_MD5_CTX context; 851 int n; 852 php_stream *stream; 853 xc_hash_value_t hv; 854 855 stream = php_stream_open_wrapper(xce->name.str.val, "rb", REPORT_ERRORS | ENFORCE_SAFE_MODE, NULL); 856 if (!stream) { 857 return FAILURE; 858 } 859 860 PHP_MD5Init(&context); 861 while ((n = php_stream_read(stream, (char *) buf, sizeof(buf))) > 0) { 862 PHP_MD5Update(&context, buf, n); 863 } 864 PHP_MD5Final((unsigned char *) php->md5, &context); 865 866 php_stream_close(stream); 867 868 if (n < 0) { 869 return FAILURE; 870 } 871 872 hv = xc_php_hash_md5(php TSRMLS_CC); 873 php->cache = xce->cache; 874 php->hvalue = (hv & php->cache->hphp->mask); 875 #ifdef DEBUG 876 { 877 char md5str[33]; 878 make_digest(md5str, (unsigned char *) php->md5); 879 TRACE("md5 %s", md5str); 880 } 881 #endif 882 883 return SUCCESS; 778 884 } 779 885 /* }}} */ … … 805 911 } 806 912 /* }}} */ 807 static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ 808 { 809 xc_sandbox_t sandbox; 913 static void xc_free_php(xc_entry_data_php_t *php TSRMLS_DC) /* {{{ */ 914 { 915 #define X_FREE(var) do {\ 916 if (php->var) { \ 917 efree(php->var); \ 918 } \ 919 } while (0) 920 921 #ifdef ZEND_ENGINE_2_1 922 X_FREE(autoglobals); 923 #endif 924 X_FREE(classinfos); 925 X_FREE(funcinfos); 926 #ifdef HAVE_XCACHE_CONSTANT 927 X_FREE(constinfos); 928 #endif 929 #undef X_FREE 930 } 931 /* }}} */ 932 static zend_op_array *xc_compile_php(xc_entry_data_php_t *php, zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ 933 { 810 934 zend_op_array *op_array; 811 xc_entry_t xce, *stored_xce;812 xc_entry_data_php_t php;813 xc_cache_t *cache;814 zend_bool clogged = 0;815 zend_bool catched = 0;816 char *filename;817 char opened_path_buffer[MAXPATHLEN];818 935 int old_constinfo_cnt, old_funcinfo_cnt, old_classinfo_cnt; 819 936 int i; 820 821 if (!xc_initized) { 822 assert(0); 823 } 824 825 if (!XG(cacher)) { 826 op_array = origin_compile_file(h, type TSRMLS_CC); 827 #ifdef HAVE_XCACHE_OPTIMIZER 828 if (XG(optimizer)) { 829 xc_optimize(op_array TSRMLS_CC); 830 } 831 #endif 832 return op_array; 833 } 834 835 /* {{{ prepare key 836 * include_once() and require_once() gives us opened_path 837 * however, include() and require() non-absolute path which break 838 * included_files, and may confuse with (include|require)_once 839 * -- Xuefer 840 */ 841 842 filename = h->opened_path ? h->opened_path : h->filename; 843 xce.data.php = &php; 844 if (!xc_entry_init_key_php(&xce, filename, opened_path_buffer TSRMLS_CC)) { 845 return origin_compile_file(h, type TSRMLS_CC); 846 } 847 cache = xce.cache; 848 /* }}} */ 849 /* {{{ restore */ 850 /* stale precheck */ 851 if (cache->compiling) { 852 cache->clogs ++; /* is it safe here? */ 853 return origin_compile_file(h, type TSRMLS_CC); 854 } 855 856 stored_xce = NULL; 857 op_array = NULL; 858 ENTER_LOCK_EX(cache) { 859 /* clogged */ 860 if (cache->compiling) { 861 cache->clogs ++; 862 op_array = NULL; 863 clogged = 1; 864 break; 865 } 866 867 stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); 868 /* found */ 869 if (stored_xce) { 870 TRACE("found %s, catch it", stored_xce->name.str.val); 871 xc_entry_hold_php_dmz(stored_xce TSRMLS_CC); 872 cache->hits ++; 873 break; 874 } 875 876 cache->compiling = XG(request_time); 877 cache->misses ++; 878 } LEAVE_LOCK_EX(cache); 879 880 if (catched) { 881 cache->compiling = 0; 882 zend_bailout(); 883 } 884 885 /* found */ 886 if (stored_xce) { 887 goto restore; 888 } 889 890 /* clogged */ 891 if (clogged) { 892 return origin_compile_file(h, type TSRMLS_CC); 893 } 894 /* }}} */ 937 zend_bool catched = 0; 895 938 896 939 /* {{{ compile */ 897 TRACE("compiling %s", filename); 898 899 /* make compile inside sandbox */ 900 xc_sandbox_init(&sandbox, filename TSRMLS_CC); 940 TRACE("compiling %s", h->opened_path ? h->opened_path : h->filename); 901 941 902 942 old_classinfo_cnt = zend_hash_num_elements(CG(class_table)); … … 915 955 916 956 if (op_array == NULL) { 917 goto err_oparray; 918 } 919 920 filename = h->opened_path ? h->opened_path : h->filename; 921 /* none-inode enabled entry hash/compare on name 922 * do not update to its name to real pathname 923 */ 924 #ifdef HAVE_INODE 925 if (xce.data.php->inode) 926 { 927 if (xce.name.str.val != filename) { 928 xce.name.str.val = filename; 929 xce.name.str.len = strlen(filename); 930 } 931 } 932 #endif 957 goto err_op_array; 958 } 933 959 934 960 #ifdef HAVE_XCACHE_OPTIMIZER … … 939 965 /* }}} */ 940 966 /* {{{ prepare */ 941 php .op_array = op_array;967 php->op_array = op_array; 942 968 943 969 #ifdef HAVE_XCACHE_CONSTANT 944 php .constinfo_cnt = zend_hash_num_elements(EG(zend_constants)) - old_constinfo_cnt;945 #endif 946 php .funcinfo_cnt = zend_hash_num_elements(CG(function_table)) - old_funcinfo_cnt;947 php .classinfo_cnt = zend_hash_num_elements(CG(class_table)) - old_classinfo_cnt;970 php->constinfo_cnt = zend_hash_num_elements(EG(zend_constants)) - old_constinfo_cnt; 971 #endif 972 php->funcinfo_cnt = zend_hash_num_elements(CG(function_table)) - old_funcinfo_cnt; 973 php->classinfo_cnt = zend_hash_num_elements(CG(class_table)) - old_classinfo_cnt; 948 974 #ifdef ZEND_ENGINE_2_1 949 /* {{{ count php .autoglobal_cnt */ {975 /* {{{ count php->autoglobal_cnt */ { 950 976 Bucket *b; 951 977 952 php .autoglobal_cnt = 0;978 php->autoglobal_cnt = 0; 953 979 for (b = CG(auto_globals)->pListHead; b != NULL; b = b->pListNext) { 954 980 zend_auto_global *auto_global = (zend_auto_global *) b->pData; 955 981 /* check if actived */ 956 982 if (auto_global->auto_global_callback && !auto_global->armed) { 957 php .autoglobal_cnt ++;983 php->autoglobal_cnt ++; 958 984 } 959 985 } … … 963 989 964 990 #define X_ALLOC_N(var, cnt) do { \ 965 if (php .cnt) {\966 ECALLOC_N(php .var, php.cnt); \967 if (!php .var) {\968 goto err_ ##var; \991 if (php->cnt) { \ 992 ECALLOC_N(php->var, php->cnt); \ 993 if (!php->var) { \ 994 goto err_alloc; \ 969 995 } \ 970 996 } \ 971 997 else { \ 972 php .var = NULL;\998 php->var = NULL; \ 973 999 } \ 974 1000 } while (0) … … 990 1016 #define COPY_H(vartype, var, cnt, name, datatype) do { \ 991 1017 for (i = 0; b; i ++, b = b->pListNext) { \ 992 vartype *data = &php .var[i];\1018 vartype *data = &php->var[i]; \ 993 1019 \ 994 1020 if (i < old_##cnt) { \ … … 996 1022 } \ 997 1023 \ 998 assert(i < old_##cnt + php .cnt);\1024 assert(i < old_##cnt + php->cnt); \ 999 1025 assert(b->pData); \ 1000 1026 memcpy(&data->name, b->pData, sizeof(datatype)); \ 1001 1027 UNISW(NOTHING, data->type = b->key.type;) \ 1002 1028 if (UNISW(1, b->key.type == IS_STRING)) { \ 1003 ZSTR_S(data->key) = BUCKET_KEY_S(b); \1029 ZSTR_S(data->key) = BUCKET_KEY_S(b); \ 1004 1030 } \ 1005 1031 else { \ … … 1027 1053 /* check if actived */ 1028 1054 if (auto_global->auto_global_callback && !auto_global->armed) { 1029 xc_autoglobal_t *data = &php .autoglobals[i];1030 1031 assert(i < php .autoglobal_cnt);1055 xc_autoglobal_t *data = &php->autoglobals[i]; 1056 1057 assert(i < php->autoglobal_cnt); 1032 1058 i ++; 1033 1059 UNISW(NOTHING, data->type = b->key.type;) … … 1045 1071 /* }}} */ 1046 1072 /* {{{ find inherited classes that should be early-binding */ 1047 php .have_early_binding = 0;1048 for (i = 0; i < php .classinfo_cnt; i ++) {1049 php .classinfos[i].oplineno = -1;1050 } 1051 1052 xc_undo_pass_two(php .op_array TSRMLS_CC);1053 xc_foreach_early_binding_class(php .op_array, xc_cache_early_binding_class_cb, (void *) &php TSRMLS_CC);1054 xc_redo_pass_two(php .op_array TSRMLS_CC);1073 php->have_early_binding = 0; 1074 for (i = 0; i < php->classinfo_cnt; i ++) { 1075 php->classinfos[i].oplineno = -1; 1076 } 1077 1078 xc_undo_pass_two(php->op_array TSRMLS_CC); 1079 xc_foreach_early_binding_class(php->op_array, xc_cache_early_binding_class_cb, (void *) &php TSRMLS_CC); 1080 xc_redo_pass_two(php->op_array TSRMLS_CC); 1055 1081 /* }}} */ 1056 #ifdef SHOW_DPRINT 1057 xc_dprint(&xce, 0 TSRMLS_CC); 1058 #endif 1059 ENTER_LOCK_EX(cache) { /* {{{ store/add entry */ 1060 stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC); 1061 } LEAVE_LOCK_EX(cache); 1062 /* }}} */ 1063 TRACE("%s", "stored"); 1064 1065 #define X_FREE(var) \ 1066 if (xce.data.php->var) { \ 1067 efree(xce.data.php->var); \ 1068 } \ 1069 err_##var: 1070 1071 #ifdef ZEND_ENGINE_2_1 1072 X_FREE(autoglobals) 1073 #endif 1074 X_FREE(classinfos) 1075 X_FREE(funcinfos) 1076 #ifdef HAVE_XCACHE_CONSTANT 1077 X_FREE(constinfos) 1078 #endif 1079 #undef X_FREE 1080 1081 err_oparray: 1082 1083 return op_array; 1084 1085 err_alloc: 1086 xc_free_php(php TSRMLS_CC); 1087 1082 1088 err_bailout: 1083 1084 if (xc_test && stored_xce) { 1085 /* free it, no install. restore now */ 1086 xc_sandbox_free(&sandbox, 0 TSRMLS_CC); 1087 } 1088 else if (!op_array) { 1089 /* failed to compile free it, no install */ 1090 xc_sandbox_free(&sandbox, 0 TSRMLS_CC); 1091 } 1092 else { 1093 CG(active_op_array) = op_array; 1094 xc_sandbox_free(&sandbox, 1 TSRMLS_CC); 1095 } 1096 1097 ENTER_LOCK(cache) { 1098 cache->compiling = 0; 1099 } LEAVE_LOCK(cache); 1089 err_op_array: 1090 1100 1091 if (catched) { 1101 1092 zend_bailout(); 1102 1093 } 1103 if (xc_test && stored_xce) { 1104 #ifdef ZEND_ENGINE_2 1105 destroy_op_array(op_array TSRMLS_CC); 1106 #else 1107 destroy_op_array(op_array); 1108 #endif 1109 efree(op_array); 1110 h = NULL; 1111 goto restore; 1112 } 1094 1113 1095 return op_array; 1114 1115 restore: 1096 } 1097 /* }}} */ 1098 static zend_op_array *xc_compile_restore(xc_entry_t *stored_xce, zend_file_handle *h TSRMLS_DC) /* {{{ */ 1099 { 1100 zend_op_array *op_array; 1101 xc_entry_t xce; 1102 xc_entry_data_php_t php; 1103 zend_bool catched; 1104 1116 1105 CG(in_compilation) = 1; 1117 1106 CG(compiled_filename) = stored_xce->name.str.val; 1118 1107 CG(zend_lineno) = 0; 1119 1108 TRACE("restoring %s", stored_xce->name.str.val); 1120 xc_processor_restore_xc_entry_t(&xce, stored_xce, xc_readonly_protection TSRMLS_CC); 1109 xc_processor_restore_xc_entry_t(&xce, stored_xce TSRMLS_CC); 1110 xc_processor_restore_xc_entry_data_php_t(&php, xce.data.php, xc_readonly_protection TSRMLS_CC); 1111 xce.data.php = &php; 1121 1112 #ifdef SHOW_DPRINT 1122 1113 xc_dprint(&xce, 0 TSRMLS_CC); … … 1130 1121 } zend_end_try(); 1131 1122 1132 #define X_FREE(var) \ 1133 if (xce.data.php->var) { \ 1134 efree(xce.data.php->var); \ 1135 } 1136 #ifdef ZEND_ENGINE_2_1 1137 X_FREE(autoglobals) 1138 #endif 1139 X_FREE(classinfos) 1140 X_FREE(funcinfos) 1141 #ifdef HAVE_XCACHE_CONSTANT 1142 X_FREE(constinfos) 1143 #endif 1144 #undef X_FREE 1145 efree(xce.data.php); 1123 xc_free_php(&php TSRMLS_CC); 1146 1124 1147 1125 if (catched) { … … 1151 1129 CG(compiled_filename) = NULL; 1152 1130 TRACE("restored %s", stored_xce->name.str.val); 1131 return op_array; 1132 } 1133 /* }}} */ 1134 static zend_op_array *xc_compile_file(zend_file_handle *h, int type TSRMLS_DC) /* {{{ */ 1135 { 1136 zend_op_array *op_array; 1137 xc_entry_t xce, *stored_xce; 1138 xc_entry_data_php_t php, *stored_php; 1139 xc_cache_t *cache; 1140 zend_bool gaveup = 0; 1141 zend_bool catched = 0; 1142 zend_bool cached_php; 1143 char *filename; 1144 char opened_path_buffer[MAXPATHLEN]; 1145 xc_sandbox_t sandbox; 1146 1147 assert(xc_initized); 1148 1149 if (!XG(cacher)) { 1150 op_array = origin_compile_file(h, type TSRMLS_CC); 1151 #ifdef HAVE_XCACHE_OPTIMIZER 1152 if (XG(optimizer)) { 1153 xc_optimize(op_array TSRMLS_CC); 1154 } 1155 #endif 1156 return op_array; 1157 } 1158 1159 /* {{{ entry_init_key */ 1160 filename = h->opened_path ? h->opened_path : h->filename; 1161 xce.data.php = &php; 1162 if (xc_entry_init_key_php(&xce, filename, opened_path_buffer TSRMLS_CC) != SUCCESS) { 1163 return origin_compile_file(h, type TSRMLS_CC); 1164 } 1165 cache = xce.cache; 1166 /* }}} */ 1167 1168 /* stale clogs precheck */ 1169 if (cache->compiling) { 1170 cache->clogs ++; 1171 return origin_compile_file(h, type TSRMLS_CC); 1172 } 1173 /* {{{ entry_lookup/hit/md5_init/php_lookup */ 1174 stored_xce = NULL; 1175 stored_php = NULL; 1176 ENTER_LOCK_EX(cache) { 1177 stored_xce = xc_entry_find_dmz(&xce TSRMLS_CC); 1178 if (stored_xce) { 1179 cache->hits ++; 1180 1181 TRACE("hit %s, holding", stored_xce->name.str.val); 1182 xc_entry_hold_php_dmz(stored_xce TSRMLS_CC); 1183 } 1184 else { 1185 cache->misses ++; 1186 TRACE("miss %s", xce.name.str.val); 1187 1188 if (xc_entry_init_key_php_md5(&php, &xce TSRMLS_CC) != SUCCESS) { 1189 gaveup = 1; 1190 break; 1191 } 1192 1193 stored_php = xc_php_find_dmz(&php TSRMLS_CC); 1194 1195 /* miss but compiling */ 1196 if (!stored_php) { 1197 if (cache->compiling) { 1198 TRACE("%s", "miss but compiling"); 1199 cache->clogs ++; 1200 gaveup = 1; 1201 break; 1202 } 1203 TRACE("%s", "php_lookup miss"); 1204 } 1205 else { 1206 TRACE("%s", "php_lookup hit"); 1207 } 1208 1209 cache->compiling = XG(request_time); 1210 } 1211 } LEAVE_LOCK_EX(cache); 1212 1213 if (catched) { 1214 cache->compiling = 0; 1215 zend_bailout(); 1216 } 1217 1218 /* hit */ 1219 if (stored_xce) { 1220 return xc_compile_restore(stored_xce, h TSRMLS_CC); 1221 } 1222 1223 /* gaveup */ 1224 if (gaveup) { 1225 return origin_compile_file(h, type TSRMLS_CC); 1226 } 1227 /* }}} */ 1228 op_array = NULL; 1229 /* {{{ compile */ 1230 if (stored_php) { 1231 cached_php = 1; 1232 xce.data.php = stored_php; 1233 } 1234 else { 1235 cached_php = 0; 1236 1237 /* make compile inside sandbox */ 1238 xc_sandbox_init(&sandbox, filename TSRMLS_CC); 1239 zend_try { 1240 op_array = xc_compile_php(&php, h, type TSRMLS_CC); 1241 } zend_catch { 1242 catched = 1; 1243 } zend_end_try(); 1244 xc_sandbox_free(&sandbox, 0 TSRMLS_CC); 1245 1246 if (catched) { 1247 cache->compiling = 0; 1248 zend_bailout(); 1249 } 1250 1251 xce.data.php = &php; 1252 } 1253 /* }}} */ 1254 #ifdef HAVE_INODE 1255 /* {{{ path name fix 1256 * inode enabled entry hash/compare on name 1257 * do not update to its name to real pathname 1258 * WARNING: this code is required to be after compile 1259 */ 1260 if (xce.inode) { 1261 filename = h->opened_path ? h->opened_path : h->filename; 1262 if (xce.name.str.val != filename) { 1263 xce.name.str.val = filename; 1264 xce.name.str.len = strlen(filename); 1265 } 1266 } 1267 /* }}} */ 1268 #endif 1269 #ifdef SHOW_DPRINT 1270 xc_dprint(&xce, 0 TSRMLS_CC); 1271 #endif 1272 stored_xce = NULL; 1273 ENTER_LOCK_EX(cache) { /* {{{ php_store/entry_store */ 1274 /* php_store */ 1275 if (!cached_php) { 1276 stored_php = xc_php_store_dmz(&php TSRMLS_CC); 1277 /* error */ 1278 if (!stored_php) { 1279 break; 1280 } 1281 } 1282 /* entry_store */ 1283 stored_xce = xc_entry_store_dmz(&xce TSRMLS_CC); 1284 if (stored_xce) { 1285 stored_xce->data.php = stored_php; 1286 stored_php->refcount ++; 1287 } 1288 else { 1289 /* error */ 1290 xc_php_remove_dmz(stored_php); 1291 stored_php = NULL; 1292 } 1293 } LEAVE_LOCK_EX(cache); 1294 /* }}} */ 1295 TRACE("%s", stored_xce ? "stored" : "store failed"); 1296 1297 cache->compiling = 0; 1298 if (catched) { 1299 zend_bailout(); 1300 } 1301 1302 if (stored_xce) { 1303 if (op_array) { 1304 #ifdef ZEND_ENGINE_2 1305 destroy_op_array(op_array TSRMLS_CC); 1306 #else 1307 destroy_op_array(op_array); 1308 #endif 1309 efree(op_array); 1310 h = NULL; 1311 } 1312 return xc_compile_restore(stored_xce, h TSRMLS_CC); 1313 } 1153 1314 return op_array; 1154 1315 } … … 1279 1440 } 1280 1441 /* }}} */ 1281 static xc_cache_t **xc_cache_init(xc_shm_t *shm, xc_hash_t *hcache, xc_hash_t *hentry, xc_ shmsize_t shmsize) /* {{{ */1442 static xc_cache_t **xc_cache_init(xc_shm_t *shm, xc_hash_t *hcache, xc_hash_t *hentry, xc_hash_t *hphp, xc_shmsize_t shmsize) /* {{{ */ 1282 1443 { 1283 1444 xc_cache_t **caches = NULL, *cache; … … 1306 1467 CHECK(cache = mem->handlers->calloc(mem, 1, sizeof(xc_cache_t)), "cache OOM"); 1307 1468 CHECK(cache->entries = mem->handlers->calloc(mem, hentry->size, sizeof(xc_entry_t*)), "entries OOM"); 1469 if (hphp) { 1470 CHECK(cache->phps= mem->handlers->calloc(mem, hphp->size, sizeof(xc_entry_data_php_t*)), "phps OOM"); 1471 } 1308 1472 CHECK(cache->lck = xc_lock_init(NULL), "can't create lock"); 1309 1473 1310 1474 cache->hcache = hcache; 1311 1475 cache->hentry = hentry; 1476 cache->hphp = hphp; 1312 1477 cache->shm = shm; 1313 1478 cache->mem = mem; … … 1364 1529 zend_compile_file = xc_compile_file; 1365 1530 1366 CHECK(xc_php_caches = xc_cache_init(shm, &xc_php_hcache, &xc_php_hentry, xc_php_size), "failed init opcode cache");1531 CHECK(xc_php_caches = xc_cache_init(shm, &xc_php_hcache, &xc_php_hentry, &xc_php_hentry, xc_php_size), "failed init opcode cache"); 1367 1532 } 1368 1533 1369 1534 if (xc_var_size) { 1370 CHECK(xc_var_caches = xc_cache_init(shm, &xc_var_hcache, &xc_var_hentry, xc_var_size), "failed init variable cache");1535 CHECK(xc_var_caches = xc_cache_init(shm, &xc_var_hcache, &xc_var_hentry, NULL, xc_var_size), "failed init variable cache"); 1371 1536 } 1372 1537 } … … 1715 1880 if (stored_xce) { 1716 1881 if (!VAR_ENTRY_EXPIRED(stored_xce)) { 1717 xc_processor_restore_zval(return_value, stored_xce->data.var->value, stored_xce-> have_references TSRMLS_CC);1882 xc_processor_restore_zval(return_value, stored_xce->data.var->value, stored_xce->data.var->have_references TSRMLS_CC); 1718 1883 /* return */ 1719 1884 break; … … 1864 2029 else { 1865 2030 TRACE("%s", "incdec: notlong"); 1866 xc_processor_restore_zval(&oldzval, stored_xce->data.var->value, stored_xce-> have_references TSRMLS_CC);2031 xc_processor_restore_zval(&oldzval, stored_xce->data.var->value, stored_xce->data.var->have_references TSRMLS_CC); 1867 2032 convert_to_long(&oldzval); 1868 2033 value = Z_LVAL(oldzval); -
trunk/xcache.h
r309 r311 165 165 typedef zend_op_array *(zend_compile_file_t)(zend_file_handle *h, int type TSRMLS_DC); 166 166 167 typedef struct _xc_entry_t xc_entry_t; 168 typedef struct _xc_entry_data_php_t xc_entry_data_php_t; 167 169 /* {{{ xc_cache_t */ 168 typedef struct _xc_entry_t xc_entry_t;169 170 typedef struct { 170 171 int cacheid; … … 182 183 xc_entry_t **entries; 183 184 int entries_count; 185 xc_entry_data_php_t **phps; 186 int phps_count; 184 187 xc_entry_t *deletes; 185 188 int deletes_count; 186 xc_hash_t *hentry; /* hash to entry */ 189 xc_hash_t *hentry; /* hash settings to entry */ 190 xc_hash_t *hphp; /* hash settings to php */ 187 191 188 192 time_t last_gc_deletes; … … 235 239 #endif 236 240 typedef enum { XC_TYPE_PHP, XC_TYPE_VAR } xc_entry_type_t; 241 typedef char xc_md5sum_t[16]; 237 242 /* {{{ xc_entry_data_php_t */ 238 typedef struct { 243 struct _xc_entry_data_php_t { 244 xc_hash_value_t hvalue; /* hash of md5 */ 245 xc_entry_data_php_t *next; 246 xc_cache_t *cache; /* which cache it's on */ 247 248 xc_md5sum_t md5; /* md5sum of the source */ 249 zend_ulong refcount; /* count of entries referencing to this data */ 250 239 251 size_t sourcesize; 240 #ifdef HAVE_INODE 241 int device; /* the filesystem device */ 242 int inode; /* the filesystem inode */ 243 #endif 244 time_t mtime; /* the mtime of origin source file */ 252 zend_ulong hits; /* hits of this php */ 253 size_t size; 245 254 246 255 zend_op_array *op_array; … … 262 271 xc_autoglobal_t *autoglobals; 263 272 #endif 264 } xc_entry_data_php_t; 273 274 zend_bool have_references; 275 }; 265 276 /* }}} */ 266 277 /* {{{ xc_entry_data_var_t */ 267 278 typedef struct { 268 279 zval *value; 280 281 zend_bool have_references; 269 282 } xc_entry_data_var_t; 270 283 /* }}} */ … … 278 291 279 292 size_t size; 280 zend_ulong refcount; 293 zend_ulong refcount; /* count of instances holding this entry */ 281 294 zend_ulong hits; 282 295 time_t ctime; /* the ctime of this entry */ … … 295 308 } data; 296 309 297 zend_bool have_references; 310 time_t mtime; /* the mtime of origin source file */ 311 #ifdef HAVE_INODE 312 int device; /* the filesystem device */ 313 int inode; /* the filesystem inode */ 314 #endif 298 315 }; 299 316 /* }}} */
Note: See TracChangeset
for help on using the changeset viewer.

