further tighten eq-hash code generation
Avoids including the bit thet indicates whether the object is GCable in the eq hash code (in a configuration where bits are available in the GC header for hashing).
This commit is contained in:
parent
8b7b96215b
commit
2a79377c60
|
@ -51,6 +51,22 @@ static void register_traversers(void);
|
||||||
#define to_signed_hash(v) ((intptr_t)v)
|
#define to_signed_hash(v) ((intptr_t)v)
|
||||||
#define to_unsigned_hash(v) ((uintptr_t)v)
|
#define to_unsigned_hash(v) ((uintptr_t)v)
|
||||||
|
|
||||||
|
#ifdef OBJHEAD_HAS_HASH_BITS
|
||||||
|
/* In 3m mode, we only have 14 bits of hash code in the
|
||||||
|
Scheme_Object header. But the GC-level object header has some
|
||||||
|
leftover bits (currently 9, 11, 41, or 43, depending on the
|
||||||
|
platform), so use those, too. That only works for GCable
|
||||||
|
objects, so we use 1 of our 14 bits to indicate whether the
|
||||||
|
other bits are present. */
|
||||||
|
# define GCABLE_OBJ_HASH_BIT 0x0004
|
||||||
|
# define OBJ_HASH_USELESS_BITS 3
|
||||||
|
#else
|
||||||
|
# define GCABLE_OBJ_HASH_BIT 0
|
||||||
|
# define OBJ_HASH_USELESS_BITS 2
|
||||||
|
#endif
|
||||||
|
#define OBJ_HASH_USEFUL_BITS (16 - OBJ_HASH_USELESS_BITS)
|
||||||
|
#define OBJ_HASH_USEFUL_MASK ((1 << OBJ_HASH_USEFUL_BITS)-1)
|
||||||
|
|
||||||
#ifdef MZ_PRECISE_GC
|
#ifdef MZ_PRECISE_GC
|
||||||
/* keygen race conditions below are "ok", because keygen is randomness
|
/* keygen race conditions below are "ok", because keygen is randomness
|
||||||
used to create a hashkey. Technically, a race condition allows
|
used to create a hashkey. Technically, a race condition allows
|
||||||
|
@ -59,7 +75,7 @@ static void register_traversers(void);
|
||||||
that only one thread at a time sets a hash code in a specific
|
that only one thread at a time sets a hash code in a specific
|
||||||
object, though, and watch out for a race with JIT-generated code
|
object, though, and watch out for a race with JIT-generated code
|
||||||
running in a future and setting flags on pairs. */
|
running in a future and setting flags on pairs. */
|
||||||
SHARED_OK static uintptr_t keygen;
|
SHARED_OK static uintptr_t keygen = GCABLE_OBJ_HASH_BIT;
|
||||||
|
|
||||||
XFORM_NONGCING static MZ_INLINE
|
XFORM_NONGCING static MZ_INLINE
|
||||||
uintptr_t PTR_TO_LONG(Scheme_Object *o)
|
uintptr_t PTR_TO_LONG(Scheme_Object *o)
|
||||||
|
@ -76,17 +92,11 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o)
|
||||||
uintptr_t local_keygen = keygen;
|
uintptr_t local_keygen = keygen;
|
||||||
v |= (short)local_keygen;
|
v |= (short)local_keygen;
|
||||||
#ifdef OBJHEAD_HAS_HASH_BITS
|
#ifdef OBJHEAD_HAS_HASH_BITS
|
||||||
/* In 3m mode, we only have 14 bits of hash code in the
|
|
||||||
Scheme_Object header. But the GC-level object header has some
|
|
||||||
leftover bits (currently 9, 11, 41, or 43, depending on the
|
|
||||||
platform), so use those, too. That only works for GCable
|
|
||||||
objects, so we use 1 of our 14 bits to indicate whether the
|
|
||||||
other bit are present. */
|
|
||||||
if (GC_is_allocated(o)) {
|
if (GC_is_allocated(o)) {
|
||||||
OBJHEAD_HASH_BITS(o) = (local_keygen >> 16);
|
OBJHEAD_HASH_BITS(o) = (local_keygen >> 16);
|
||||||
v |= 0x4000;
|
v |= GCABLE_OBJ_HASH_BIT;
|
||||||
} else
|
} else
|
||||||
v &= ~0x4000;
|
v &= ~GCABLE_OBJ_HASH_BIT;
|
||||||
#endif
|
#endif
|
||||||
if (!v) v = 0x1AD0;
|
if (!v) v = 0x1AD0;
|
||||||
#ifdef MZ_USE_FUTURES
|
#ifdef MZ_USE_FUTURES
|
||||||
|
@ -99,11 +109,11 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o)
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
o->keyex = v;
|
o->keyex = v;
|
||||||
keygen += 4;
|
keygen += (1 << OBJ_HASH_USELESS_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef OBJHEAD_HAS_HASH_BITS
|
#ifdef OBJHEAD_HAS_HASH_BITS
|
||||||
if (v & 0x4000)
|
if (v & GCABLE_OBJ_HASH_BIT)
|
||||||
bits = OBJHEAD_HASH_BITS(o);
|
bits = OBJHEAD_HASH_BITS(o);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -112,7 +122,7 @@ uintptr_t PTR_TO_LONG(Scheme_Object *o)
|
||||||
/* We need to drop the low two bits of `v', which
|
/* We need to drop the low two bits of `v', which
|
||||||
are used for non-hashing purposes in some types. */
|
are used for non-hashing purposes in some types. */
|
||||||
|
|
||||||
return (bits << 14) | ((v >> 2) & 0x3FFF);
|
return (bits << OBJ_HASH_USEFUL_BITS) | ((v >> OBJ_HASH_USELESS_BITS) & OBJ_HASH_USEFUL_MASK);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define PTR_TO_LONG(p) ((uintptr_t)(p)>>2)
|
# define PTR_TO_LONG(p) ((uintptr_t)(p)>>2)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user