@@ -100,6 +100,13 @@ static uint32_t add_static_slot(HashTable *hash,
100100 return ret ;
101101}
102102
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+
103110static zend_string * create_str_cache_key (zval * literal , uint8_t num_related )
104111{
105112 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)
124131 ZEND_ASSERT (0 && "Currently not needed" );
125132 }
126133
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 );
130135 return key ;
131136}
132137
@@ -141,7 +146,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
141146 int l_false = -1 ;
142147 int l_true = -1 ;
143148 int l_empty_arr = -1 ;
144- HashTable hash , double_hash ;
149+ HashTable hash ;
145150 zend_string * key = NULL ;
146151 void * checkpoint = zend_arena_checkpoint (ctx -> arena );
147152 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
285290 /* Merge equal constants */
286291 j = 0 ;
287292 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 );
290293 map = (int * )zend_arena_alloc (& ctx -> arena , op_array -> last_literal * sizeof (int ));
291294 memset (map , 0 , op_array -> last_literal * sizeof (int ));
292295 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
349352 } else {
350353 ZEND_ASSERT (info [i ].num_related == 2 );
351354 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 );
356358 map [i ] = Z_LVAL_P (pos );
357359 zval_ptr_dtor_nogc (& op_array -> literals [i + 1 ]);
358360 } else {
@@ -373,18 +375,21 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
373375 break ;
374376 case IS_DOUBLE :
375377 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 ))) {
377381 map [i ] = Z_LVAL_P (pos );
378382 } else {
379383 map [i ] = j ;
380384 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 );
382386 if (i != j ) {
383387 op_array -> literals [j ] = op_array -> literals [i ];
384388 info [j ] = info [i ];
385389 }
386390 j ++ ;
387391 }
392+ zend_string_release_ex (key , 0 );
388393 break ;
389394 case IS_STRING : {
390395 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
452457
453458 /* Only clean "hash", as it will be reused in the loop below. */
454459 zend_hash_clean (& hash );
455- zend_hash_destroy (& double_hash );
456460 op_array -> last_literal = j ;
457461
458462 const_slot = zend_arena_alloc (& ctx -> arena , j * 6 * sizeof (int ));
0 commit comments