Resweep after compaction in a separate pass.

This commit is contained in:
Hayley Patton 2024-01-22 20:37:00 +11:00 committed by Stas Boukarev
parent e75515a6a0
commit 3830ae2246
3 changed files with 40 additions and 30 deletions

View file

@ -177,29 +177,7 @@ static void move_objects() {
lispobj bogus = compute_lispobj(where);
scavenge(&bogus, 1);
}
/* Free all lines we just copied from. */
uword_t decrement = 0;
char *allocation = (char*)allocation_bitmap;
for_lines_in_page (l, p)
if (DECODE_GEN(line_bytemap[l]) == target_generation) {
line_bytemap[l] = 0;
allocation[l] = 0;
decrement++;
}
set_page_bytes_used(p, page_bytes_used(p) - LINE_SIZE * decrement);
generations[target_generation].bytes_allocated -= LINE_SIZE * decrement;
bytes_allocated -= LINE_SIZE * decrement;
if (page_words_used(p) == 0) {
set_page_need_to_zero(p, 1);
#ifdef LISP_FEATURE_DARWIN_JIT
reset_page_flags(p);
#else
set_page_type(page_table[p], FREE_PAGE_FLAG);
page_table[p].scan_start_offset_ = 0;
#endif
}
}
if (force_compaction && !lisp_startup_options.noinform)
fprintf(stderr, "Forced compaction moved %ld pages\n", pages_moved);
}
@ -281,7 +259,36 @@ static void fix_slots() {
}
}
void run_compaction(_Atomic(uword_t) *copy_meter, _Atomic(uword_t) *fix_meter) {
static void resweep_moved_lines() {
unsigned char *allocation = (unsigned char*)allocation_bitmap;
for (page_index_t p = 0; p < page_table_pages; p++) {
if (target_pages[p] && !page_single_obj_p(p)) {
uword_t decrement = 0;
for_lines_in_page (l, p)
if (DECODE_GEN(line_bytemap[l]) == target_generation) {
line_bytemap[l] = 0;
allocation[l] = 0;
decrement++;
}
set_page_bytes_used(p, page_bytes_used(p) - LINE_SIZE * decrement);
generations[target_generation].bytes_allocated -= LINE_SIZE * decrement;
bytes_allocated -= LINE_SIZE * decrement;
if (page_words_used(p) == 0) {
set_page_need_to_zero(p, 1);
#ifdef LISP_FEATURE_DARWIN_JIT
reset_page_flags(p);
#else
set_page_type(page_table[p], FREE_PAGE_FLAG);
page_table[p].scan_start_offset_ = 0;
#endif
}
}
}
}
void run_compaction(_Atomic(uword_t) *copy_meter,
_Atomic(uword_t) *fix_meter,
_Atomic(uword_t) *resweep_meter) {
if (compacting) {
/* Check again, in case fragmentation somehow improves.
* Not likely, but it's a cheap test which avoids effort. */
@ -290,6 +297,7 @@ void run_compaction(_Atomic(uword_t) *copy_meter, _Atomic(uword_t) *fix_meter) {
METER(copy_meter, move_objects());
gc_close_collector_regions(0);
METER(fix_meter, fix_slots());
METER(resweep_meter, resweep_moved_lines());
should_compact("I just moved, but still");
}
memset(target_pages, 0, page_table_pages);

View file

@ -14,7 +14,9 @@ extern uword_t bytes_to_copy;
extern bool compacting;
extern void compactor_init();
extern void consider_compaction(generation_index_t gen);
extern void run_compaction(_Atomic(uword_t) *copy_meter, _Atomic(uword_t) *fix_meter);
extern void run_compaction(_Atomic(uword_t) *copy_meter,
_Atomic(uword_t) *fix_meter,
_Atomic(uword_t) *resweep_meter);
/* Tracing/logging interface */
extern unsigned char *target_pages;

View file

@ -56,7 +56,7 @@ static struct {
_Atomic(uword_t) consider, scavenge, prefix;
_Atomic(uword_t) trace, trace_alive, trace_running;
_Atomic(uword_t) sweep, weak, sweep_lines, sweep_pages;
_Atomic(uword_t) compact, copy, fix, raise;
_Atomic(uword_t) compact, copy, fix, compact_resweep, raise;
uword_t fresh_pointers; uword_t pinned_pages;
uword_t compacts;
} meters = { 0 };
@ -72,14 +72,14 @@ void mr_print_meters() {
"collection %d (%.0f%% compacting):\n"
" %ldus consider\n"
" %ld scavenge (%ld prefixes) %ld trace (%ld alive %ld running)\n"
" %ld sweep (%ld lines %ld pages) %ld compact (%ld copy %ld fix)\n"
" %ld sweep (%ld lines %ld pages) %ld compact (%ld copy %ld fix %ld resweep)\n"
" %ld raise; %ldB fresh %ldpg pinned\n",
collection,
collection ? 100.0 * (float)meters.compacts / collection : 0.0,
NORM(consider), NORM(scavenge), NORM(prefix),
NORM(trace), NORM(trace_alive), NORM(trace_running),
NORM(sweep), NORM(sweep_lines), NORM(sweep_pages),
NORM(compact), NORM(copy), NORM(fix),
NORM(compact), NORM(copy), NORM(fix), NORM(compact_resweep),
NORM(raise), NORM(fresh_pointers), NORM(pinned_pages));
#undef NORM
}
@ -1210,7 +1210,7 @@ void mr_collect_garbage(bool raise) {
* we could snoop TLS of each GC thread instead. */
run_on_thread_pool(commit_thread_local_remset);
reset_alloc_start_pages(true);
METER(compact, run_compaction(&meters.copy, &meters.fix));
METER(compact, run_compaction(&meters.copy, &meters.fix, &meters.compact_resweep));
}
#endif
/* scan_finalizers checks forwarding pointers, so we need to
@ -1305,11 +1305,11 @@ void find_references_to(lispobj something) {
void draw_page_table(int from, int to) {
fprintf(stderr, "\n ");
for (int i = 0; i < 50; i++)
fprintf(stderr, "%3d", i);
fprintf(stderr, "%3d ", i);
for (int i = from; i < to; i++) {
if (i % 50 == 0) fprintf(stderr, "\n%6d ", i);
fprintf(stderr,
"\033[%c;9%cm%c%c%c\033[0m",
"\033[%c;9%cm%c%c%c\033[0m ",
(page_table[i].type & SINGLE_OBJECT_FLAG) ? '1' : '0',
'0' + (page_table[i].type & 7),
64 + page_table[i].type,