Skip to content

Commit 45a012e

Browse files
committed
Add old object counter for sweep2 fast path
1 parent 15bdcbc commit 45a012e

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

src/gc.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -407,10 +407,13 @@ static inline int gc_setmark_pool(void *o, int mark_mode)
407407
mark_mode = GC_MARKED;
408408
}
409409
if (!(bits & GC_MARKED)) {
410-
if (mark_mode == GC_MARKED)
410+
if (mark_mode == GC_MARKED) {
411411
perm_scanned_bytes += page->osize;
412-
else
412+
page->nold++;
413+
}
414+
else {
413415
scanned_bytes += page->osize;
416+
}
414417
objprofile_count(jl_typeof(jl_valueof(o)),
415418
mark_mode == GC_MARKED, page->osize);
416419
}
@@ -878,8 +881,8 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
878881
// For quick sweep, we might be able to skip the page if the page doesn't
879882
// have any young live cell before marking.
880883
if (sweep_mask == GC_MARKED_NOESC && !pg->has_young) {
881-
// TODO handle `prev_sweep_mask == GC_MARKED` with additional counters
882-
if (prev_sweep_mask == GC_MARKED_NOESC) {
884+
assert(prev_sweep_mask == GC_MARKED_NOESC || pg->prev_nold >= pg->nold);
885+
if (prev_sweep_mask == GC_MARKED_NOESC || pg->prev_nold == pg->nold) {
883886
// the position of the freelist begin/end in this page
884887
// is stored in its metadata
885888
if (pg->fl_begin_offset != (uint16_t)-1) {
@@ -895,6 +898,7 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
895898
{ // scope to avoid clang goto errors
896899
int has_marked = 0;
897900
int has_young = 0;
901+
int16_t prev_nold = 0;
898902
int pg_nfree = 0;
899903
gcval_t **pfl_begin = NULL;
900904
uint8_t msk = 1; // mask for the age bit in the current age byte
@@ -914,6 +918,7 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
914918
if (sweep_mask == GC_MARKED || bits == GC_MARKED_NOESC) {
915919
bits = gc_bits(v) = GC_QUEUED; // promote
916920
}
921+
prev_nold++;
917922
}
918923
else {
919924
assert(bits == GC_MARKED_NOESC);
@@ -939,6 +944,10 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
939944
pg->fl_end_offset = pfl_begin ? (char*)pfl - data : (uint16_t)-1;
940945

941946
pg->nfree = pg_nfree;
947+
if (sweep_mask == GC_MARKED) {
948+
pg->nold = 0;
949+
pg->prev_nold = prev_nold;
950+
}
942951
page_done++;
943952
}
944953
free_page:

src/gc.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,17 @@ typedef struct {
154154
//
155155
// For a quick sweep preceded by a full sweep. If this bit is set,
156156
// the page needs to be swept. If this bit is not set, there could
157-
// still be old dead objects in the page.
157+
// still be old dead objects in the page and `nold` and `prev_nold`
158+
// should be used to determine if the page needs to be swept.
158159
uint16_t has_young: 1;
159160
};
160-
uint16_t nfree; // number of free objects in this page.
161-
// invalid if pool that owns this page is allocating objects from this page.
161+
// number of old objects in this page
162+
uint16_t nold;
163+
// number of old objects in this page during the previous full sweep
164+
uint16_t prev_nold;
165+
// number of free objects in this page.
166+
// invalid if pool that owns this page is allocating objects from this page.
167+
uint16_t nfree;
162168
uint16_t osize; // size of each object in this page
163169
uint16_t fl_begin_offset; // offset of first free object in this page
164170
uint16_t fl_end_offset; // offset of last free object in this page

0 commit comments

Comments
 (0)