Beispiel #1
0
/* HashTable容量满了的时候重新分配大小 */
static int zend_hash_do_resize(HashTable *ht)
{
	Bucket **t;
#ifdef ZEND_SIGNALS
	TSRMLS_FETCH();
#endif

	IS_CONSISTENT(ht);

	if ((ht->nTableSize << 1) > 0) { /* Let's double the table size */
		/* 重新分配大小 */
		t = (Bucket **)perealloc_recoverable(
		    ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *),
		    ht->persistent);
		if (t) {
			HANDLE_BLOCK_INTERRUPTIONS();
			ht->arBuckets = t;
			/* 设置nTableSize */
			ht->nTableSize = (ht->nTableSize << 1);
			/* nTableMask随着nTableSize改变,永远是nTableSize-1 */
			ht->nTableMask = ht->nTableSize - 1;
			/* 修改HashTable大小之后需要重新哈希 */
			zend_hash_rehash(ht);
			HANDLE_UNBLOCK_INTERRUPTIONS();
			return SUCCESS;
		}
		return FAILURE;
	}
	return SUCCESS;
}
Beispiel #2
0
static int zend_hash_do_resize(HashTable *ht)
{
	Bucket **t;

	IS_CONSISTENT(ht);

	if ((ht->nTableSize << 1) > 0) {	/* Let's double the table size */
		t = (Bucket **) perealloc_recoverable(ht->arBuckets, (ht->nTableSize << 1) * sizeof(Bucket *), ht->persistent);
		if (t) {
			HANDLE_BLOCK_INTERRUPTIONS();
			ht->arBuckets = t;
			ht->nTableSize = (ht->nTableSize << 1);
			ht->nTableMask = ht->nTableSize - 1;
			zend_hash_rehash(ht);
			HANDLE_UNBLOCK_INTERRUPTIONS();
#if DEBUG_RESIZE
			asm("int3");
			printf("#%d resized %d\n", ++resizes, ht->nTableSize);
#endif
			return SUCCESS;
		}
		return FAILURE;
	}
	return SUCCESS;
}
Beispiel #3
0
static const char *zend_new_interned_string_int(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
{
#ifndef ZTS
	ulong h;
	uint nIndex;
	Bucket *p;

	if (IS_INTERNED(arKey)) {
		return arKey;
	}

	h = zend_inline_hash_func(arKey, nKeyLength);
	nIndex = h & CG(interned_strings).nTableMask;
	p = CG(interned_strings).arBuckets[nIndex];
	while (p != NULL) {
		if ((p->h == h) && (p->nKeyLength == nKeyLength)) {
			if (!memcmp(p->arKey, arKey, nKeyLength)) {
				if (free_src) {
					efree((void *)arKey);
				}
				return p->arKey;
			}
		}
		p = p->pNext;
	}
	
	if (CG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
	    CG(interned_strings_end)) {
	    /* no memory */
		return arKey;
	}

	p = (Bucket *) CG(interned_strings_top);
	CG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);

#if ZEND_DEBUG_INTERNED_STRINGS
	mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ | PROT_WRITE);
#endif
	
	p->arKey = (char*)(p+1);
	memcpy((char*)p->arKey, arKey, nKeyLength);
	if (free_src) {
		efree((void *)arKey);
	}
	p->nKeyLength = nKeyLength;
	p->h = h;
	p->pData = &p->pDataPtr;
	p->pDataPtr = p;
	
	p->pNext = CG(interned_strings).arBuckets[nIndex];
	p->pLast = NULL;
	if (p->pNext) {
		p->pNext->pLast = p;
	}

	HANDLE_BLOCK_INTERRUPTIONS();
	
	p->pListLast = CG(interned_strings).pListTail;
	CG(interned_strings).pListTail = p;
	p->pListNext = NULL;
	if (p->pListLast != NULL) {
		p->pListLast->pListNext = p;
	}
	if (!CG(interned_strings).pListHead) {
		CG(interned_strings).pListHead = p;
	}

	CG(interned_strings).arBuckets[nIndex] = p;

	HANDLE_UNBLOCK_INTERRUPTIONS();

	CG(interned_strings).nNumOfElements++;

	if (CG(interned_strings).nNumOfElements > CG(interned_strings).nTableSize) {
		if ((CG(interned_strings).nTableSize << 1) > 0) {	/* Let's double the table size */
			Bucket **t = (Bucket **) perealloc_recoverable(CG(interned_strings).arBuckets, (CG(interned_strings).nTableSize << 1) * sizeof(Bucket *), CG(interned_strings).persistent);

			if (t) {
				HANDLE_BLOCK_INTERRUPTIONS();
				CG(interned_strings).arBuckets = t;
				CG(interned_strings).nTableSize = (CG(interned_strings).nTableSize << 1);
				CG(interned_strings).nTableMask = CG(interned_strings).nTableSize - 1;
				zend_hash_rehash(&CG(interned_strings));
				HANDLE_UNBLOCK_INTERRUPTIONS();
			}
		}
	}

#if ZEND_DEBUG_INTERNED_STRINGS
	mprotect(CG(interned_strings_start), CG(interned_strings_end) - CG(interned_strings_start), PROT_READ);
#endif

	return p->arKey;
#else
	return arKey;
#endif
}