optimizer: improve hashing of variables during inlining

When creating a copy of a variable in the process of inlining, make
sure the copy has its own `eq?` hash code.
This commit is contained in:
Matthew Flatt 2017-09-07 17:53:29 +01:00
parent 1f02cf226e
commit 425d08c8e2
3 changed files with 17 additions and 1 deletions

View File

@ -67,6 +67,10 @@ static void register_traversers(void);
#define OBJ_HASH_USEFUL_BITS (16 - OBJ_HASH_USELESS_BITS)
#define OBJ_HASH_USEFUL_MASK ((1 << OBJ_HASH_USEFUL_BITS)-1)
/* A hash code has been installed if any of these bits is
non-zero: */
#define HASH_CODE_PRESENT_BITS 0xFFFC
#ifdef MZ_PRECISE_GC
/* keygen race conditions below are "ok", because keygen is randomness
used to create a hashkey. Technically, a race condition allows
@ -88,7 +92,7 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o)
v = o->keyex;
if (!(v & 0xFFFC)) {
if (!(v & HASH_CODE_PRESENT_BITS)) {
uintptr_t local_keygen = keygen;
v |= (short)local_keygen;
#ifdef OBJHEAD_HAS_HASH_BITS
@ -128,6 +132,15 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o)
# define PTR_TO_LONG(p) ((uintptr_t)(p)>>2)
#endif
void scheme_set_distinct_eq_hash(Scheme_Object *o)
/* Used after cloning a value to ensure that the
hash code is not cloned */
{
#ifdef MZ_PRECISE_GC
o->keyex = o->keyex & ~HASH_CODE_PRESENT_BITS;
#endif
}
void scheme_install_symbol_hash_code(Scheme_Object *sym, uintptr_t h)
{
#ifdef MZ_PRECISE_GC

View File

@ -8386,6 +8386,7 @@ static Scheme_IR_Local *clone_variable(Scheme_IR_Local *var)
MZ_ASSERT(SAME_TYPE(var->so.type, scheme_ir_local_type));
var2 = MALLOC_ONE_TAGGED(Scheme_IR_Local);
memcpy(var2, var, sizeof(Scheme_IR_Local));
scheme_set_distinct_eq_hash((Scheme_Object *)var2);
return var2;
}

View File

@ -4510,6 +4510,8 @@ Scheme_Object *scheme_append_strings(Scheme_Object *s1, Scheme_Object *s2);
void scheme_reset_hash_table(Scheme_Hash_Table *ht, int *history);
XFORM_NONGCING void scheme_set_distinct_eq_hash(Scheme_Object *var2);
XFORM_NONGCING Scheme_Object *scheme_regexp_source(Scheme_Object *re);
int scheme_regexp_is_byte(Scheme_Object *re);
int scheme_regexp_is_pregexp(Scheme_Object *re);