Skip to content

Commit cc506a8

Browse files
committed
Used string with biased hash for double deduplication
Rather than using a separate hash table for doubles, use the same biases hash approach we use for everything else. Either way works fine, but there doesn't seem to be any strong reason to use a different approach for doubles than we use for other cases.
1 parent 83e0a5d commit cc506a8

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

Zend/Optimizer/compact_literals.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
103110
static 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

Comments
 (0)