Annotation of embedaddon/php/Zend/zend_string.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | Zend Engine |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 2.00 of the Zend 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.zend.com/license/2_00.txt. |
! 11: | If you did not receive a copy of the Zend license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@zend.com so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Authors: Dmitry Stogov <dmitry@zend.com> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: $ */
! 20:
! 21: #include "zend.h"
! 22: #include "zend_globals.h"
! 23:
! 24: #ifndef ZEND_DEBUG_INTERNED_STRINGS
! 25: # define ZEND_DEBUG_INTERNED_STRINGS 0
! 26: #endif
! 27:
! 28: #if ZEND_DEBUG_INTERNED_STRINGS
! 29: # include <sys/mman.h>
! 30: #endif
! 31:
! 32: ZEND_API const char *(*zend_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
! 33: ZEND_API void (*zend_interned_strings_snapshot)(TSRMLS_D);
! 34: ZEND_API void (*zend_interned_strings_restore)(TSRMLS_D);
! 35:
! 36: static const char *zend_new_interned_string_int(const char *str, int len, int free_src TSRMLS_DC);
! 37: static void zend_interned_strings_snapshot_int(TSRMLS_D);
! 38: static void zend_interned_strings_restore_int(TSRMLS_D);
! 39:
! 40: void zend_interned_strings_init(TSRMLS_D)
! 41: {
! 42: #ifndef ZTS
! 43: size_t size = 1024 * 1024;
! 44:
! 45: #if ZEND_DEBUG_INTERNED_STRINGS
! 46: CG(interned_strings_start) = valloc(size);
! 47: #else
! 48: CG(interned_strings_start) = malloc(size);
! 49: #endif
! 50:
! 51: CG(interned_strings_top) = CG(interned_strings_start);
! 52: CG(interned_strings_snapshot_top) = CG(interned_strings_start);
! 53: CG(interned_strings_end) = CG(interned_strings_start) + size;
! 54:
! 55: zend_hash_init(&CG(interned_strings), 0, NULL, NULL, 1);
! 56:
! 57: CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
! 58: CG(interned_strings).arBuckets = (Bucket **) pecalloc(CG(interned_strings).nTableSize, sizeof(Bucket *), CG(interned_strings).persistent);
! 59:
! 60: #if ZEND_DEBUG_INTERNED_STRINGS
! 61: mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
! 62: #endif
! 63:
! 64: #endif
! 65:
! 66: zend_new_interned_string = zend_new_interned_string_int;
! 67: zend_interned_strings_snapshot = zend_interned_strings_snapshot_int;
! 68: zend_interned_strings_restore = zend_interned_strings_restore_int;
! 69: }
! 70:
! 71: void zend_interned_strings_dtor(TSRMLS_D)
! 72: {
! 73: #ifndef ZTS
! 74: #if ZEND_DEBUG_INTERNED_STRINGS
! 75: mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
! 76: #endif
! 77: free(CG(interned_strings).arBuckets);
! 78: free(CG(interned_strings_start));
! 79: #endif
! 80: }
! 81:
! 82: static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
! 83: {
! 84: #ifndef ZTS
! 85: ulong h;
! 86: uint nIndex;
! 87: Bucket *p;
! 88:
! 89: if (IS_INTERNED(arKey)) {
! 90: return arKey;
! 91: }
! 92:
! 93: h = zend_inline_hash_func(arKey, nKeyLength);
! 94: nIndex = h & CG(interned_strings).nTableMask;
! 95: p = CG(interned_strings).arBuckets[nIndex];
! 96: while (p != NULL) {
! 97: if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
! 98: if (!memcmp(p->arKey, arKey, nKeyLength)) {
! 99: if (free_src) {
! 100: efree((void *)arKey);
! 101: }
! 102: return p->arKey;
! 103: }
! 104: }
! 105: p = p->pNext;
! 106: }
! 107:
! 108: if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
! 109: CG(interned_strings_end)) {
! 110: /* no memory */
! 111: return arKey;
! 112: }
! 113:
! 114: p = (Bucket *) CG(interned_strings_top);
! 115: CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
! 116:
! 117: #if ZEND_DEBUG_INTERNED_STRINGS
! 118: mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
! 119: #endif
! 120:
! 121: p->arKey = (char*)(p+1);
! 122: memcpy((char*)p->arKey, arKey, nKeyLength);
! 123: if (free_src) {
! 124: efree((void *)arKey);
! 125: }
! 126: p->nKeyLength = nKeyLength;
! 127: p->h = h;
! 128: p->pData = &p->pDataPtr;
! 129: p->pDataPtr = p;
! 130:
! 131: p->pNext = CG(interned_strings).arBuckets[nIndex];
! 132: p->pLast = NULL;
! 133: if (p->pNext) {
! 134: p->pNext->pLast = p;
! 135: }
! 136:
! 137: HANDLE_BLOCK_INTERRUPTIONS();
! 138:
! 139: p->pListLast = CG(interned_strings).pListTail;
! 140: CG(interned_strings).pListTail = p;
! 141: p->pListNext = NULL;
! 142: if (p->pListLast != NULL) {
! 143: p->pListLast->pListNext = p;
! 144: }
! 145: if (!CG(interned_strings).pListHead) {
! 146: CG(interned_strings).pListHead = p;
! 147: }
! 148:
! 149: CG(interned_strings).arBuckets[nIndex] = p;
! 150:
! 151: HANDLE_UNBLOCK_INTERRUPTIONS();
! 152:
! 153: CG(interned_strings).nNumOfElements++;
! 154:
! 155: if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
! 156: if ((CG(interned_strings).nTableSize << 1) > 0) { /* Let's double the table size */
! 157: Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);
! 158:
! 159: if (t) {
! 160: HANDLE_BLOCK_INTERRUPTIONS();
! 161: CG(interned_strings).arBuckets = t;
! 162: CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
! 163: CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
! 164: zend_hash_rehash(&CG(interned_strings));
! 165: HANDLE_UNBLOCK_INTERRUPTIONS();
! 166: }
! 167: }
! 168: }
! 169:
! 170: #if ZEND_DEBUG_INTERNED_STRINGS
! 171: mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
! 172: #endif
! 173:
! 174: return p->arKey;
! 175: #else
! 176: return arKey;
! 177: #endif
! 178: }
! 179:
! 180: static void zend_interned_strings_snapshot_int(TSRMLS_D)
! 181: {
! 182: CG(interned_strings_snapshot_top) = CG(interned_strings_top);
! 183: }
! 184:
! 185: static void zend_interned_strings_restore_int(TSRMLS_D)
! 186: {
! 187: #ifndef ZTS
! 188: Bucket *p;
! 189: int i;
! 190: #endif
! 191:
! 192: CG(interned_strings_top) = CG(interned_strings_snapshot_top);
! 193:
! 194: #ifndef ZTS
! 195: #if ZEND_DEBUG_INTERNED_STRINGS
! 196: mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_WRITE | PROT_READ);
! 197: #endif
! 198:
! 199: for (i = 0; i < CG(interned_strings).nTableSize; i++) {
! 200: p = CG(interned_strings).arBuckets[i];
! 201: while (p && p->arKey > CG(interned_strings_top)) {
! 202: CG(interned_strings).nNumOfElements--;
! 203: if (p->pListLast != NULL) {
! 204: p->pListLast->pListNext = p->pListNext;
! 205: } else {
! 206: CG(interned_strings).pListHead = p->pListNext;
! 207: }
! 208: if (p->pListNext != NULL) {
! 209: p->pListNext->pListLast = p->pListLast;
! 210: } else {
! 211: CG(interned_strings).pListTail = p->pListLast;
! 212: }
! 213: p = p->pNext;
! 214: }
! 215: if (p) {
! 216: p->pLast = NULL;
! 217: }
! 218: CG(interned_strings).arBuckets[i] = p;
! 219: }
! 220:
! 221: #if ZEND_DEBUG_INTERNED_STRINGS
! 222: mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
! 223: #endif
! 224: #endif
! 225: }
! 226:
! 227: /*
! 228: * Local variables:
! 229: * tab-width: 4
! 230: * c-basic-offset: 4
! 231: * indent-tabs-mode: t
! 232: * End:
! 233: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>