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/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.4 KiB

  1. dnl DEF_HASH_TABLE_FUNC(1:name, 2:datatype [, 3:dataname])
  2. define(`DEF_HASH_TABLE_FUNC', `DEF_STRUCT_P_FUNC(`HashTable', `$1', `
  3. pushdefFUNC_NAME(`$2', `$3')
  4. dnl {{{ dasm
  5. IFDASM(`
  6. const Bucket *srcBucket;
  7. zval *zv;
  8. int bufsize = 2;
  9. char *buf = emalloc(bufsize);
  10. int keysize;
  11. define(`AUTOCHECK_SKIP')
  12. IFAUTOCHECK(`xc_autocheck_skip = 1;')
  13. DISABLECHECK(`
  14. for (srcBucket = SRC(`pListHead'); srcBucket != NULL; srcBucket = srcBucket->pListNext) {
  15. ALLOC_INIT_ZVAL(zv);
  16. array_init(zv);
  17. FUNC_NAME (dasm, zv, (($2*)srcBucket->pData) TSRMLS_CC);
  18. keysize = BUCKET_KEY_SIZE(srcBucket) + 2;
  19. if (keysize > bufsize) {
  20. do {
  21. bufsize *= 2;
  22. } while (keysize > bufsize);
  23. buf = erealloc(buf, bufsize);
  24. }
  25. memcpy(buf, BUCKET_KEY_S(srcBucket), keysize - 2);
  26. buf[keysize - 2] = buf[keysize - 1] = ""[0];
  27. keysize = srcBucket->nKeyLength;
  28. #ifdef IS_UNICODE
  29. if (BUCKET_KEY_TYPE(srcBucket) == IS_UNICODE) {
  30. if (buf[0] == ""[0] && buf[1] == ""[0]) {
  31. keysize ++;
  32. }
  33. } else
  34. #endif
  35. {
  36. if (buf[0] == ""[0]) {
  37. keysize ++;
  38. }
  39. }
  40. add_u_assoc_zval_ex(dst, BUCKET_KEY_TYPE(srcBucket), ZSTR(buf), keysize, zv);
  41. }
  42. ')
  43. efree(buf);
  44. ', ` dnl IFDASM else
  45. dnl }}}
  46. Bucket *srcBucket;
  47. IFCOPY(`Bucket *first = NULL, *last = NULL;')
  48. IFRELOCATE(`Bucket *dstBucket = NULL;')
  49. IFRESTORE(`Bucket *dstBucket = NULL;')
  50. IFRELOCATE(`uint n;')
  51. IFRESTORE(`uint n;')
  52. IFCALCCOPY(`size_t bucketSize;')
  53. #if defined(HARDENING_PATCH_HASH_PROTECT) && HARDENING_PATCH_HASH_PROTECT
  54. IFRESTORE(`
  55. DST(`canary') = zend_hash_canary;
  56. DONE(canary)
  57. ', `
  58. PROCESS(unsigned int, canary)
  59. ')
  60. #endif
  61. PROCESS(uint, nTableSize)
  62. PROCESS(uint, nTableMask)
  63. PROCESS(uint, nNumOfElements)
  64. PROCESS(ulong, nNextFreeElement)
  65. IFCOPY(`DST(`pInternalPointer') = NULL; /* Used for element traversal */') DONE(pInternalPointer)
  66. #ifdef ZEND_ENGINE_2_4
  67. if (SRC(`nTableMask')) {
  68. #endif
  69. CALLOC(`DST(`arBuckets')', Bucket*, SRC(`nTableSize'))
  70. DONE(arBuckets)
  71. DISABLECHECK(`
  72. for (srcBucket = PTR_FROM_VIRTUAL_EX(`Bucket', SRC(`pListHead')); srcBucket != NULL; srcBucket = PTR_FROM_VIRTUAL_EX(`Bucket', `srcBucket->pListNext')) {
  73. IFCALCCOPY(`bucketSize = BUCKET_SIZE(srcBucket);')
  74. ALLOC(dstBucket, char, bucketSize, , Bucket)
  75. IFCOPY(`
  76. #ifdef ZEND_ENGINE_2_4
  77. memcpy(dstBucket, srcBucket, BUCKET_HEAD_SIZE(Bucket));
  78. if (BUCKET_KEY_SIZE(srcBucket)) {
  79. memcpy((char *) (dstBucket + 1), srcBucket->arKey, BUCKET_KEY_SIZE(srcBucket));
  80. dstBucket->arKey = (const char *) (dstBucket + 1);
  81. }
  82. else {
  83. dstBucket->arKey = NULL;
  84. }
  85. #else
  86. memcpy(dstBucket, srcBucket, bucketSize);
  87. #endif
  88. n = srcBucket->h & SRC(`nTableMask');
  89. /* dstBucket into hash node chain */
  90. dstBucket->pLast = NULL;
  91. dstBucket->pNext = DST(`arBuckets[n]');
  92. if (dstBucket->pNext) {
  93. dstBucket->pNext->pLast = dstBucket;
  94. }
  95. ')
  96. IFDPRINT(`
  97. INDENT()
  98. fprintf(stderr, "$2:\"");
  99. xc_dprint_str_len(BUCKET_KEY_S(srcBucket), BUCKET_KEY_SIZE(srcBucket));
  100. fprintf(stderr, "\" %d:h=%lu ", BUCKET_KEY_SIZE(srcBucket), srcBucket->h);
  101. ')
  102. if (sizeof(void *) == sizeof($2)) {
  103. IFCOPY(`dstBucket->pData = &dstBucket->pDataPtr;')
  104. IFRELOCATE(`srcBucket->pData = &srcBucket->pDataPtr;')
  105. dnl $6 = ` ' to skip alloc, skip pointer fix
  106. STRUCT_P_EX(`$2', dstBucket->pData, (($2*)srcBucket->pData), `', `$3', ` ')
  107. RELOCATE_EX(`$2', dstBucket->pData)
  108. }
  109. else {
  110. STRUCT_P_EX(`$2', dstBucket->pData, (($2*)srcBucket->pData), `', `$3')
  111. IFCOPY(`dstBucket->pDataPtr = NULL;')
  112. }
  113. IFCOPY(`
  114. if (!first) {
  115. first = dstBucket;
  116. }
  117. /* flat link */
  118. dstBucket->pListLast = last;
  119. dstBucket->pListNext = NULL;
  120. if (last) {
  121. last->pListNext = dstBucket;
  122. }
  123. last = dstBucket;
  124. n = srcBucket->h & SRC(`nTableMask');
  125. /* dstBucket into hash node chain */
  126. dstBucket->pLast = NULL;
  127. dstBucket->pNext = DST(`arBuckets[n]');
  128. if (dstBucket->pNext) {
  129. dstBucket->pNext->pLast = dstBucket;
  130. }
  131. DST(`arBuckets[n]') = dstBucket;
  132. ')
  133. }
  134. ') dnl DISABLECHECK
  135. IFCOPY(`DST(`pListHead') = first;') DONE(pListHead)
  136. IFCOPY(`DST(`pListTail') = dstBucket;') DONE(pListTail)
  137. IFRELOCATE(`
  138. for (n = 0; n < SRC(`nTableSize'); ++n) {
  139. if (SRC(`arBuckets[n]')) {
  140. Bucket *next = PTR_FROM_VIRTUAL_EX(`Bucket', `DST(`arBuckets[n]')');
  141. do {
  142. dstBucket = next;
  143. next = PTR_FROM_VIRTUAL_EX(`Bucket', `next->pNext');
  144. if (dstBucket->pListLast) {
  145. RELOCATE_EX(Bucket, dstBucket->pListLast)
  146. }
  147. if (dstBucket->pListNext) {
  148. RELOCATE_EX(Bucket, dstBucket->pListNext)
  149. }
  150. if (dstBucket->pNext) {
  151. RELOCATE_EX(Bucket, dstBucket->pNext)
  152. }
  153. if (dstBucket->pLast) {
  154. RELOCATE_EX(Bucket, dstBucket->pLast)
  155. }
  156. } while (next);
  157. RELOCATE(Bucket, arBuckets[n])
  158. }
  159. }
  160. ')
  161. if (SRC(`nNumOfElements')) {
  162. RELOCATE(Bucket, pListHead)
  163. RELOCATE(Bucket, pListTail)
  164. }
  165. RELOCATE(Bucket *, arBuckets)
  166. #ifdef ZEND_ENGINE_2_4
  167. }
  168. else { /* if (SRC(`nTableMask')) */
  169. IFCOPY(`DST(`pListHead') = NULL;') DONE(pListHead)
  170. IFCOPY(`DST(`pListTail') = NULL;') DONE(pListTail)
  171. DONE(arBuckets)
  172. }
  173. #endif
  174. IFCOPY(`DST(`pDestructor') = SRC(`pDestructor');') DONE(pDestructor)
  175. PROCESS(zend_bool, persistent)
  176. #ifdef IS_UNICODE
  177. PROCESS(zend_bool, unicode)
  178. #endif
  179. PROCESS(unsigned char, nApplyCount)
  180. PROCESS(zend_bool, bApplyProtection)
  181. #if ZEND_DEBUG
  182. PROCESS(int, inconsistent)
  183. #endif
  184. ')dnl IFDASM
  185. popdef(`FUNC_NAME')
  186. ')')