@@ -100,6 +100,13 @@ static uint32_t add_static_slot(HashTable *hash,
100
100
return ret ;
101
101
}
102
102
103
+ static inline void bias_key (zend_string * key , uint32_t bias )
104
+ {
105
+ /* Add a bias to the hash so we can distinguish string keys
106
+ * that would otherwise be the same. */
107
+ ZSTR_H (key ) = zend_string_hash_val (key ) + bias ;
108
+ }
109
+
103
110
static zend_string * create_str_cache_key (zval * literal , uint8_t num_related )
104
111
{
105
112
ZEND_ASSERT (Z_TYPE_P (literal ) == IS_STRING );
@@ -124,9 +131,7 @@ static zend_string *create_str_cache_key(zval *literal, uint8_t num_related)
124
131
ZEND_ASSERT (0 && "Currently not needed" );
125
132
}
126
133
127
- /* Add a bias to the hash so we can distinguish keys
128
- * that would otherwise be the same after concatenation. */
129
- ZSTR_H (key ) = zend_string_hash_val (key ) + num_related - 1 ;
134
+ bias_key (key , num_related - 1 );
130
135
return key ;
131
136
}
132
137
@@ -141,7 +146,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
141
146
int l_false = -1 ;
142
147
int l_true = -1 ;
143
148
int l_empty_arr = -1 ;
144
- HashTable hash , double_hash ;
149
+ HashTable hash ;
145
150
zend_string * key = NULL ;
146
151
void * checkpoint = zend_arena_checkpoint (ctx -> arena );
147
152
int * const_slot , * class_slot , * func_slot , * bind_var_slot , * property_slot , * method_slot ;
@@ -285,8 +290,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
285
290
/* Merge equal constants */
286
291
j = 0 ;
287
292
zend_hash_init (& hash , op_array -> last_literal , NULL , NULL , 0 );
288
- /* Use separate hashtable for doubles stored as string keys, to avoid collisions. */
289
- zend_hash_init (& double_hash , 0 , NULL , NULL , 0 );
290
293
map = (int * )zend_arena_alloc (& ctx -> arena , op_array -> last_literal * sizeof (int ));
291
294
memset (map , 0 , op_array -> last_literal * sizeof (int ));
292
295
for (i = 0 ; i < op_array -> last_literal ; i ++ ) {
@@ -349,10 +352,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
349
352
} else {
350
353
ZEND_ASSERT (info [i ].num_related == 2 );
351
354
key = zend_string_init (Z_STRVAL (op_array -> literals [i + 1 ]), Z_STRLEN (op_array -> literals [i + 1 ]), 0 );
352
- ZSTR_H (key ) = ZSTR_HASH (Z_STR (op_array -> literals [i + 1 ])) + 100 +
353
- info [i ].num_related - 1 ;
354
- if ((pos = zend_hash_find (& hash , key )) != NULL
355
- && info [Z_LVAL_P (pos )].num_related == 2 ) {
355
+ bias_key (key , 100 + info [i ].num_related - 1 );
356
+ if ((pos = zend_hash_find (& hash , key )) != NULL ) {
357
+ ZEND_ASSERT (info [Z_LVAL_P (pos )].num_related == 2 );
356
358
map [i ] = Z_LVAL_P (pos );
357
359
zval_ptr_dtor_nogc (& op_array -> literals [i + 1 ]);
358
360
} else {
@@ -373,18 +375,21 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
373
375
break ;
374
376
case IS_DOUBLE :
375
377
ZEND_ASSERT (info [i ].num_related == 1 );
376
- if ((pos = zend_hash_str_find (& double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
378
+ key = zend_string_init ((char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), 0 );
379
+ bias_key (key , 200 );
380
+ if ((pos = zend_hash_find (& hash , key ))) {
377
381
map [i ] = Z_LVAL_P (pos );
378
382
} else {
379
383
map [i ] = j ;
380
384
ZVAL_LONG (& zv , j );
381
- zend_hash_str_add_new ( & double_hash , ( char * ) & Z_DVAL ( op_array -> literals [ i ]), sizeof ( double ) , & zv );
385
+ zend_hash_add_new ( & hash , key , & zv );
382
386
if (i != j ) {
383
387
op_array -> literals [j ] = op_array -> literals [i ];
384
388
info [j ] = info [i ];
385
389
}
386
390
j ++ ;
387
391
}
392
+ zend_string_release_ex (key , 0 );
388
393
break ;
389
394
case IS_STRING : {
390
395
key = create_str_cache_key (& op_array -> literals [i ], info [i ].num_related );
@@ -452,7 +457,6 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
452
457
453
458
/* Only clean "hash", as it will be reused in the loop below. */
454
459
zend_hash_clean (& hash );
455
- zend_hash_destroy (& double_hash );
456
460
op_array -> last_literal = j ;
457
461
458
462
const_slot = zend_arena_alloc (& ctx -> arena , j * 6 * sizeof (int ));
0 commit comments