@@ -125,7 +125,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
125
125
int l_false = -1 ;
126
126
int l_true = -1 ;
127
127
int l_empty_arr = -1 ;
128
- HashTable hash ;
128
+ HashTable hash , double_hash ;
129
129
zend_string * key = NULL ;
130
130
void * checkpoint = zend_arena_checkpoint (ctx -> arena );
131
131
int * const_slot , * class_slot , * func_slot , * bind_var_slot , * property_slot , * method_slot ;
@@ -329,6 +329,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
329
329
/* Merge equal constants */
330
330
j = 0 ;
331
331
zend_hash_init (& hash , op_array -> last_literal , NULL , NULL , 0 );
332
+ /* Use separate hashtable for doubles stored as string keys, to avoid collisions. */
333
+ zend_hash_init (& double_hash , 0 , NULL , NULL , 0 );
332
334
map = (int * )zend_arena_alloc (& ctx -> arena , op_array -> last_literal * sizeof (int ));
333
335
memset (map , 0 , op_array -> last_literal * sizeof (int ));
334
336
for (i = 0 ; i < op_array -> last_literal ; i ++ ) {
@@ -411,12 +413,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
411
413
}
412
414
break ;
413
415
case IS_DOUBLE :
414
- if ((pos = zend_hash_str_find (& hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
416
+ if ((pos = zend_hash_str_find (& double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
415
417
map [i ] = Z_LVAL_P (pos );
416
418
} else {
417
419
map [i ] = j ;
418
420
ZVAL_LONG (& zv , j );
419
- zend_hash_str_add (& hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), & zv );
421
+ zend_hash_str_add (& double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), & zv );
420
422
if (i != j ) {
421
423
op_array -> literals [j ] = op_array -> literals [i ];
422
424
info [j ] = info [i ];
@@ -494,7 +496,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
494
496
break ;
495
497
}
496
498
}
499
+
500
+ /* Only clean "hash", as it will be reused in the loop below. */
497
501
zend_hash_clean (& hash );
502
+ zend_hash_destroy (& double_hash );
498
503
op_array -> last_literal = j ;
499
504
500
505
const_slot = zend_arena_alloc (& ctx -> arena , j * 6 * sizeof (int ));
0 commit comments