XCache is a fast, stable PHP opcode cacher that has been proven and is now running on production servers under high load. https://xcache.lighttpd.net/
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

195 linhas
6.4 KiB

  1. dnl {{{ xc_store_target
  2. EXPORT(`typedef void *(*xc_processor_storage_allocator_t)(void *data, size_t size);')
  3. EXPORT(`typedef struct { xc_processor_storage_allocator_t allocator; void *allocator_data; ptrdiff_t relocatediff; } xc_processor_storage_t;')
  4. dnl }}}
  5. define(`DEFINE_STORE_API', `
  6. EXPORTED_FUNCTION(`$1 *xc_processor_store_$1(const xc_processor_storage_t *storage, $1 *src TSRMLS_DC)') dnl {{{
  7. {
  8. $1 *dst;
  9. xc_processor_t processor;
  10. memset(&processor, 0, sizeof(processor));
  11. processor.handle_reference = 1;
  12. processor.relocatediff = storage->relocatediff;
  13. IFAUTOCHECK(`xc_vector_init(unsigned long, &processor.allocsizes);')
  14. /* calc size */ {
  15. zend_hash_init(&processor.strings, 0, NULL, NULL, 0);
  16. if (processor.handle_reference) {
  17. zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
  18. }
  19. processor.size = 0;
  20. /* allocate */
  21. processor.size = ALIGN(processor.size + sizeof(src[0]));
  22. xc_calc_$1(&processor, src TSRMLS_CC);
  23. if (processor.handle_reference) {
  24. zend_hash_destroy(&processor.zvalptrs);
  25. }
  26. zend_hash_destroy(&processor.strings);
  27. }
  28. ifelse(
  29. `$1', `xc_entry_data_php_t', `SRC(`size')',
  30. `', `', SRC(`entry.size')) = processor.size;
  31. ifelse(
  32. `$1', `xc_entry_var_t', `SRC(`have_references') = processor.have_references;',
  33. `$1', `xc_entry_data_php_t', `SRC(`have_references') = processor.have_references;'
  34. )
  35. IFAUTOCHECK(`xc_vector_reverse(&processor.allocsizes);')
  36. /* store {{{ */
  37. {
  38. IFAUTOCHECK(`char *oldp;')
  39. zend_hash_init(&processor.strings, 0, NULL, NULL, 0);
  40. if (processor.handle_reference) {
  41. zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
  42. }
  43. /* allocator :) */
  44. processor.p = (char *) storage->allocator(storage->allocator_data, processor.size);
  45. if (processor.p == NULL) {
  46. dst = NULL;
  47. goto err_alloc;
  48. }
  49. IFAUTOCHECK(`oldp = processor.p;')
  50. assert(processor.p == (char *) ALIGN(processor.p));
  51. /* allocate */
  52. dst = ($1 *) processor.p;
  53. processor.p = (char *) ALIGN(processor.p + sizeof(dst[0]));
  54. xc_store_$1(&processor, dst, src TSRMLS_CC);
  55. IFAUTOCHECK(` {
  56. size_t unexpected = processor.p - oldp;
  57. size_t expected = processor.size;
  58. if (unexpected != processor.size) {
  59. fprintf(stderr, "unexpected:%lu - expected:%lu = %ld != 0\n", (unsigned long) unexpected, (unsigned long) expected, (long) unexpected - expected);
  60. abort();
  61. }
  62. }')
  63. err_alloc:
  64. if (processor.handle_reference) {
  65. zend_hash_destroy(&processor.zvalptrs);
  66. }
  67. zend_hash_destroy(&processor.strings);
  68. }
  69. /* }}} */
  70. IFAUTOCHECK(`xc_vector_destroy(&processor.allocsizes);')
  71. return dst;
  72. }
  73. dnl }}}
  74. ')
  75. DEFINE_STORE_API(`xc_entry_php_t')
  76. DEFINE_STORE_API(`xc_entry_data_php_t')
  77. DEFINE_STORE_API(`xc_entry_var_t')
  78. EXPORTED_FUNCTION(`xc_entry_php_t *xc_processor_restore_xc_entry_php_t(xc_entry_php_t *dst, const xc_entry_php_t *src TSRMLS_DC)') dnl {{{
  79. {
  80. xc_processor_t processor;
  81. memset(&processor, 0, sizeof(processor));
  82. xc_restore_xc_entry_php_t(&processor, dst, src TSRMLS_CC);
  83. return dst;
  84. }
  85. dnl }}}
  86. EXPORTED_FUNCTION(`xc_entry_data_php_t *xc_processor_restore_xc_entry_data_php_t(const xc_entry_php_t *entry_php, xc_entry_data_php_t *dst, const xc_entry_data_php_t *src, zend_bool readonly_protection TSRMLS_DC)') dnl {{{
  87. {
  88. xc_processor_t processor;
  89. memset(&processor, 0, sizeof(processor));
  90. processor.readonly_protection = readonly_protection;
  91. /* this function is used for php data only */
  92. if (SRC(`have_references')) {
  93. processor.handle_reference = 1;
  94. }
  95. processor.entry_php_src = entry_php;
  96. if (processor.handle_reference) {
  97. zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
  98. }
  99. xc_restore_xc_entry_data_php_t(&processor, dst, src TSRMLS_CC);
  100. if (processor.handle_reference) {
  101. zend_hash_destroy(&processor.zvalptrs);
  102. }
  103. return dst;
  104. }
  105. dnl }}}
  106. EXPORTED_FUNCTION(`zval *xc_processor_restore_var(zval *dst, const xc_entry_var_t *src, zend_class_entry **index_to_ce TSRMLS_DC)') dnl {{{
  107. {
  108. xc_processor_t processor;
  109. memset(&processor, 0, sizeof(processor));
  110. processor.handle_reference = src->have_references;
  111. if (processor.handle_reference) {
  112. zend_hash_init(&processor.zvalptrs, 0, NULL, NULL, 0);
  113. dnl fprintf(stderr, "mark[%p] = %p\n", src, dst);
  114. zend_hash_add(&processor.zvalptrs, (char *)src->value, sizeof(src->value), (void *) &dst, sizeof(dst), NULL);
  115. }
  116. processor.index_to_ce = index_to_ce;
  117. #ifdef ZEND_ENGINE_2
  118. if (src->objects_count) {
  119. zend_uint i;
  120. xc_vector_init(zend_object_handle, &processor.object_handles);
  121. xc_vector_reserve(&processor.object_handles, src->objects_count);
  122. for (i = 0; i < src->objects_count; ++i) {
  123. zend_object *object = emalloc(sizeof(*object));
  124. xc_vector_data(zend_object_handle, &processor.object_handles)[i] = zend_objects_store_put(object, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) zend_objects_free_object_storage, NULL TSRMLS_CC);
  125. xc_restore_zend_object(&processor, object, &src->objects[i] TSRMLS_CC);
  126. }
  127. }
  128. #endif
  129. xc_restore_zval(&processor, dst, src->value TSRMLS_CC);
  130. if (processor.handle_reference) {
  131. zend_hash_destroy(&processor.zvalptrs);
  132. }
  133. #ifdef ZEND_ENGINE_2
  134. if (src->objects_count) {
  135. zend_uint i;
  136. for (i = 0; i < src->objects_count; ++i) {
  137. zend_objects_store_del_ref_by_handle(xc_vector_data(zend_object_handle, &processor.object_handles)[i] TSRMLS_CC);
  138. }
  139. xc_vector_destroy(&processor.object_handles);
  140. }
  141. #endif
  142. return dst;
  143. }
  144. dnl }}}
  145. define(`DEFINE_RELOCATE_API', `
  146. /* src = readable element, before memcpy if any
  147. * dst = writable element, after memcpy if any
  148. * virtual_src = brother pointers relatived to this address, before relocation
  149. * virtual_dst = brother pointers relatived to this address, after relocation
  150. */
  151. EXPORTED_FUNCTION(`void xc_processor_relocate_$1($1 *dst, $1 *virtual_dst, $1 *src, $1 *virtual_src TSRMLS_DC)') dnl {{{
  152. {
  153. char *old_address = 0; /* unkown X used later */
  154. ptrdiff_t offset = ptrsub(old_address, (ptrdiff_t) virtual_src);
  155. /* diff to new_ptr */
  156. ptrdiff_t ptrdiff = ptrsub(dst, virtual_src);
  157. ptrdiff_t relocatediff = (ptrdiff_t) ptradd($1 *, virtual_dst, offset);
  158. xc_relocate_$1(dst, ptrdiff, relocatediff TSRMLS_CC);
  159. }
  160. dnl }}}
  161. ')
  162. DEFINE_RELOCATE_API(`xc_entry_var_t')
  163. DEFINE_RELOCATE_API(`xc_entry_php_t')
  164. DEFINE_RELOCATE_API(`xc_entry_data_php_t')
  165. EXPORTED(`#ifdef HAVE_XCACHE_DPRINT')
  166. EXPORTED_FUNCTION(`void xc_dprint(xc_entry_php_t *src, int indent TSRMLS_DC)') dnl {{{
  167. {
  168. IFDPRINT(`INDENT()`'fprintf(stderr, "xc_entry_php_t:src");')
  169. xc_dprint_xc_entry_php_t(src, indent TSRMLS_CC);
  170. }
  171. dnl }}}
  172. EXPORTED(`#endif')