@@ -54,6 +54,14 @@ get_key_with_optional_prefix(simdjson::dom::element &doc, std::string_view json_
5454 return doc.at_pointer (std_pointer);
5555}
5656
57+ static zend_always_inline zend_string* simdjson_string_init (const char * buf, const size_t len) {
58+ zend_string *str = zend_string_init (buf, len, 0 );
59+ #ifdef IS_STR_VALID_UTF8
60+ GC_ADD_FLAGS (str, IS_STR_VALID_UTF8); // JSON string must be always valid UTF-8 string
61+ #endif
62+ return str;
63+ }
64+
5765static simdjson::error_code
5866build_parsed_json_cust (simdjson_php_parser* parser, simdjson::dom::element &doc, const char *buf, size_t len, bool realloc_if_needed,
5967 size_t depth = simdjson::DEFAULT_MAX_DEPTH) {
@@ -93,7 +101,7 @@ build_parsed_json_cust(simdjson_php_parser* parser, simdjson::dom::element &doc,
93101static zend_always_inline void simdjson_set_zval_to_string (zval *v, const char *buf, size_t len) {
94102 /* In php 7.1, the ZSTR_CHAR macro doesn't exist, and CG(one_char_string)[chr] may or may not be null */
95103#if PHP_VERSION_ID >= 70200
96- if (len <= 1 ) {
104+ if (UNEXPECTED ( len <= 1 ) ) {
97105 /*
98106 A note on performance benefits of the use of interned strings here and elsewhere:
99107
@@ -111,7 +119,8 @@ static zend_always_inline void simdjson_set_zval_to_string(zval *v, const char *
111119 return ;
112120 }
113121#endif
114- ZVAL_STRINGL (v, buf, len);
122+ zend_string *str = simdjson_string_init (buf, len);
123+ ZVAL_NEW_STR (v, str);
115124}
116125
117126static zend_always_inline void simdjson_add_key_to_symtable (HashTable *ht, const char *buf, size_t len, zval *value) {
@@ -125,7 +134,7 @@ static zend_always_inline void simdjson_add_key_to_symtable(HashTable *ht, const
125134 return ;
126135 }
127136#endif
128- zend_string *key = zend_string_init (buf, len, 0 );
137+ zend_string *key = simdjson_string_init (buf, len);
129138 zend_symtable_update (ht, key, value);
130139 /* Release the reference counted key */
131140 zend_string_release_ex (key, 0 );
@@ -208,7 +217,6 @@ static simdjson_php_error_code create_array(simdjson::dom::element element, zval
208217 ZVAL_NULL (return_value);
209218 return error;
210219 }
211- /* TODO consider using zend_string_init_existing_interned in php 8.1+ to save memory and time freeing strings. */
212220 simdjson_add_key_to_symtable (arr, field.key .data (), field.key .size (), &array_element);
213221 }
214222 break ;
@@ -297,7 +305,7 @@ static simdjson_php_error_code create_object(simdjson::dom::element element, zva
297305 if (size <= 1 ) {
298306 key = size == 1 ? ZSTR_CHAR ((unsigned char )data[0 ]) : ZSTR_EMPTY_ALLOC ();
299307 } else {
300- key = zend_string_init (data, size, 0 );
308+ key = simdjson_string_init (data, size);
301309 }
302310 zend_std_write_property (obj, key, &value, NULL );
303311 zend_string_release_ex (key, 0 );
0 commit comments