Revert HASH_FLAG_INITIALIZED into HASH_FLAG_UNINITIALIZED.

This commit is contained in:
Dmitry Stogov 2018-12-28 11:22:18 +03:00
parent c706adaaab
commit 76d8f3923e
7 changed files with 58 additions and 49 deletions

View File

@ -12,6 +12,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES
i. php_fgetcsv() and php_fputcsv()
j. Removed add_get_assoc_*() and add_get_index_*()
k. Class declaration opcodes
l. HASH_FLAG_INITIALIZED
2. Build system changes
a. Abstract
@ -153,6 +154,10 @@ PHP 7.4 INTERNALS UPGRADE NOTES
actual linked performed by ZEND_DECLARE_...CLASS... opcode(s).
Linked classes have ZEND_ACC_LINKED flag set.
l. HASH_FLAG_INITIALIZED was reverted into HASH_FLAG_UNINITIALIZED.
Special HT_IS_INITIALIZED() and HT_INVALIDATE() macro were introduced
to hide implementation details.
========================
2. Build system changes
========================

View File

@ -129,7 +129,7 @@ static zend_always_inline void zend_hash_real_init_packed_ex(HashTable *ht)
data = emalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK));
}
HT_SET_DATA_ADDR(ht, data);
HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
HT_FLAGS(ht) = HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS;
HT_HASH_RESET_PACKED(ht);
}
@ -144,7 +144,7 @@ static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht)
data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_SIZE_TO_MASK(HT_MIN_SIZE)));
ht->nTableMask = HT_SIZE_TO_MASK(HT_MIN_SIZE);
HT_SET_DATA_ADDR(ht, data);
HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED;
HT_FLAGS(ht) = HASH_FLAG_STATIC_KEYS;
#ifdef __SSE2__
do {
__m128i xmm0 = _mm_setzero_si128();
@ -178,14 +178,14 @@ static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht)
}
ht->nTableMask = HT_SIZE_TO_MASK(nSize);
HT_SET_DATA_ADDR(ht, data);
HT_FLAGS(ht) |= HASH_FLAG_INITIALIZED;
HT_FLAGS(ht) = HASH_FLAG_STATIC_KEYS;
HT_HASH_RESET(ht);
}
static zend_always_inline void zend_hash_real_init_ex(HashTable *ht, int packed)
{
HT_ASSERT_RC1(ht);
ZEND_ASSERT(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED));
ZEND_ASSERT(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED);
if (packed) {
zend_hash_real_init_packed_ex(ht);
} else {
@ -199,7 +199,7 @@ static const uint32_t uninitialized_bucket[-HT_MIN_MASK] =
ZEND_API const HashTable zend_empty_array = {
.gc.refcount = 2,
.gc.u.type_info = IS_ARRAY | (GC_IMMUTABLE << GC_FLAGS_SHIFT),
.u.flags = HASH_FLAG_STATIC_KEYS,
.u.flags = HASH_FLAG_UNINITIALIZED,
.nTableMask = HT_MIN_MASK,
.arData = (Bucket*)&uninitialized_bucket[2],
.nNumUsed = 0,
@ -214,7 +214,7 @@ static zend_always_inline void _zend_hash_init_int(HashTable *ht, uint32_t nSize
{
GC_SET_REFCOUNT(ht, 1);
GC_TYPE_INFO(ht) = IS_ARRAY | (persistent ? (GC_PERSISTENT << GC_FLAGS_SHIFT) : (GC_COLLECTABLE << GC_FLAGS_SHIFT));
HT_FLAGS(ht) = HASH_FLAG_STATIC_KEYS;
HT_FLAGS(ht) = HASH_FLAG_UNINITIALIZED;
ht->nTableMask = HT_MIN_MASK;
HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
ht->nNumUsed = 0;
@ -313,7 +313,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, zend
{
HT_ASSERT_RC1(ht);
if (nSize == 0) return;
if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
if (UNEXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
if (nSize > ht->nTableSize) {
ht->nTableSize = zend_hash_check_size(nSize);
}
@ -680,7 +680,8 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
IS_CONSISTENT(ht);
HT_ASSERT_RC1(ht);
if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
if (UNEXPECTED(HT_FLAGS(ht) & (HASH_FLAG_UNINITIALIZED|HASH_FLAG_PACKED))) {
if (EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
zend_hash_real_init_mixed(ht);
if (!ZSTR_IS_INTERNED(key)) {
zend_string_addref(key);
@ -688,13 +689,14 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
zend_string_hash_val(key);
}
goto add_to_hash;
} else if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
} else {
zend_hash_packed_to_hash(ht);
if (!ZSTR_IS_INTERNED(key)) {
zend_string_addref(key);
HT_FLAGS(ht) &= ~HASH_FLAG_STATIC_KEYS;
zend_string_hash_val(key);
}
}
} else if ((flag & HASH_ADD_NEW) == 0) {
p = zend_hash_find_bucket(ht, key, 0);
@ -765,11 +767,13 @@ static zend_always_inline zval *_zend_hash_str_add_or_update_i(HashTable *ht, co
IS_CONSISTENT(ht);
HT_ASSERT_RC1(ht);
if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
if (UNEXPECTED(HT_FLAGS(ht) & (HASH_FLAG_UNINITIALIZED|HASH_FLAG_PACKED))) {
if (EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
zend_hash_real_init_mixed(ht);
goto add_to_hash;
} else if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
} else {
zend_hash_packed_to_hash(ht);
}
} else if ((flag & HASH_ADD_NEW) == 0) {
p = zend_hash_str_find_bucket(ht, str, len, h);
@ -973,7 +977,7 @@ add_to_packed:
convert_to_hash:
zend_hash_packed_to_hash(ht);
}
} else if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
} else if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
if (h < ht->nTableSize) {
zend_hash_real_init_packed_ex(ht);
goto add_to_packed;
@ -1142,7 +1146,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
IS_CONSISTENT(ht);
if (UNEXPECTED(ht->nNumOfElements == 0)) {
if (HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) {
if (!(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
ht->nNumUsed = 0;
HT_HASH_RESET(ht);
}
@ -1537,7 +1541,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
}
}
zend_hash_iterators_remove(ht);
} else if (EXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
} else if (EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
return;
}
pefree(HT_GET_DATA_ADDR(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
@ -1588,7 +1592,7 @@ ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
}
zend_hash_iterators_remove(ht);
SET_INCONSISTENT(HT_DESTROYED);
} else if (EXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
} else if (EXPECTED(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
goto free_ht;
}
efree(HT_GET_DATA_ADDR(ht));
@ -1717,7 +1721,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_graceful_destroy(HashTable *ht)
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
_zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
}
if (HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) {
if (!(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
pefree(HT_GET_DATA_ADDR(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
}
@ -1741,7 +1745,7 @@ ZEND_API void ZEND_FASTCALL zend_hash_graceful_reverse_destroy(HashTable *ht)
_zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
}
if (HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) {
if (!(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED)) {
pefree(HT_GET_DATA_ADDR(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
}
@ -2010,7 +2014,7 @@ ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source)
target->pDestructor = ZVAL_PTR_DTOR;
if (source->nNumOfElements == 0) {
HT_FLAGS(target) = (HT_FLAGS(source) & ~(HASH_FLAG_INITIALIZED|HASH_FLAG_PACKED)) | HASH_FLAG_STATIC_KEYS;
HT_FLAGS(target) = HASH_FLAG_UNINITIALIZED;
target->nTableMask = HT_MIN_MASK;
target->nNumUsed = 0;
target->nNumOfElements = 0;

View File

@ -35,7 +35,7 @@
#define HASH_FLAG_CONSISTENCY ((1<<0) | (1<<1))
#define HASH_FLAG_PACKED (1<<2)
#define HASH_FLAG_INITIALIZED (1<<3)
#define HASH_FLAG_UNINITIALIZED (1<<3)
#define HASH_FLAG_STATIC_KEYS (1<<4) /* long and interned strings */
#define HASH_FLAG_HAS_EMPTY_IND (1<<5)
#define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6)
@ -43,11 +43,11 @@
#define HT_FLAGS(ht) (ht)->u.flags
#define HT_INVALIDATE(ht) do { \
HT_FLAGS(ht) = 0; \
HT_FLAGS(ht) = HASH_FLAG_UNINITIALIZED; \
} while (0)
#define HT_IS_INITIALIZED(ht) \
((HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) != 0)
((HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) == 0)
#define HT_IS_PACKED(ht) \
((HT_FLAGS(ht) & HASH_FLAG_PACKED) != 0)

View File

@ -143,7 +143,7 @@ static void zend_hash_clone_constants(HashTable *ht)
Bucket *p, *end;
zend_class_constant *c;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
return;
}
@ -174,7 +174,7 @@ static void zend_hash_clone_methods(HashTable *ht)
ht->pDestructor = ZEND_FUNCTION_DTOR;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
return;
}
@ -212,7 +212,7 @@ static void zend_hash_clone_prop_info(HashTable *ht)
Bucket *p, *end;
zend_property_info *prop_info;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
return;
}

View File

@ -272,7 +272,7 @@ static void zend_file_cache_serialize_hash(HashTable *ht,
{
Bucket *p, *end;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
ht->arData = NULL;
return;
}
@ -965,7 +965,7 @@ static void zend_file_cache_unserialize_hash(HashTable *ht,
Bucket *p, *end;
ht->pDestructor = dtor;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
if (EXPECTED(!file_cache_only)) {
HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
} else {

View File

@ -94,7 +94,7 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement
ht->pDestructor = NULL;
ht->nInternalPointer = 0;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
} else {
@ -110,7 +110,7 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement
} else {
HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
}
HT_FLAGS(ht) &= ~HASH_FLAG_INITIALIZED;
HT_FLAGS(ht) |= HASH_FLAG_UNINITIALIZED;
return;
}
if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
@ -189,7 +189,7 @@ static void zend_hash_persist_immutable(HashTable *ht)
HT_FLAGS(ht) |= HASH_FLAG_STATIC_KEYS;
ht->pDestructor = NULL;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) {
if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) {
HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket));
} else {
@ -205,7 +205,7 @@ static void zend_hash_persist_immutable(HashTable *ht)
} else {
HT_SET_DATA_ADDR(ht, &uninitialized_bucket);
}
HT_FLAGS(ht) &= ~HASH_FLAG_INITIALIZED;
HT_FLAGS(ht) |= HASH_FLAG_UNINITIALIZED;
return;
}
if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
@ -806,7 +806,7 @@ static void zend_persist_class_entry(zval *zv)
zend_accel_store_interned_string(ce->parent_name);
}
zend_hash_persist(&ce->function_table, zend_persist_class_method);
HT_FLAGS(&ce->function_table) &= (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS);
HT_FLAGS(&ce->function_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS);
if (ce->default_properties_table) {
int i;
@ -835,7 +835,7 @@ static void zend_persist_class_entry(zval *zv)
}
zend_hash_persist(&ce->constants_table, zend_persist_class_constant);
HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS);
HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS);
if (ce->info.user.filename) {
/* do not free! PHP has centralized filename storage, compiler will free it */
@ -853,7 +853,7 @@ static void zend_persist_class_entry(zval *zv)
}
}
zend_hash_persist(&ce->properties_info, zend_persist_property_info);
HT_FLAGS(&ce->properties_info) &= (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS);
HT_FLAGS(&ce->properties_info) &= (HASH_FLAG_UNINITIALIZED | HASH_FLAG_STATIC_KEYS);
if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_LINKED)) {
uint32_t i = 0;

View File

@ -60,7 +60,7 @@ static void zend_hash_persist_calc(HashTable *ht, void (*pPersistElement)(zval *
uint32_t idx;
Bucket *p;
if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) || ht->nNumUsed == 0) {
if ((HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) || ht->nNumUsed == 0) {
return;
}