@@ -112,6 +112,41 @@ static uint32_t add_static_slot(HashTable *hash,
112
112
return ret ;
113
113
}
114
114
115
+ static zend_string * create_str_cache_key (zval * literal , uint32_t flags )
116
+ {
117
+ ZEND_ASSERT (Z_TYPE_P (literal ) == IS_STRING );
118
+ uint32_t num_related = LITERAL_NUM_RELATED (flags );
119
+ if (num_related == 1 ) {
120
+ return zend_string_copy (Z_STR_P (literal ));
121
+ }
122
+ if ((flags & LITERAL_KIND_MASK ) == LITERAL_VALUE ) {
123
+ /* Don't merge LITERAL_VALUE that has related literals */
124
+ return NULL ;
125
+ }
126
+
127
+ /* Concatenate all the related literals for the cache key. */
128
+ zend_string * key ;
129
+ if (num_related == 2 ) {
130
+ ZEND_ASSERT (Z_TYPE_P (literal + 1 ) == IS_STRING );
131
+ key = zend_string_concat2 (
132
+ Z_STRVAL_P (literal ), Z_STRLEN_P (literal ),
133
+ Z_STRVAL_P (literal + 1 ), Z_STRLEN_P (literal + 1 ));
134
+ } else if (num_related == 3 ) {
135
+ ZEND_ASSERT (Z_TYPE_P (literal + 1 ) == IS_STRING && Z_TYPE_P (literal + 2 ) == IS_STRING );
136
+ key = zend_string_concat3 (
137
+ Z_STRVAL_P (literal ), Z_STRLEN_P (literal ),
138
+ Z_STRVAL_P (literal + 1 ), Z_STRLEN_P (literal + 1 ),
139
+ Z_STRVAL_P (literal + 2 ), Z_STRLEN_P (literal + 2 ));
140
+ } else {
141
+ ZEND_ASSERT (0 && "Currently not needed" );
142
+ }
143
+
144
+ /* Add a bias to the hash so we can distinguish keys
145
+ * that would otherwise be the same after concatenation. */
146
+ ZSTR_H (key ) = zend_string_hash_val (key ) + num_related - 1 ;
147
+ return key ;
148
+ }
149
+
115
150
void zend_optimizer_compact_literals (zend_op_array * op_array , zend_optimizer_ctx * ctx )
116
151
{
117
152
zend_op * opline , * end ;
@@ -403,16 +438,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
403
438
}
404
439
break ;
405
440
case IS_STRING : {
406
- if (LITERAL_NUM_RELATED (info [i ].flags ) == 1 ) {
407
- key = zend_string_copy (Z_STR (op_array -> literals [i ]));
408
- } else if ((info [i ].flags & LITERAL_KIND_MASK ) != LITERAL_VALUE ) {
409
- key = zend_string_init (Z_STRVAL (op_array -> literals [i ]), Z_STRLEN (op_array -> literals [i ]), 0 );
410
- ZSTR_H (key ) = ZSTR_HASH (Z_STR (op_array -> literals [i ])) +
411
- LITERAL_NUM_RELATED (info [i ].flags ) - 1 ;
412
- } else {
413
- /* Don't merge LITERAL_VALUE that has related literals */
414
- key = NULL ;
415
- }
441
+ key = create_str_cache_key (& op_array -> literals [i ], info [i ].flags );
416
442
if (key && (pos = zend_hash_find (& hash , key )) != NULL &&
417
443
Z_TYPE (op_array -> literals [Z_LVAL_P (pos )]) == IS_STRING &&
418
444
LITERAL_NUM_RELATED (info [i ].flags ) == LITERAL_NUM_RELATED (info [Z_LVAL_P (pos )].flags ) &&
0 commit comments