Skip to content

Commit

Permalink
make object_ids and hashes in precompiled modules more stable
Browse files Browse the repository at this point in the history
fixes #17043, also helps #5849
  • Loading branch information
JeffBezanson committed Jul 13, 2016
1 parent 2ea885c commit 382e98f
Showing 7 changed files with 17 additions and 23 deletions.
2 changes: 1 addition & 1 deletion src/alloc.c
Original file line number Diff line number Diff line change
@@ -817,7 +817,7 @@ JL_DLLEXPORT jl_typename_t *jl_new_typename_in(jl_sym_t *name, jl_module_t *modu
tn->cache = jl_emptysvec;
tn->linearcache = jl_emptysvec;
tn->names = NULL;
tn->uid = jl_assign_type_uid();
tn->hash = bitmix(bitmix(module ? module->uuid : 0, name->hash), 0xa1ada1da);
tn->mt = NULL;
JL_GC_PUSH1(&tn);
tn->mt = NULL;
25 changes: 7 additions & 18 deletions src/builtins.c
Original file line number Diff line number Diff line change
@@ -1012,21 +1012,17 @@ JL_CALLABLE(jl_f_invoke)

// hashing --------------------------------------------------------------------

#ifdef _P64
#define bitmix(a,b) int64hash((a)^bswap_64(b))
#define hash64(a) int64hash(a)
#else
#define bitmix(a,b) int64to32hash((((uint64_t)a)<<32)|((uint64_t)b))
#define hash64(a) int64to32hash(a)
#endif

static uintptr_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);
#ifdef _P64
case 8: return int64hash(*(int64_t*)b);
#else
case 8: return int64to32hash(*(int64_t*)b);
#endif
default:
#ifdef _P64
return memhash((char*)b, sz);
@@ -1057,17 +1053,10 @@ static uintptr_t jl_object_id_(jl_value_t *tv, jl_value_t *v)
jl_datatype_t *dt = (jl_datatype_t*)tv;
if (dt == jl_datatype_type) {
jl_datatype_t *dtv = (jl_datatype_t*)v;
uintptr_t h = 0xda1ada1a;
// has_typevars always returns 0 on name->primary, so that type
// can exist in the cache. however, interpreter.c mutates its
// typevars' `bound` fields to 0, corrupting the cache. this is
// avoided simply by hashing name->primary specially here.
if (jl_egal(dtv->name->primary, v))
return bitmix(bitmix(h, dtv->name->uid), 0xaa5566aa);
return bitmix(bitmix(h, dtv->name->uid), hash_svec(dtv->parameters));
return bitmix(~dtv->name->hash, hash_svec(dtv->parameters));
}
if (dt == jl_typename_type)
return bitmix(((jl_typename_t*)v)->uid, 0xa1ada1ad);
return ((jl_typename_t*)v)->hash;
if (dt->mutabl) return inthash((uintptr_t)v);
size_t sz = jl_datatype_size(tv);
uintptr_t h = jl_object_id(tv);
1 change: 0 additions & 1 deletion src/dump.c
Original file line number Diff line number Diff line change
@@ -1628,7 +1628,6 @@ static jl_value_t *jl_deserialize_value_(ios_t *s, jl_value_t *vtag, jl_value_t
if ((mode == MODE_MODULE || mode == MODE_MODULE_POSTWORK)) {
if (dt == jl_typename_type) {
jl_typename_t *tn = (jl_typename_t*)v;
tn->uid = jl_assign_type_uid(); // make sure this has a new uid
tn->cache = jl_emptysvec; // the cache is refilled later (tag 5)
tn->linearcache = jl_emptysvec; // the cache is refilled later (tag 5)
}
2 changes: 1 addition & 1 deletion src/jltypes.c
Original file line number Diff line number Diff line change
@@ -3524,7 +3524,7 @@ void jl_init_types(void)
jl_typename_type->name->names = jl_svec(8, jl_symbol("name"), jl_symbol("module"),
jl_symbol("names"), jl_symbol("primary"),
jl_symbol("cache"), jl_symbol("linearcache"),
jl_symbol("uid"), jl_symbol("mt"));
jl_symbol("hash"), jl_symbol("mt"));
jl_typename_type->types = jl_svec(8, jl_sym_type, jl_any_type, jl_simplevector_type,
jl_type_type, jl_simplevector_type, jl_simplevector_type,
jl_any_type, jl_any_type);
2 changes: 1 addition & 1 deletion src/julia.h
Original file line number Diff line number Diff line change
@@ -300,7 +300,7 @@ typedef struct {
jl_value_t *primary;
jl_svec_t *cache; // sorted array
jl_svec_t *linearcache; // unsorted array
intptr_t uid;
intptr_t hash;
struct _jl_methtable_t *mt;
} jl_typename_t;

2 changes: 1 addition & 1 deletion src/module.c
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ JL_DLLEXPORT jl_module_t *jl_new_module(jl_sym_t *name)
m->name = name;
m->parent = NULL;
m->istopmod = 0;
m->uuid = uv_now(uv_default_loop());
m->uuid = jl_hrtime();
m->counter = 0;
htable_new(&m->bindings, 0);
arraylist_new(&m->usings, 0);
6 changes: 6 additions & 0 deletions src/support/hashing.h
Original file line number Diff line number Diff line change
@@ -21,6 +21,12 @@ JL_DLLEXPORT uint64_t memhash_seed(const char *buf, size_t n, uint32_t seed);
JL_DLLEXPORT uint32_t memhash32(const char *buf, size_t n);
JL_DLLEXPORT uint32_t memhash32_seed(const char *buf, size_t n, uint32_t seed);

#ifdef _P64
#define bitmix(a,b) int64hash((a)^bswap_64(b))
#else
#define bitmix(a,b) int64to32hash((((uint64_t)a)<<32)|((uint64_t)b))
#endif

#ifdef __cplusplus
}
#endif

0 comments on commit 382e98f

Please sign in to comment.