diff --git a/src/gc.c b/src/gc.c index cd7f4876d689a..d133fc6399a65 100644 --- a/src/gc.c +++ b/src/gc.c @@ -1877,30 +1877,25 @@ STATIC_INLINE jl_value_t *gc_mark_obj8(jl_ptls_t ptls, char *obj8_parent, uint8_ { (void)jl_assume(obj8_begin < obj8_end); jl_gc_markqueue_t *mq = &ptls->mark_queue; - jl_value_t **slot; - jl_value_t *new_obj; - for (; obj8_begin < obj8_end - 1; obj8_begin++) { + jl_value_t **slot = NULL; + jl_value_t *new_obj = NULL; + for (; obj8_begin < obj8_end; obj8_begin++) { slot = &((jl_value_t**)obj8_parent)[*obj8_begin]; new_obj = *slot; if (new_obj != NULL) { verify_parent2("object", obj8_parent, slot, "field(%d)", gc_slot_to_fieldidx(obj8_parent, slot, (jl_datatype_t*)jl_typeof(obj8_parent))); - gc_try_claim_and_push(mq, new_obj, &nptr); + if (obj8_begin + 1 != obj8_end) { + gc_try_claim_and_push(mq, new_obj, &nptr); + } + else { + jl_taggedvalue_t *o = jl_astaggedvalue(new_obj); + nptr |= !gc_old(o->header); + if (!gc_try_setmark_tag(o, GC_MARKED)) new_obj = NULL; + } gc_heap_snapshot_record_object_edge((jl_value_t*)obj8_parent, slot); } } - // Unroll last iteration to avoid pushing last element - // and popping right away - slot = &((jl_value_t **)obj8_parent)[*(obj8_end - 1)]; - new_obj = *slot; - if (new_obj != NULL) { - verify_parent2("object", obj8_parent, slot, "field(%d)", - gc_slot_to_fieldidx(obj8_parent, slot, (jl_datatype_t*)jl_typeof(obj8_parent))); - gc_heap_snapshot_record_object_edge((jl_value_t*)obj8_parent, slot); - jl_taggedvalue_t *o = jl_astaggedvalue(new_obj); - nptr |= !gc_old(o->header); - if (!gc_try_setmark_tag(o, GC_MARKED)) new_obj = NULL; - } gc_mark_push_remset(ptls, (jl_value_t *)obj8_parent, nptr); return new_obj; } @@ -1911,30 +1906,26 @@ STATIC_INLINE jl_value_t *gc_mark_obj16(jl_ptls_t ptls, char *obj16_parent, uint { (void)jl_assume(obj16_begin < obj16_end); jl_gc_markqueue_t *mq = &ptls->mark_queue; - jl_value_t **slot; - jl_value_t *new_obj; - for (; obj16_begin < obj16_end - 1; obj16_begin++) { + jl_value_t **slot = NULL; + jl_value_t *new_obj = NULL; + for (; obj16_begin < obj16_end; obj16_begin++) { slot = &((jl_value_t **)obj16_parent)[*obj16_begin]; new_obj = *slot; if (new_obj != NULL) { verify_parent2("object", obj16_parent, slot, "field(%d)", gc_slot_to_fieldidx(obj16_parent, slot, (jl_datatype_t*)jl_typeof(obj16_parent))); gc_try_claim_and_push(mq, new_obj, &nptr); + if (obj16_begin + 1 != obj16_end) { + gc_try_claim_and_push(mq, new_obj, &nptr); + } + else { + jl_taggedvalue_t *o = jl_astaggedvalue(new_obj); + nptr |= !gc_old(o->header); + if (!gc_try_setmark_tag(o, GC_MARKED)) new_obj = NULL; + } gc_heap_snapshot_record_object_edge((jl_value_t*)obj16_parent, slot); } } - // Unroll last iteration to avoid pushing last element - // and popping right away - slot = &((jl_value_t **)obj16_parent)[*(obj16_end - 1)]; - new_obj = *slot; - if (new_obj != NULL) { - verify_parent2("object", obj16_parent, slot, "field(%d)", - gc_slot_to_fieldidx(obj16_parent, slot, (jl_datatype_t*)jl_typeof(obj16_parent))); - gc_heap_snapshot_record_object_edge((jl_value_t*)obj16_parent, slot); - jl_taggedvalue_t *o = jl_astaggedvalue(new_obj); - nptr |= !gc_old(o->header); - if (!gc_try_setmark_tag(o, GC_MARKED)) new_obj = NULL; - } gc_mark_push_remset(ptls, (jl_value_t *)obj16_parent, nptr); return new_obj; } @@ -1945,31 +1936,25 @@ STATIC_INLINE jl_value_t *gc_mark_obj32(jl_ptls_t ptls, char *obj32_parent, uint { (void)jl_assume(obj32_begin < obj32_end); jl_gc_markqueue_t *mq = &ptls->mark_queue; - jl_value_t **slot; - jl_value_t *new_obj; - for (; obj32_begin < obj32_end - 1; obj32_begin++) { + jl_value_t **slot = NULL; + jl_value_t *new_obj = NULL; + for (; obj32_begin < obj32_end; obj32_begin++) { slot = &((jl_value_t **)obj32_parent)[*obj32_begin]; new_obj = *slot; if (new_obj != NULL) { verify_parent2("object", obj32_parent, slot, "field(%d)", gc_slot_to_fieldidx(obj32_parent, slot, (jl_datatype_t*)jl_typeof(obj32_parent))); - gc_try_claim_and_push(mq, new_obj, &nptr); + if (obj32_begin + 1 != obj32_end) { + gc_try_claim_and_push(mq, new_obj, &nptr); + } + else { + jl_taggedvalue_t *o = jl_astaggedvalue(new_obj); + nptr |= !gc_old(o->header); + if (!gc_try_setmark_tag(o, GC_MARKED)) new_obj = NULL; + } gc_heap_snapshot_record_object_edge((jl_value_t*)obj32_parent, slot); } } - // Unroll last iteration to avoid pushing last element - // and popping right away - slot = &((jl_value_t **)obj32_parent)[*(obj32_end - 1)]; - new_obj = *slot; - if (new_obj != NULL) { - verify_parent2("object", obj32_parent, slot, "field(%d)", - gc_slot_to_fieldidx(obj32_parent, slot,(jl_datatype_t*)jl_typeof(obj32_parent))); - gc_heap_snapshot_record_object_edge((jl_value_t*)obj32_parent, slot); - jl_taggedvalue_t *o = jl_astaggedvalue(new_obj); - nptr |= !gc_old(o->header); - if (!gc_try_setmark_tag(o, GC_MARKED)) new_obj = NULL; - } - gc_mark_push_remset(ptls, (jl_value_t *)obj32_parent, nptr); return new_obj; }