Skip to content

Commit 179e60e

Browse files
authored
Fix assumptions around interned strings on PHP 7.3 (#3224)
Additionally we always intern the zai config value zval on PHP 7.3+. Not interning these zvals leads to unncessary string value duplication. Signed-off-by: Bob Weinand <bob.weinand@datadoghq.com>
1 parent bd41c09 commit 179e60e

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

zend_abstract_interface/config/config.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,13 +139,20 @@ static void zai_config_entries_init(zai_config_entry entries[], zai_config_id en
139139
}
140140
}
141141

142+
#if PHP_VERSION_ID >= 70300 && PHP_VERSION_ID < 70400
143+
zend_new_interned_string_func_t zai_persistent_new_interned_string;
144+
#endif
145+
142146
bool zai_config_minit(zai_config_entry entries[], size_t entries_count, zai_config_env_to_ini_name env_to_ini,
143147
int module_number) {
144148
if (!entries || !entries_count) return false;
145149
if (!zai_json_setup_bindings()) return false;
146150
zai_config_entries_init(entries, entries_count);
147151
zai_config_ini_minit(env_to_ini, module_number);
148152
zai_config_stable_file_minit();
153+
#if PHP_VERSION_ID >= 70300 && PHP_VERSION_ID < 70400
154+
zai_persistent_new_interned_string = zend_new_interned_string;
155+
#endif
149156
return true;
150157
}
151158

@@ -176,6 +183,8 @@ static void zai_config_intern_zval(zval *pzval) {
176183
if (Z_TYPE_P(pzval) == IS_STRING) {
177184
#if PHP_VERSION_ID >= 70400
178185
ZVAL_INTERNED_STR(pzval, zend_new_interned_string(Z_STR_P(pzval)));
186+
#elif PHP_VERSION_ID >= 70300
187+
ZVAL_INTERNED_STR(pzval, zai_persistent_new_interned_string(Z_STR_P(pzval)));
179188
#else
180189
GC_ADD_FLAGS(Z_STR_P(pzval), IS_STR_INTERNED);
181190
Z_TYPE_INFO_P(pzval) = IS_INTERNED_STRING_EX;
@@ -206,6 +215,8 @@ static void zai_config_intern_zval(zval *pzval) {
206215
if (bucket->key) {
207216
#if PHP_VERSION_ID >= 70400
208217
bucket->key = zend_new_interned_string(bucket->key);
218+
#elif PHP_VERSION_ID >= 70300
219+
bucket->key = zai_persistent_new_interned_string(bucket->key);
209220
#else
210221
GC_ADD_FLAGS(bucket->key, IS_STR_INTERNED);
211222
#endif
@@ -217,18 +228,25 @@ static void zai_config_intern_zval(zval *pzval) {
217228
}
218229

219230
void zai_config_first_time_rinit(bool in_request) {
231+
// On PHP 7.3 zend_interned_strings_switch_storage has undesired side effects (it calls interned_string_copy_storage); hence we collect zend_new_interned_string_permanent via zai_persistent_new_interned_string at minit.
220232
#if PHP_VERSION_ID >= 70400
221233
if (in_request) {
222234
zend_interned_strings_switch_storage(0);
223235
}
236+
#else
237+
(void)in_request;
224238
#endif
225239

226240
for (uint16_t i = 0; i < zai_config_memoized_entries_count; i++) {
227241
zai_config_memoized_entry *memoized = &zai_config_memoized_entries[i];
228242
zai_config_find_and_set_value(memoized, i);
243+
#if PHP_VERSION_ID >= 70300
244+
zai_config_intern_zval(&memoized->decoded_value);
245+
#else
229246
if (in_request) {
230247
zai_config_intern_zval(&memoized->decoded_value);
231248
}
249+
#endif
232250
}
233251

234252
#if PHP_VERSION_ID >= 70400

0 commit comments

Comments
 (0)