@@ -126,7 +126,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
126
126
int l_false = -1 ;
127
127
int l_true = -1 ;
128
128
int l_empty_arr = -1 ;
129
- HashTable hash ;
129
+ HashTable hash , double_hash ;
130
130
zend_string * key = NULL ;
131
131
void * checkpoint = zend_arena_checkpoint (ctx -> arena );
132
132
int * const_slot , * class_slot , * func_slot , * bind_var_slot , * property_slot , * method_slot ;
@@ -309,6 +309,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
309
309
/* Merge equal constants */
310
310
j = 0 ;
311
311
zend_hash_init (& hash , op_array -> last_literal , NULL , NULL , 0 );
312
+ /* Use separate hashtable for doubles stored as string keys, to avoid collisions. */
313
+ zend_hash_init (& double_hash , 0 , NULL , NULL , 0 );
312
314
map = (int * )zend_arena_alloc (& ctx -> arena , op_array -> last_literal * sizeof (int ));
313
315
memset (map , 0 , op_array -> last_literal * sizeof (int ));
314
316
for (i = 0 ; i < op_array -> last_literal ; i ++ ) {
@@ -391,12 +393,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
391
393
}
392
394
break ;
393
395
case IS_DOUBLE :
394
- if ((pos = zend_hash_str_find (& hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
396
+ if ((pos = zend_hash_str_find (& double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
395
397
map [i ] = Z_LVAL_P (pos );
396
398
} else {
397
399
map [i ] = j ;
398
400
ZVAL_LONG (& zv , j );
399
- zend_hash_str_add ( & hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), & zv );
401
+ zend_hash_str_add_new ( & double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), & zv );
400
402
if (i != j ) {
401
403
op_array -> literals [j ] = op_array -> literals [i ];
402
404
info [j ] = info [i ];
@@ -479,7 +481,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
479
481
break ;
480
482
}
481
483
}
484
+
485
+ /* Only clean "hash", as it will be reused in the loop below. */
482
486
zend_hash_clean (& hash );
487
+ zend_hash_destroy (& double_hash );
483
488
op_array -> last_literal = j ;
484
489
485
490
const_slot = zend_arena_alloc (& ctx -> arena , j * 6 * sizeof (int ));
0 commit comments