diff options
-rw-r--r-- | ext/opcache/ZendAccelerator.c | 13 | ||||
-rw-r--r-- | ext/opcache/ZendAccelerator.h | 2 | ||||
-rw-r--r-- | ext/opcache/zend_persist.c | 36 | ||||
-rw-r--r-- | ext/opcache/zend_persist.h | 2 |
4 files changed, 44 insertions, 9 deletions
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 11b2c4ea77..d983d4c056 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1235,8 +1235,8 @@ static zend_persistent_script *store_script_in_file_cache(zend_persistent_script ZCG(mem) = zend_arena_alloc(&CG(arena), memory_used); #endif - /* Copy into shared memory */ - new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0); + /* Copy into memory block */ + new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0, 0); zend_shared_alloc_destroy_xlat_table(); @@ -1355,7 +1355,7 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr } /* Copy into shared memory */ - new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length); + new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length, 1); zend_shared_alloc_destroy_xlat_table(); @@ -2526,6 +2526,8 @@ static inline int accel_find_sapi(void) static int zend_accel_init_shm(void) { + int i; + zend_shared_alloc_lock(); accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals)); @@ -2589,6 +2591,11 @@ static int zend_accel_init_shm(void) ZCSG(last_restart_time) = 0; ZCSG(restart_in_progress) = 0; + + for (i = 0; i < -HT_MIN_MASK; i++) { + ZCSG(uninitialized_bucket)[i] = HT_INVALID_IDX; + } + zend_shared_alloc_unlock(); return SUCCESS; diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index d0f69d6b7c..a1db3ee7a5 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -283,6 +283,8 @@ typedef struct _zend_accel_shared_globals { char *interned_strings_end; char *interned_strings_saved_top; HashTable interned_strings; + /* uninitialized HashTable Support */ + uint32_t uninitialized_bucket[-HT_MIN_MASK]; } zend_accel_shared_globals; extern zend_bool accel_startup_ok; diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 3e55331313..830b3883c8 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -89,13 +89,21 @@ static void zend_hash_persist(HashTable *ht, zend_persist_func_t pPersistElement ht->pDestructor = NULL; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { - HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) { + HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket)); + } else { + HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + } return; } if (ht->nNumUsed == 0) { efree(HT_GET_DATA_ADDR(ht)); ht->nTableMask = HT_MIN_MASK; - HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) { + HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket)); + } else { + HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + } ht->u.flags &= ~HASH_FLAG_INITIALIZED; return; } @@ -175,13 +183,21 @@ static void zend_hash_persist_immutable(HashTable *ht) ht->pDestructor = NULL; if (!(ht->u.flags & HASH_FLAG_INITIALIZED)) { - HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) { + HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket)); + } else { + HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + } return; } if (ht->nNumUsed == 0) { efree(HT_GET_DATA_ADDR(ht)); ht->nTableMask = HT_MIN_MASK; - HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + if (EXPECTED(!ZCG(current_persistent_script)->corrupted)) { + HT_SET_DATA_ADDR(ht, &ZCSG(uninitialized_bucket)); + } else { + HT_SET_DATA_ADDR(ht, &uninitialized_bucket); + } ht->u.flags &= ~HASH_FLAG_INITIALIZED; return; } @@ -833,9 +849,16 @@ static void zend_accel_persist_class_table(HashTable *class_table) zend_hash_apply(class_table, (apply_func_t) zend_update_parent_ce); } -zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length) +zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length, int for_shm) { script->mem = ZCG(mem); + script->corrupted = 0; + ZCG(current_persistent_script) = script; + + if (!for_shm) { + /* script is not going to be saved in SHM */ + script->corrupted = 1; + } ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */ zend_shared_alloc_clear_xlat_table(); @@ -860,6 +883,9 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script zend_hash_persist(&script->script.function_table, zend_persist_op_array); zend_persist_op_array_ex(&script->script.main_op_array, script); + script->corrupted = 0; + ZCG(current_persistent_script) = NULL; + return script; } diff --git a/ext/opcache/zend_persist.h b/ext/opcache/zend_persist.h index 67561882a6..166c08fd13 100644 --- a/ext/opcache/zend_persist.h +++ b/ext/opcache/zend_persist.h @@ -24,6 +24,6 @@ int zend_accel_script_persistable(zend_persistent_script *script); uint zend_accel_script_persist_calc(zend_persistent_script *script, char *key, unsigned int key_length, int for_shm); -zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length); +zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length, int for_shm); #endif /* ZEND_PERSIST_H */ |