@@ -132,7 +132,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
132
132
int l_false = -1 ;
133
133
int l_true = -1 ;
134
134
int l_empty_arr = -1 ;
135
- HashTable hash ;
135
+ HashTable hash , double_hash ;
136
136
zend_string * key = NULL ;
137
137
void * checkpoint = zend_arena_checkpoint (ctx -> arena );
138
138
int * const_slot , * class_slot , * func_slot , * bind_var_slot , * property_slot , * method_slot ;
@@ -315,6 +315,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
315
315
/* Merge equal constants */
316
316
j = 0 ;
317
317
zend_hash_init (& hash , op_array -> last_literal , NULL , NULL , 0 );
318
+ /* Use separate hashtable for doubles stored as string keys, to avoid collisions. */
319
+ zend_hash_init (& double_hash , 0 , NULL , NULL , 0 );
318
320
map = (int * )zend_arena_alloc (& ctx -> arena , op_array -> last_literal * sizeof (int ));
319
321
memset (map , 0 , op_array -> last_literal * sizeof (int ));
320
322
for (i = 0 ; i < op_array -> last_literal ; i ++ ) {
@@ -397,12 +399,12 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
397
399
}
398
400
break ;
399
401
case IS_DOUBLE :
400
- if ((pos = zend_hash_str_find (& hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
402
+ if ((pos = zend_hash_str_find (& double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ))) != NULL ) {
401
403
map [i ] = Z_LVAL_P (pos );
402
404
} else {
403
405
map [i ] = j ;
404
406
ZVAL_LONG (& zv , j );
405
- zend_hash_str_add ( & hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), & zv );
407
+ zend_hash_str_add_new ( & double_hash , (char * )& Z_DVAL (op_array -> literals [i ]), sizeof (double ), & zv );
406
408
if (i != j ) {
407
409
op_array -> literals [j ] = op_array -> literals [i ];
408
410
info [j ] = info [i ];
@@ -485,7 +487,10 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
485
487
break ;
486
488
}
487
489
}
490
+
491
+ /* Only clean "hash", as it will be reused in the loop below. */
488
492
zend_hash_clean (& hash );
493
+ zend_hash_destroy (& double_hash );
489
494
op_array -> last_literal = j ;
490
495
491
496
const_slot = zend_arena_alloc (& ctx -> arena , j * 6 * sizeof (int ));
0 commit comments