From 8edf4925da29b5a6d0cc07f22e63c0048b597c19 Mon Sep 17 00:00:00 2001 From: Reimer Behrends Date: Mon, 28 May 2018 04:46:28 +0200 Subject: [PATCH] Revert changes to TryMark(), as they break conservative stack scanning. --- src/julia_gc.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/julia_gc.c b/src/julia_gc.c index de0cf05661..fb9e7c0543 100644 --- a/src/julia_gc.c +++ b/src/julia_gc.c @@ -408,13 +408,37 @@ static inline int JMark(void * obj) static void TryMark(void * p) { jl_value_t * p2 = jl_gc_internal_obj_base_ptr(p); - if (p2) { + if (!p2) { + // It is possible for p to point past the end of + // the object, so we subtract one word from the + // address. This is safe, as the object is preceded + // by a larger header. + p2 = treap_find(bigvals, (char *)p - 1); + if (p2) { + // It is possible for types to not be valid objects. + // Objects with such types are not normally made visible + // to the mark loop, so we need to avoid marking them + // during conservative stack scanning. + // While jl_gc_internal_obj_base_ptr(p) already eliminates this + // case, it can still happen for bigval_t objects, so + // we run an explicit check that the type is a valid + // object for these. + p2 = (jl_value_t *)((char *)p2 + bigval_startoffset); + jl_taggedvalue_t * hdr = jl_astaggedvalue(p2); + if (hdr->type != jl_gc_internal_obj_base_ptr(hdr->type)) + return; + } + } else { if (jl_typeis(p2, datatype_mptr)) - MarkCache[MARK_HASH((UInt)p2)] = (Bag)p2; + MarkCache[MARK_HASH((UInt)p2)] = (Bag) p2; + } + if (p2) { JMark(p2); } } + + static void TryMarkRange(void * start, void * end) { if (lt_ptr(end, start)) {