static uptrint_t bits_hash(void *b, size_t sz) { switch (sz) { case 1: return int32hash(*(int8_t*)b); case 2: return int32hash(*(int16_t*)b); case 4: return int32hash(*(int32_t*)b); case 8: return hash64(*(int64_t*)b); default: #ifdef _P64 return memhash((char*)b, sz); #else return memhash32((char*)b, sz); #endif } }
static uintptr_t bits_hash(const void *b, size_t sz) { switch (sz) { case 1: return int32hash(*(const int8_t*)b); case 2: return int32hash(jl_load_unaligned_i16(b)); case 4: return int32hash(jl_load_unaligned_i32(b)); #ifdef _P64 case 8: return int64hash(jl_load_unaligned_i64(b)); #else case 8: return int64to32hash(jl_load_unaligned_i64(b)); #endif default: #ifdef _P64 return memhash((const char*)b, sz); #else return memhash32((const char*)b, sz); #endif } }
DLLEXPORT uptrint_t jl_object_id(jl_value_t *v) { if (jl_is_symbol(v)) return ((jl_sym_t*)v)->hash; jl_value_t *tv = (jl_value_t*)jl_typeof(v); if (jl_is_bits_type(tv)) { size_t nb = jl_bitstype_nbits(tv)/8; uptrint_t h = inthash((uptrint_t)tv); switch (nb) { case 1: return int32hash(*(int8_t*)jl_bits_data(v) ^ h); case 2: return int32hash(*(int16_t*)jl_bits_data(v) ^ h); case 4: return int32hash(*(int32_t*)jl_bits_data(v) ^ h); case 8: return hash64(*(int64_t*)jl_bits_data(v) ^ h); default: #ifdef __LP64__ return h ^ memhash((char*)jl_bits_data(v), nb); #else return h ^ memhash32((char*)jl_bits_data(v), nb); #endif } } if (tv == (jl_value_t*)jl_union_kind) { #ifdef __LP64__ return jl_object_id(jl_fieldref(v,0))^0xA5A5A5A5A5A5A5A5L; #else return jl_object_id(jl_fieldref(v,0))^0xA5A5A5A5; #endif } if (jl_is_struct_type(tv)) return inthash((uptrint_t)v); assert(jl_is_tuple(v)); uptrint_t h = 0; size_t l = jl_tuple_len(v); for(size_t i = 0; i < l; i++) { uptrint_t u = jl_object_id(jl_tupleref(v,i)); h = bitmix(h, u); } return h; }