Chez Scheme: repair to code vs. non-code chunk handling
The daily build plot showed much higher peak memory use due to some missing pieces for the split.
This commit is contained in:
parent
1bf4086dae
commit
3085780849
|
@ -1651,7 +1651,7 @@ ptr GCENTRY(ptr tc, ptr count_roots_ls) {
|
||||||
si->forwarded_flonums = 0;
|
si->forwarded_flonums = 0;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
chunkinfo *chunk = si->chunk;
|
chunkinfo *chunk = si->chunk, **chunks = ((si->space == space_code) ? S_code_chunks : S_chunks);
|
||||||
S_G.number_of_nonstatic_segments -= 1;
|
S_G.number_of_nonstatic_segments -= 1;
|
||||||
S_G.number_of_empty_segments += 1;
|
S_G.number_of_empty_segments += 1;
|
||||||
si->space = space_empty;
|
si->space = space_empty;
|
||||||
|
@ -1666,10 +1666,10 @@ ptr GCENTRY(ptr tc, ptr count_roots_ls) {
|
||||||
* small stuff into them and thereby invite fragmentation */
|
* small stuff into them and thereby invite fragmentation */
|
||||||
S_free_chunk(chunk);
|
S_free_chunk(chunk);
|
||||||
} else {
|
} else {
|
||||||
S_move_to_chunk_list(chunk, &S_chunks[PARTIAL_CHUNK_POOLS]);
|
S_move_to_chunk_list(chunk, &chunks[PARTIAL_CHUNK_POOLS]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
S_move_to_chunk_list(chunk, &S_chunks[PARTIAL_CHUNK_POOLS-1]);
|
S_move_to_chunk_list(chunk, &chunks[PARTIAL_CHUNK_POOLS-1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -648,7 +648,7 @@ static void check_heap_dirty_msg(msg, x) char *msg; ptr *x; {
|
||||||
void S_check_heap(aftergc, mcg) IBOOL aftergc; IGEN mcg; {
|
void S_check_heap(aftergc, mcg) IBOOL aftergc; IGEN mcg; {
|
||||||
uptr seg; INT d; ISPC s; IGEN g; IDIRTYBYTE dirty; IBOOL found_eos; IGEN pg;
|
uptr seg; INT d; ISPC s; IGEN g; IDIRTYBYTE dirty; IBOOL found_eos; IGEN pg;
|
||||||
ptr p, *pp1, *pp2, *nl;
|
ptr p, *pp1, *pp2, *nl;
|
||||||
iptr i;
|
iptr i, for_code;
|
||||||
uptr empty_segments = 0;
|
uptr empty_segments = 0;
|
||||||
uptr used_segments = 0;
|
uptr used_segments = 0;
|
||||||
uptr static_segments = 0;
|
uptr static_segments = 0;
|
||||||
|
@ -673,27 +673,31 @@ void S_check_heap(aftergc, mcg) IBOOL aftergc; IGEN mcg; {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = PARTIAL_CHUNK_POOLS; i >= -1; i -= 1) {
|
for (for_code = 0; for_code < 2; for_code++) {
|
||||||
chunkinfo *chunk = i == -1 ? S_chunks_full : S_chunks[i];
|
for (i = PARTIAL_CHUNK_POOLS; i >= -1; i -= 1) {
|
||||||
while (chunk != NULL) {
|
chunkinfo *chunk = (i == -1
|
||||||
seginfo *si = chunk->unused_segs;
|
? (for_code ? S_code_chunks_full : S_chunks_full)
|
||||||
iptr count = 0;
|
: (for_code ? S_code_chunks[i] : S_chunks[i]));
|
||||||
while(si) {
|
while (chunk != NULL) {
|
||||||
count += 1;
|
seginfo *si = chunk->unused_segs;
|
||||||
if (si->space != space_empty) {
|
iptr count = 0;
|
||||||
S_checkheap_errors += 1;
|
while(si) {
|
||||||
printf("!!! unused segment has unexpected space\n");
|
count += 1;
|
||||||
|
if (si->space != space_empty) {
|
||||||
|
S_checkheap_errors += 1;
|
||||||
|
printf("!!! unused segment has unexpected space\n");
|
||||||
|
}
|
||||||
|
si = si->next;
|
||||||
}
|
}
|
||||||
si = si->next;
|
if ((chunk->segs - count) != chunk->nused_segs) {
|
||||||
|
S_checkheap_errors += 1;
|
||||||
|
printf("!!! unexpected used segs count "Ptd" with "Ptd" total segs and "Ptd" segs on the unused list\n",
|
||||||
|
(ptrdiff_t)chunk->nused_segs, (ptrdiff_t)chunk->segs, (ptrdiff_t)count);
|
||||||
|
}
|
||||||
|
used_segments += chunk->nused_segs;
|
||||||
|
empty_segments += count;
|
||||||
|
chunk = chunk->next;
|
||||||
}
|
}
|
||||||
if ((chunk->segs - count) != chunk->nused_segs) {
|
|
||||||
S_checkheap_errors += 1;
|
|
||||||
printf("!!! unexpected used segs count "Ptd" with "Ptd" total segs and "Ptd" segs on the unused list\n",
|
|
||||||
(ptrdiff_t)chunk->nused_segs, (ptrdiff_t)chunk->segs, (ptrdiff_t)count);
|
|
||||||
}
|
|
||||||
used_segments += chunk->nused_segs;
|
|
||||||
empty_segments += count;
|
|
||||||
chunk = chunk->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -734,274 +738,278 @@ void S_check_heap(aftergc, mcg) IBOOL aftergc; IGEN mcg; {
|
||||||
(ptrdiff_t)empty_segments);
|
(ptrdiff_t)empty_segments);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = PARTIAL_CHUNK_POOLS; i >= -1; i -= 1) {
|
for (for_code = 0; for_code < 2; for_code++) {
|
||||||
chunkinfo *chunk = i == -1 ? S_chunks_full : S_chunks[i];
|
for (i = PARTIAL_CHUNK_POOLS; i >= -1; i -= 1) {
|
||||||
while (chunk != NULL) {
|
chunkinfo *chunk = (i == -1
|
||||||
uptr nsegs; seginfo *si;
|
? (for_code ? S_code_chunks_full : S_chunks_full)
|
||||||
for (si = &chunk->sis[0], nsegs = chunk->segs; nsegs != 0; nsegs -= 1, si += 1) {
|
: (for_code ? S_code_chunks[i] : S_chunks[i]));
|
||||||
seginfo *recorded_si; uptr recorded_seg;
|
while (chunk != NULL) {
|
||||||
if ((seg = si->number) != (recorded_seg = (chunk->base + chunk->segs - nsegs))) {
|
uptr nsegs; seginfo *si;
|
||||||
S_checkheap_errors += 1;
|
for (si = &chunk->sis[0], nsegs = chunk->segs; nsegs != 0; nsegs -= 1, si += 1) {
|
||||||
printf("!!! recorded segment number "PHtx" differs from actual segment number "PHtx"", (ptrdiff_t)seg, (ptrdiff_t)recorded_seg);
|
seginfo *recorded_si; uptr recorded_seg;
|
||||||
}
|
if ((seg = si->number) != (recorded_seg = (chunk->base + chunk->segs - nsegs))) {
|
||||||
if ((recorded_si = SegInfo(seg)) != si) {
|
|
||||||
S_checkheap_errors += 1;
|
|
||||||
printf("!!! recorded segment "PHtx" seginfo "PHtx" differs from actual seginfo "PHtx"", (ptrdiff_t)seg, (ptrdiff_t)recorded_si, (ptrdiff_t)si);
|
|
||||||
}
|
|
||||||
s = si->space;
|
|
||||||
g = si->generation;
|
|
||||||
|
|
||||||
if (si->use_marks)
|
|
||||||
printf("!!! use_marks set on generation %d segment "PHtx"\n", g, (ptrdiff_t)seg);
|
|
||||||
|
|
||||||
if (s == space_new) {
|
|
||||||
if (g != 0 && !si->marked_mask) {
|
|
||||||
S_checkheap_errors += 1;
|
S_checkheap_errors += 1;
|
||||||
printf("!!! unexpected generation %d segment "PHtx" in space_new\n", g, (ptrdiff_t)seg);
|
printf("!!! recorded segment number "PHtx" differs from actual segment number "PHtx"", (ptrdiff_t)seg, (ptrdiff_t)recorded_seg);
|
||||||
}
|
}
|
||||||
} else if (s == space_impure || s == space_symbol || s == space_pure || s == space_weakpair || s == space_ephemeron
|
if ((recorded_si = SegInfo(seg)) != si) {
|
||||||
|| s == space_immobile_impure || s == space_count_pure || s == space_count_impure || s == space_closure
|
S_checkheap_errors += 1;
|
||||||
|| s == space_pure_typed_object || s == space_continuation || s == space_port || s == space_code
|
printf("!!! recorded segment "PHtx" seginfo "PHtx" differs from actual seginfo "PHtx"", (ptrdiff_t)seg, (ptrdiff_t)recorded_si, (ptrdiff_t)si);
|
||||||
|| s == space_impure_record || s == space_impure_typed_object) {
|
}
|
||||||
ptr start;
|
s = si->space;
|
||||||
|
g = si->generation;
|
||||||
/* check for dangling references */
|
|
||||||
pp1 = TO_VOIDP(build_ptr(seg, 0));
|
|
||||||
pp2 = TO_VOIDP(build_ptr(seg + 1, 0));
|
|
||||||
|
|
||||||
nl = FIND_NL(pp1, pp2, s, g);
|
if (si->use_marks)
|
||||||
if (pp1 <= nl && nl < pp2) pp2 = nl;
|
printf("!!! use_marks set on generation %d segment "PHtx"\n", g, (ptrdiff_t)seg);
|
||||||
|
|
||||||
if (s == space_pure_typed_object || s == space_port || s == space_code
|
if (s == space_new) {
|
||||||
|| s == space_impure_record || s == space_impure_typed_object) {
|
if (g != 0 && !si->marked_mask) {
|
||||||
/* only check this segment for objects that start on it */
|
S_checkheap_errors += 1;
|
||||||
uptr before_seg = seg;
|
printf("!!! unexpected generation %d segment "PHtx" in space_new\n", g, (ptrdiff_t)seg);
|
||||||
|
|
||||||
/* Back up over segments for the same space and generation: */
|
|
||||||
while (1) {
|
|
||||||
seginfo *before_si = MaybeSegInfo(before_seg-1);
|
|
||||||
if (!before_si
|
|
||||||
|| (before_si->space != si->space)
|
|
||||||
|| (before_si->generation != si->generation)
|
|
||||||
|| ((before_si->marked_mask == NULL) != (si->marked_mask == NULL)))
|
|
||||||
break;
|
|
||||||
before_seg--;
|
|
||||||
}
|
}
|
||||||
|
} else if (s == space_impure || s == space_symbol || s == space_pure || s == space_weakpair || s == space_ephemeron
|
||||||
|
|| s == space_immobile_impure || s == space_count_pure || s == space_count_impure || s == space_closure
|
||||||
|
|| s == space_pure_typed_object || s == space_continuation || s == space_port || s == space_code
|
||||||
|
|| s == space_impure_record || s == space_impure_typed_object) {
|
||||||
|
ptr start;
|
||||||
|
|
||||||
|
/* check for dangling references */
|
||||||
|
pp1 = TO_VOIDP(build_ptr(seg, 0));
|
||||||
|
pp2 = TO_VOIDP(build_ptr(seg + 1, 0));
|
||||||
|
|
||||||
/* Move forward to reach `seg` again: */
|
nl = FIND_NL(pp1, pp2, s, g);
|
||||||
start = build_ptr(before_seg, 0);
|
if (pp1 <= nl && nl < pp2) pp2 = nl;
|
||||||
while (before_seg != seg) {
|
|
||||||
ptr *before_pp2, *before_nl;
|
|
||||||
|
|
||||||
before_pp2 = TO_VOIDP(build_ptr(before_seg + 1, 0));
|
if (s == space_pure_typed_object || s == space_port || s == space_code
|
||||||
if ((ptr *)TO_VOIDP(start) > before_pp2) {
|
|| s == space_impure_record || s == space_impure_typed_object) {
|
||||||
/* skipped to a further segment */
|
/* only check this segment for objects that start on it */
|
||||||
before_seg++;
|
uptr before_seg = seg;
|
||||||
} else {
|
|
||||||
before_nl = FIND_NL(TO_VOIDP(start), before_pp2, s, g);
|
/* Back up over segments for the same space and generation: */
|
||||||
if (((ptr*)TO_VOIDP(start)) <= before_nl && before_nl < before_pp2) {
|
while (1) {
|
||||||
/* this segment ends, so move to next segment */
|
seginfo *before_si = MaybeSegInfo(before_seg-1);
|
||||||
|
if (!before_si
|
||||||
|
|| (before_si->space != si->space)
|
||||||
|
|| (before_si->generation != si->generation)
|
||||||
|
|| ((before_si->marked_mask == NULL) != (si->marked_mask == NULL)))
|
||||||
|
break;
|
||||||
|
before_seg--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Move forward to reach `seg` again: */
|
||||||
|
start = build_ptr(before_seg, 0);
|
||||||
|
while (before_seg != seg) {
|
||||||
|
ptr *before_pp2, *before_nl;
|
||||||
|
|
||||||
|
before_pp2 = TO_VOIDP(build_ptr(before_seg + 1, 0));
|
||||||
|
if ((ptr *)TO_VOIDP(start) > before_pp2) {
|
||||||
|
/* skipped to a further segment */
|
||||||
before_seg++;
|
before_seg++;
|
||||||
if (s == space_code) {
|
|
||||||
/* in the case of code, it's possible for a whole segment to
|
|
||||||
go unused if a large code object didn't fit; give up, just in case */
|
|
||||||
start = build_ptr(seg+1, 0);
|
|
||||||
} else {
|
|
||||||
start = build_ptr(before_seg, 0);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
seginfo *before_si = MaybeSegInfo(before_seg);
|
before_nl = FIND_NL(TO_VOIDP(start), before_pp2, s, g);
|
||||||
while (((ptr *)TO_VOIDP(start)) < before_pp2) {
|
if (((ptr*)TO_VOIDP(start)) <= before_nl && before_nl < before_pp2) {
|
||||||
if (before_si->marked_mask) {
|
/* this segment ends, so move to next segment */
|
||||||
if (before_si->marked_mask[segment_bitmap_byte(start)] & segment_bitmap_bit(start)) {
|
before_seg++;
|
||||||
start = (ptr)((uptr)start + size_object(TYPE(start, type_typed_object)));
|
if (s == space_code) {
|
||||||
} else {
|
/* in the case of code, it's possible for a whole segment to
|
||||||
/* skip past unmarked */
|
go unused if a large code object didn't fit; give up, just in case */
|
||||||
start = (ptr)((uptr)start + byte_alignment);
|
start = build_ptr(seg+1, 0);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (*(ptr *)TO_VOIDP(start) == forward_marker) {
|
start = build_ptr(before_seg, 0);
|
||||||
/* this segment ends, so move to next segment */
|
}
|
||||||
if (s == space_code) {
|
} else {
|
||||||
start = build_ptr(seg+1, 0);
|
seginfo *before_si = MaybeSegInfo(before_seg);
|
||||||
|
while (((ptr *)TO_VOIDP(start)) < before_pp2) {
|
||||||
|
if (before_si->marked_mask) {
|
||||||
|
if (before_si->marked_mask[segment_bitmap_byte(start)] & segment_bitmap_bit(start)) {
|
||||||
|
start = (ptr)((uptr)start + size_object(TYPE(start, type_typed_object)));
|
||||||
} else {
|
} else {
|
||||||
start = build_ptr(before_seg+1, 0);
|
/* skip past unmarked */
|
||||||
|
start = (ptr)((uptr)start + byte_alignment);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
start = (ptr)((uptr)start + size_object(TYPE(start, type_typed_object)));
|
if (*(ptr *)TO_VOIDP(start) == forward_marker) {
|
||||||
|
/* this segment ends, so move to next segment */
|
||||||
|
if (s == space_code) {
|
||||||
|
start = build_ptr(seg+1, 0);
|
||||||
|
} else {
|
||||||
|
start = build_ptr(before_seg+1, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
start = (ptr)((uptr)start + size_object(TYPE(start, type_typed_object)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
before_seg++;
|
||||||
}
|
}
|
||||||
before_seg++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (((ptr *)TO_VOIDP(start)) >= pp2) {
|
if (((ptr *)TO_VOIDP(start)) >= pp2) {
|
||||||
/* previous object extended past the segment */
|
/* previous object extended past the segment */
|
||||||
} else {
|
} else {
|
||||||
pp1 = TO_VOIDP(start);
|
pp1 = TO_VOIDP(start);
|
||||||
while (pp1 < pp2) {
|
while (pp1 < pp2) {
|
||||||
if (si->marked_mask) {
|
if (si->marked_mask) {
|
||||||
if (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1))) {
|
if (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1))) {
|
||||||
p = TYPE(TO_PTR(pp1), type_typed_object);
|
p = TYPE(TO_PTR(pp1), type_typed_object);
|
||||||
check_object(p, seg, s, aftergc);
|
check_object(p, seg, s, aftergc);
|
||||||
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + size_object(p)));
|
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + size_object(p)));
|
||||||
} else {
|
|
||||||
/* skip past unmarked */
|
|
||||||
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + byte_alignment));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (*pp1 == forward_marker)
|
|
||||||
break;
|
|
||||||
else {
|
|
||||||
p = TYPE(TO_PTR(pp1), type_typed_object);
|
|
||||||
check_object(p, seg, s, aftergc);
|
|
||||||
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + size_object(p)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (s == space_continuation) {
|
|
||||||
while (pp1 < pp2) {
|
|
||||||
if (*pp1 == forward_marker)
|
|
||||||
break;
|
|
||||||
if (!si->marked_mask || (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1)))) {
|
|
||||||
p = TYPE(TO_PTR(pp1), type_closure);
|
|
||||||
check_object(p, seg, s, aftergc);
|
|
||||||
}
|
|
||||||
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + size_continuation));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (pp1 < pp2) {
|
|
||||||
if (!si->marked_mask || (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1)))) {
|
|
||||||
int a;
|
|
||||||
for (a = 0; (a < ptr_alignment) && (pp1 < pp2); a++) {
|
|
||||||
#define in_ephemeron_pair_part(pp1, seg) ((((uptr)TO_PTR(pp1) - (uptr)build_ptr(seg, 0)) % size_ephemeron) < size_pair)
|
|
||||||
if ((s == space_ephemeron) && !in_ephemeron_pair_part(pp1, seg)) {
|
|
||||||
/* skip non-pair part of ephemeron */
|
|
||||||
} else {
|
|
||||||
p = *pp1;
|
|
||||||
if (!si->marked_mask && (p == forward_marker)) {
|
|
||||||
pp1 = pp2; /* break out of outer loop */
|
|
||||||
break;
|
|
||||||
} else {
|
} else {
|
||||||
check_pointer(pp1, 1, (ptr)0, seg, s, aftergc);
|
/* skip past unmarked */
|
||||||
|
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + byte_alignment));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (*pp1 == forward_marker)
|
||||||
|
break;
|
||||||
|
else {
|
||||||
|
p = TYPE(TO_PTR(pp1), type_typed_object);
|
||||||
|
check_object(p, seg, s, aftergc);
|
||||||
|
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + size_object(p)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pp1 += 1;
|
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
pp1 += ptr_alignment;
|
} else if (s == space_continuation) {
|
||||||
}
|
while (pp1 < pp2) {
|
||||||
}
|
if (*pp1 == forward_marker)
|
||||||
|
break;
|
||||||
/* further verify that dirty bits are set appropriately; only handles some spaces
|
if (!si->marked_mask || (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1)))) {
|
||||||
to make sure that the dirty byte is not unnecessarily approximate, but we have also
|
p = TYPE(TO_PTR(pp1), type_closure);
|
||||||
checked dirty bytes alerady via `check_pointer` */
|
check_object(p, seg, s, aftergc);
|
||||||
if (s == space_impure || s == space_symbol || s == space_weakpair || s == space_ephemeron
|
|
||||||
|| s == space_immobile_impure || s == space_closure) {
|
|
||||||
found_eos = 0;
|
|
||||||
pp2 = pp1 = TO_VOIDP(build_ptr(seg, 0));
|
|
||||||
for (d = 0; d < cards_per_segment; d += 1) {
|
|
||||||
if (found_eos) {
|
|
||||||
if (si->dirty_bytes[d] != 0xff) {
|
|
||||||
S_checkheap_errors += 1;
|
|
||||||
printf("!!! Dirty byte set past end-of-segment for segment "PHtx", card %d\n", (ptrdiff_t)seg, d);
|
|
||||||
segment_tell(seg);
|
|
||||||
}
|
}
|
||||||
continue;
|
pp1 = TO_VOIDP((ptr)((uptr)TO_PTR(pp1) + size_continuation));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
pp2 += bytes_per_card / sizeof(ptr);
|
|
||||||
if (pp1 <= nl && nl < pp2) {
|
|
||||||
found_eos = 1;
|
|
||||||
pp2 = nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf("pp1 = "PHtx", pp2 = "PHtx", nl = "PHtx"\n", (ptrdiff_t)pp1, (ptrdiff_t)pp2, (ptrdiff_t)nl);
|
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dirty = 0xff;
|
|
||||||
while (pp1 < pp2) {
|
while (pp1 < pp2) {
|
||||||
if (!si->marked_mask || (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1)))) {
|
if (!si->marked_mask || (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1)))) {
|
||||||
int a;
|
int a;
|
||||||
for (a = 0; (a < ptr_alignment) && (pp1 < pp2); a++) {
|
for (a = 0; (a < ptr_alignment) && (pp1 < pp2); a++) {
|
||||||
|
#define in_ephemeron_pair_part(pp1, seg) ((((uptr)TO_PTR(pp1) - (uptr)build_ptr(seg, 0)) % size_ephemeron) < size_pair)
|
||||||
if ((s == space_ephemeron) && !in_ephemeron_pair_part(pp1, seg)) {
|
if ((s == space_ephemeron) && !in_ephemeron_pair_part(pp1, seg)) {
|
||||||
/* skip non-pair part of ephemeron */
|
/* skip non-pair part of ephemeron */
|
||||||
} else {
|
} else {
|
||||||
p = *pp1;
|
p = *pp1;
|
||||||
|
if (!si->marked_mask && (p == forward_marker)) {
|
||||||
if (p == forward_marker) {
|
pp1 = pp2; /* break out of outer loop */
|
||||||
found_eos = 1;
|
|
||||||
pp1 = pp2;
|
|
||||||
break;
|
break;
|
||||||
} else if (!IMMEDIATE(p)) {
|
} else {
|
||||||
seginfo *psi = MaybeSegInfo(ptr_get_segment(p));
|
check_pointer(pp1, 1, (ptr)0, seg, s, aftergc);
|
||||||
if ((psi != NULL) && ((pg = psi->generation) < g)) {
|
|
||||||
if (pg < dirty) dirty = pg;
|
|
||||||
if (si->dirty_bytes[d] > pg) {
|
|
||||||
S_checkheap_errors += 1;
|
|
||||||
check_heap_dirty_msg("!!! INVALID", pp1);
|
|
||||||
} else if (checkheap_noisy)
|
|
||||||
check_heap_dirty_msg("... ", pp1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pp1 += 1;
|
pp1 += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
pp1 += ptr_alignment;
|
pp1 += ptr_alignment;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (checkheap_noisy && si->dirty_bytes[d] < dirty) {
|
|
||||||
/* sweep_dirty won't sweep, and update dirty byte, for
|
|
||||||
cards with dirty pointers to segments older than the
|
|
||||||
maximum copyied generation, so we can get legitimate
|
|
||||||
conservative dirty bytes even after gc */
|
|
||||||
printf("... Conservative dirty byte %x (%x) %sfor segment "PHtx" card %d ",
|
|
||||||
si->dirty_bytes[d], dirty,
|
|
||||||
(aftergc ? "after gc " : ""),
|
|
||||||
(ptrdiff_t)seg, d);
|
|
||||||
segment_tell(seg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* at least check that no dirty bytes are set beyond the end of the segment */
|
|
||||||
if (pp2 < (ptr *)TO_VOIDP(build_ptr(seg + 1, 0))) {
|
|
||||||
uptr card = (uptr)TO_PTR(pp2) >> card_offset_bits;
|
|
||||||
int d = (int)(card & ((1 << segment_card_offset_bits) - 1));
|
|
||||||
|
|
||||||
for (d++; d < cards_per_segment; d++) {
|
/* further verify that dirty bits are set appropriately; only handles some spaces
|
||||||
if (si->dirty_bytes[d] != 0xff) {
|
to make sure that the dirty byte is not unnecessarily approximate, but we have also
|
||||||
S_checkheap_errors += 1;
|
checked dirty bytes alerady via `check_pointer` */
|
||||||
printf("!!! Dirty byte set past end-of-segment for segment "PHtx", card %d\n", (ptrdiff_t)seg, d);
|
if (s == space_impure || s == space_symbol || s == space_weakpair || s == space_ephemeron
|
||||||
|
|| s == space_immobile_impure || s == space_closure) {
|
||||||
|
found_eos = 0;
|
||||||
|
pp2 = pp1 = TO_VOIDP(build_ptr(seg, 0));
|
||||||
|
for (d = 0; d < cards_per_segment; d += 1) {
|
||||||
|
if (found_eos) {
|
||||||
|
if (si->dirty_bytes[d] != 0xff) {
|
||||||
|
S_checkheap_errors += 1;
|
||||||
|
printf("!!! Dirty byte set past end-of-segment for segment "PHtx", card %d\n", (ptrdiff_t)seg, d);
|
||||||
|
segment_tell(seg);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
pp2 += bytes_per_card / sizeof(ptr);
|
||||||
|
if (pp1 <= nl && nl < pp2) {
|
||||||
|
found_eos = 1;
|
||||||
|
pp2 = nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf("pp1 = "PHtx", pp2 = "PHtx", nl = "PHtx"\n", (ptrdiff_t)pp1, (ptrdiff_t)pp2, (ptrdiff_t)nl);
|
||||||
|
fflush(stdout);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dirty = 0xff;
|
||||||
|
while (pp1 < pp2) {
|
||||||
|
if (!si->marked_mask || (si->marked_mask[segment_bitmap_byte(TO_PTR(pp1))] & segment_bitmap_bit(TO_PTR(pp1)))) {
|
||||||
|
int a;
|
||||||
|
for (a = 0; (a < ptr_alignment) && (pp1 < pp2); a++) {
|
||||||
|
if ((s == space_ephemeron) && !in_ephemeron_pair_part(pp1, seg)) {
|
||||||
|
/* skip non-pair part of ephemeron */
|
||||||
|
} else {
|
||||||
|
p = *pp1;
|
||||||
|
|
||||||
|
if (p == forward_marker) {
|
||||||
|
found_eos = 1;
|
||||||
|
pp1 = pp2;
|
||||||
|
break;
|
||||||
|
} else if (!IMMEDIATE(p)) {
|
||||||
|
seginfo *psi = MaybeSegInfo(ptr_get_segment(p));
|
||||||
|
if ((psi != NULL) && ((pg = psi->generation) < g)) {
|
||||||
|
if (pg < dirty) dirty = pg;
|
||||||
|
if (si->dirty_bytes[d] > pg) {
|
||||||
|
S_checkheap_errors += 1;
|
||||||
|
check_heap_dirty_msg("!!! INVALID", pp1);
|
||||||
|
} else if (checkheap_noisy)
|
||||||
|
check_heap_dirty_msg("... ", pp1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pp1 += 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pp1 += ptr_alignment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checkheap_noisy && si->dirty_bytes[d] < dirty) {
|
||||||
|
/* sweep_dirty won't sweep, and update dirty byte, for
|
||||||
|
cards with dirty pointers to segments older than the
|
||||||
|
maximum copyied generation, so we can get legitimate
|
||||||
|
conservative dirty bytes even after gc */
|
||||||
|
printf("... Conservative dirty byte %x (%x) %sfor segment "PHtx" card %d ",
|
||||||
|
si->dirty_bytes[d], dirty,
|
||||||
|
(aftergc ? "after gc " : ""),
|
||||||
|
(ptrdiff_t)seg, d);
|
||||||
segment_tell(seg);
|
segment_tell(seg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* at least check that no dirty bytes are set beyond the end of the segment */
|
||||||
|
if (pp2 < (ptr *)TO_VOIDP(build_ptr(seg + 1, 0))) {
|
||||||
|
uptr card = (uptr)TO_PTR(pp2) >> card_offset_bits;
|
||||||
|
int d = (int)(card & ((1 << segment_card_offset_bits) - 1));
|
||||||
|
|
||||||
|
for (d++; d < cards_per_segment; d++) {
|
||||||
|
if (si->dirty_bytes[d] != 0xff) {
|
||||||
|
S_checkheap_errors += 1;
|
||||||
|
printf("!!! Dirty byte set past end-of-segment for segment "PHtx", card %d\n", (ptrdiff_t)seg, d);
|
||||||
|
segment_tell(seg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (aftergc
|
||||||
|
&& (s != space_empty)
|
||||||
|
&& (g == 0
|
||||||
|
|| (s != space_new && s != space_impure && s != space_symbol && s != space_port && s != space_weakpair && s != space_ephemeron
|
||||||
|
&& s != space_impure_record && s != space_impure_typed_object
|
||||||
|
&& s != space_immobile_impure && s != space_count_impure && s != space_closure))) {
|
||||||
|
for (d = 0; d < cards_per_segment; d += 1) {
|
||||||
|
if (si->dirty_bytes[d] != 0xff) {
|
||||||
|
S_checkheap_errors += 1;
|
||||||
|
printf("!!! Unnecessary dirty byte %x (%x) after gc for segment "PHtx" card %d ",
|
||||||
|
si->dirty_bytes[d], 0xff, (ptrdiff_t)(si->number), d);
|
||||||
|
segment_tell(seg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aftergc
|
chunk = chunk->next;
|
||||||
&& (s != space_empty)
|
|
||||||
&& (g == 0
|
|
||||||
|| (s != space_new && s != space_impure && s != space_symbol && s != space_port && s != space_weakpair && s != space_ephemeron
|
|
||||||
&& s != space_impure_record && s != space_impure_typed_object
|
|
||||||
&& s != space_immobile_impure && s != space_count_impure && s != space_closure))) {
|
|
||||||
for (d = 0; d < cards_per_segment; d += 1) {
|
|
||||||
if (si->dirty_bytes[d] != 0xff) {
|
|
||||||
S_checkheap_errors += 1;
|
|
||||||
printf("!!! Unnecessary dirty byte %x (%x) after gc for segment "PHtx" card %d ",
|
|
||||||
si->dirty_bytes[d], 0xff, (ptrdiff_t)(si->number), d);
|
|
||||||
segment_tell(seg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
chunk = chunk->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,6 +275,10 @@ static ptr sorted_chunk_list(void) {
|
||||||
ls = Scons(TO_PTR(chunk), ls);
|
ls = Scons(TO_PTR(chunk), ls);
|
||||||
n += 1;
|
n += 1;
|
||||||
}
|
}
|
||||||
|
for (chunk = (i == -1) ? S_code_chunks_full : S_code_chunks[i]; chunk != NULL; chunk = chunk->next) {
|
||||||
|
ls = Scons(TO_PTR(chunk), ls);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sort_chunks(ls, n);
|
return sort_chunks(ls, n);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user