@@ -320,7 +320,6 @@ static int64_t scanned_bytes; // young bytes scanned while marking
320
320
static int64_t perm_scanned_bytes ; // old bytes scanned while marking
321
321
static int prev_sweep_mask = GC_MARKED ;
322
322
323
- static size_t array_nbytes (jl_array_t * );
324
323
#define inc_sat (v ,s ) v = (v) >= s ? s : (v)+1
325
324
326
325
// Full collection heuristics
@@ -415,8 +414,9 @@ static inline int gc_setmark_pool(void *o, int mark_mode)
415
414
objprofile_count (jl_typeof (jl_valueof (o )),
416
415
mark_mode == GC_MARKED , page -> osize );
417
416
}
417
+ assert (mark_mode & GC_MARKED );
418
+ page -> has_marked = 1 ;
418
419
_gc_setmark (o , mark_mode );
419
- page -> gc_bits |= mark_mode ;
420
420
verify_val (jl_valueof (o ));
421
421
return mark_mode ;
422
422
}
@@ -667,15 +667,15 @@ static void sweep_malloced_arrays(void)
667
667
// pool allocation
668
668
static inline gcval_t * reset_page (jl_gc_pool_t * p , jl_gc_pagemeta_t * pg , gcval_t * fl )
669
669
{
670
- pg -> gc_bits = 0 ;
671
670
pg -> nfree = (GC_PAGE_SZ - GC_PAGE_OFFSET ) / p -> osize ;
672
671
jl_tls_states_t * ptls = jl_all_tls_states [pg -> thread_n ];
673
672
pg -> pool_n = p - ptls -> heap .norm_pools ;
674
673
memset (pg -> ages , 0 , GC_PAGE_SZ / 8 / p -> osize + 1 );
675
674
gcval_t * beg = (gcval_t * )(pg -> data + GC_PAGE_OFFSET );
676
675
gcval_t * end = (gcval_t * )((char * )beg + (pg -> nfree - 1 )* p -> osize );
677
676
end -> next = fl ;
678
- pg -> allocd = 0 ;
677
+ pg -> has_young = 0 ;
678
+ pg -> has_marked = 0 ;
679
679
pg -> fl_begin_offset = GC_PAGE_OFFSET ;
680
680
pg -> fl_end_offset = (char * )end - (char * )beg + GC_PAGE_OFFSET ;
681
681
return beg ;
@@ -724,7 +724,7 @@ static inline void *__pool_alloc(jl_gc_pool_t *p, int osize, int end_offset)
724
724
jl_gc_pagemeta_t * pg = page_metadata (v );
725
725
assert (pg -> osize == p -> osize );
726
726
pg -> nfree = 0 ;
727
- pg -> allocd = 1 ;
727
+ pg -> has_young = 1 ;
728
728
if (next )
729
729
p -> nfree = page_metadata (next )-> nfree ;
730
730
}
@@ -745,7 +745,7 @@ static inline void *__pool_alloc(jl_gc_pool_t *p, int osize, int end_offset)
745
745
jl_gc_pagemeta_t * pg = page_metadata (v );
746
746
assert (pg -> osize == p -> osize );
747
747
pg -> nfree = 0 ;
748
- pg -> allocd = 1 ;
748
+ pg -> has_young = 1 ;
749
749
p -> newpages = v -> next ;
750
750
}
751
751
v -> flags = 0 ;
@@ -873,12 +873,15 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
873
873
freedall = 1 ;
874
874
old_nfree += pg -> nfree ;
875
875
876
- if (pg -> gc_bits == GC_MARKED ) {
877
- // this page only contains GC_MARKED and free cells
878
- // if we are doing a quick sweep and nothing has been allocated inside since last sweep
879
- // we can skip it
880
- if (sweep_mask == GC_MARKED_NOESC && !pg -> allocd ) {
881
- // the position of the freelist begin/end in this page is stored in its metadata
876
+ if (!pg -> has_marked )
877
+ goto free_page ;
878
+ // For quick sweep, we might be able to skip the page if the page doesn't
879
+ // have any young live cell before marking.
880
+ 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 ) {
883
+ // the position of the freelist begin/end in this page
884
+ // is stored in its metadata
882
885
if (pg -> fl_begin_offset != (uint16_t )-1 ) {
883
886
* pfl = page_pfl_beg (pg );
884
887
pfl = prev_pfl = (gcval_t * * )page_pfl_end (pg );
@@ -888,11 +891,10 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
888
891
goto free_page ;
889
892
}
890
893
}
891
- else if (pg -> gc_bits == GC_CLEAN ) {
892
- goto free_page ;
893
- }
894
894
895
895
{ // scope to avoid clang goto errors
896
+ int has_marked = 0 ;
897
+ int has_young = 0 ;
896
898
int pg_nfree = 0 ;
897
899
gcval_t * * pfl_begin = NULL ;
898
900
uint8_t msk = 1 ; // mask for the age bit in the current age byte
@@ -906,14 +908,19 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
906
908
* ages &= ~msk ;
907
909
}
908
910
else { // marked young or old
909
- if (* ages & msk ) { // old enough
911
+ if (* ages & msk || bits == GC_MARKED ) { // old enough
912
+ // `!age && bits == GC_MARKED` is possible for
913
+ // non-first-class objects like `jl_binding_t`
910
914
if (sweep_mask == GC_MARKED || bits == GC_MARKED_NOESC ) {
911
- gc_bits (v ) = GC_QUEUED ; // promote
915
+ bits = gc_bits (v ) = GC_QUEUED ; // promote
912
916
}
913
917
}
914
- else if ((sweep_mask & bits ) == sweep_mask ) {
915
- gc_bits (v ) = GC_CLEAN ; // unmark
918
+ else {
919
+ assert (bits == GC_MARKED_NOESC );
920
+ bits = gc_bits (v ) = GC_CLEAN ; // unmark
921
+ has_young = 1 ;
916
922
}
923
+ has_marked |= (bits & GC_MARKED ) != 0 ;
917
924
* ages |= msk ;
918
925
freedall = 0 ;
919
926
}
@@ -925,12 +932,14 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
925
932
}
926
933
}
927
934
935
+ assert (!freedall );
936
+ pg -> has_marked = has_marked ;
937
+ pg -> has_young = has_young ;
928
938
pg -> fl_begin_offset = pfl_begin ? (char * )pfl_begin - data : (uint16_t )-1 ;
929
939
pg -> fl_end_offset = pfl_begin ? (char * )pfl - data : (uint16_t )-1 ;
930
940
931
941
pg -> nfree = pg_nfree ;
932
942
page_done ++ ;
933
- pg -> allocd = 0 ;
934
943
}
935
944
free_page :
936
945
pg_freedall += freedall ;
@@ -966,10 +975,6 @@ static gcval_t **sweep_page(jl_gc_pool_t *p, jl_gc_pagemeta_t *pg, gcval_t **pfl
966
975
nfree += obj_per_page ;
967
976
}
968
977
else {
969
- if (sweep_mask == GC_MARKED )
970
- pg -> gc_bits = GC_CLEAN ;
971
- if (sweep_mask == GC_MARKED_NOESC )
972
- pg -> gc_bits = GC_MARKED ;
973
978
nfree += pg -> nfree ;
974
979
}
975
980
@@ -1024,7 +1029,7 @@ static int gc_sweep_inc(int sweep_mask)
1024
1029
gcval_t * last = p -> freelist ;
1025
1030
if (last ) {
1026
1031
jl_gc_pagemeta_t * pg = page_metadata (last );
1027
- pg -> allocd = 1 ;
1032
+ pg -> has_young = 1 ;
1028
1033
pg -> nfree = p -> nfree ;
1029
1034
}
1030
1035
p -> freelist = NULL ;
@@ -1034,7 +1039,7 @@ static int gc_sweep_inc(int sweep_mask)
1034
1039
if (last ) {
1035
1040
jl_gc_pagemeta_t * pg = page_metadata (last );
1036
1041
pg -> nfree = (GC_PAGE_SZ - ((char * )last - gc_page_data (last ))) / p -> osize ;
1037
- pg -> allocd = 1 ;
1042
+ pg -> has_young = 1 ;
1038
1043
}
1039
1044
p -> newpages = NULL ;
1040
1045
}
0 commit comments