return &p->val;
}
+static zend_always_inline zval *_zend_hash_str_add_or_update_i(HashTable *ht, const char *str, size_t len, zend_ulong h, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
+{
+ zend_string *key;
+ uint32_t nIndex;
+ uint32_t idx;
+ Bucket *p;
+
+ IS_CONSISTENT(ht);
+ HT_ASSERT_RC1(ht);
+
+ if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
+ CHECK_INIT(ht, 0);
+ goto add_to_hash;
+ } else if (ht->u.flags & HASH_FLAG_PACKED) {
+ zend_hash_packed_to_hash(ht);
+ } else if ((flag & HASH_ADD_NEW) == 0) {
+ p = zend_hash_str_find_bucket(ht, str, len, h);
+
+ if (p) {
+ zval *data;
+
+ if (flag & HASH_ADD) {
+ if (!(flag & HASH_UPDATE_INDIRECT)) {
+ return NULL;
+ }
+ ZEND_ASSERT(&p->val != pData);
+ data = &p->val;
+ if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ if (Z_TYPE_P(data) != IS_UNDEF) {
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
+ } else {
+ ZEND_ASSERT(&p->val != pData);
+ data = &p->val;
+ if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ }
+ }
+ if (ht->pDestructor) {
+ ht->pDestructor(data);
+ }
+ ZVAL_COPY_VALUE(data, pData);
+ return data;
+ }
+ }
+
+ ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
+
+add_to_hash:
+ idx = ht->nNumUsed++;
+ ht->nNumOfElements++;
+ if (ht->nInternalPointer == HT_INVALID_IDX) {
+ ht->nInternalPointer = idx;
+ }
+ zend_hash_iterators_update(ht, HT_INVALID_IDX, idx);
+ p = ht->arData + idx;
+ p->key = key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
+ p->h = ZSTR_H(key) = h;
+ ht->u.flags &= ~HASH_FLAG_STATIC_KEYS;
+ ZVAL_COPY_VALUE(&p->val, pData);
+ nIndex = h | ht->nTableMask;
+ Z_NEXT(p->val) = HT_HASH(ht, nIndex);
+ HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
+
+ return &p->val;
+}
+
ZEND_API zval* ZEND_FASTCALL _zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
return _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC);
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_or_update(HashTable *ht, const char *str, size_t len, zval *pData, uint32_t flag ZEND_FILE_LINE_DC)
{
- zend_string *key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC);
- zend_string_release(key);
- return ret;
+ zend_ulong h = zend_hash_func(str, len);
+
+ return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, flag ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
- zend_string *key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC);
- zend_string_release(key);
- return ret;
+ zend_ulong h = zend_hash_func(str, len);
+
+ return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update_ind(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
- zend_string *key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC);
- zend_string_release(key);
- return ret;
+ zend_ulong h = zend_hash_func(str, len);
+
+ return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
- zend_string *key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC);
- zend_string_release(key);
- return ret;
+ zend_ulong h = zend_hash_func(str, len);
+
+ return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData ZEND_FILE_LINE_DC)
{
- zend_string *key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
- zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
- zend_string_delref(key);
- return ret;
+ zend_ulong h = zend_hash_func(str, len);
+
+ return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC);
}
ZEND_API zval* ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h)