Skip to content

Commit 8b19f5f

Browse files
authored
Merge pull request JuliaLang#49185 from gbaraldi/image_bit
Add bit to the GC tag to turn GC in image search O(1) and also increase gc interval when encountering many pointers
2 parents cd394eb + 450c1fa commit 8b19f5f

File tree

4 files changed

+29
-9
lines changed

4 files changed

+29
-9
lines changed

src/gc.c

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,7 @@ FORCE_INLINE void gc_mark_outrefs(jl_ptls_t ptls, jl_gc_markqueue_t *mq, void *_
23902390
int update_meta = __likely(!meta_updated && !gc_verifying);
23912391
int foreign_alloc = 0;
23922392
// directly point at eyt_obj_in_img to encourage inlining
2393-
if (update_meta && eyt_obj_in_img(new_obj)) {
2393+
if (update_meta && o->bits.in_image) {
23942394
foreign_alloc = 1;
23952395
update_meta = 0;
23962396
}
@@ -3059,12 +3059,14 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
30593059

30603060
// update heuristics only if this GC was automatically triggered
30613061
if (collection == JL_GC_AUTO) {
3062-
if (not_freed_enough) {
3063-
gc_num.interval = gc_num.interval * 2;
3064-
}
30653062
if (large_frontier) {
30663063
sweep_full = 1;
3064+
gc_num.interval = last_long_collect_interval;
30673065
}
3066+
if (not_freed_enough || large_frontier) {
3067+
gc_num.interval = gc_num.interval * 2;
3068+
}
3069+
30683070
size_t maxmem = 0;
30693071
#ifdef _P64
30703072
// on a big memory machine, increase max_collect_interval to totalmem / nthreads / 2
@@ -3097,6 +3099,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
30973099
// on the first collection after sweep_full, and the current scan
30983100
perm_scanned_bytes = 0;
30993101
promoted_bytes = 0;
3102+
last_long_collect_interval = gc_num.interval;
31003103
}
31013104
scanned_bytes = 0;
31023105
// 6. start sweeping
@@ -3166,22 +3169,34 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
31663169
live_bytes += -gc_num.freed + gc_num.since_sweep;
31673170

31683171
if (collection == JL_GC_AUTO) {
3172+
//If we aren't freeing enough or are seeing lots and lots of pointers let it increase faster
3173+
if(!not_freed_enough || large_frontier) {
3174+
int64_t tot = 2 * (live_bytes + gc_num.since_sweep) / 3;
3175+
if (gc_num.interval > tot) {
3176+
gc_num.interval = tot;
3177+
last_long_collect_interval = tot;
3178+
}
31693179
// If the current interval is larger than half the live data decrease the interval
3170-
int64_t half = live_bytes/2;
3171-
if (gc_num.interval > half) gc_num.interval = half;
3180+
} else {
3181+
int64_t half = (live_bytes / 2);
3182+
if (gc_num.interval > half)
3183+
gc_num.interval = half;
3184+
}
3185+
31723186
// But never go below default
31733187
if (gc_num.interval < default_collect_interval) gc_num.interval = default_collect_interval;
31743188
}
31753189

31763190
if (gc_num.interval + live_bytes > max_total_memory) {
31773191
if (live_bytes < max_total_memory) {
31783192
gc_num.interval = max_total_memory - live_bytes;
3193+
last_long_collect_interval = max_total_memory - live_bytes;
31793194
}
31803195
else {
31813196
// We can't stay under our goal so let's go back to
31823197
// the minimum interval and hope things get better
31833198
gc_num.interval = default_collect_interval;
3184-
}
3199+
}
31853200
}
31863201

31873202
gc_time_summary(sweep_full, t_start, gc_end_time, gc_num.freed,

src/julia.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ typedef struct _jl_value_t jl_value_t;
9191

9292
struct _jl_taggedvalue_bits {
9393
uintptr_t gc:2;
94+
uintptr_t in_image:1;
9495
};
9596

9697
JL_EXTENSION struct _jl_taggedvalue_t {

src/julia_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ static inline void memmove_refs(void **dstp, void *const *srcp, size_t n) JL_NOT
301301
#define GC_MARKED 1 // reachable and young
302302
#define GC_OLD 2 // if it is reachable it will be marked as old
303303
#define GC_OLD_MARKED (GC_OLD | GC_MARKED) // reachable and old
304+
#define GC_IN_IMAGE 4
304305

305306
// useful constants
306307
extern jl_methtable_t *jl_type_type_mt JL_GLOBALLY_ROOTED;

src/staticdata.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,7 @@ void gc_sweep_sysimg(void)
17581758
last_pos = pos;
17591759
jl_taggedvalue_t *o = (jl_taggedvalue_t *)(base + pos);
17601760
o->bits.gc = GC_OLD;
1761+
assert(o->bits.in_image == 1);
17611762
}
17621763
}
17631764
}
@@ -2811,7 +2812,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
28112812
*base = image_base;
28122813

28132814
s.s = &sysimg;
2814-
jl_read_reloclist(&s, s.link_ids_gctags, GC_OLD); // gctags
2815+
jl_read_reloclist(&s, s.link_ids_gctags, GC_OLD | GC_IN_IMAGE); // gctags
28152816
size_t sizeof_tags = ios_pos(&relocs);
28162817
(void)sizeof_tags;
28172818
jl_read_reloclist(&s, s.link_ids_relocs, 0); // general relocs
@@ -2922,7 +2923,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
29222923
arraylist_push(&cleanup_list, (void*)obj);
29232924
}
29242925
if (tag)
2925-
*pfld = (uintptr_t)newobj | GC_OLD;
2926+
*pfld = (uintptr_t)newobj | GC_OLD | GC_IN_IMAGE;
29262927
else
29272928
*pfld = (uintptr_t)newobj;
29282929
assert(!(image_base < (char*)newobj && (char*)newobj <= image_base + sizeof_sysimg + sizeof(uintptr_t)));
@@ -2965,6 +2966,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
29652966
memset(o, 0xba, sizeof(jl_value_t*) + sizeof(jl_datatype_t));
29662967
else
29672968
memset(o, 0xba, sizeof(jl_value_t*) + 0); // singleton
2969+
o->bits.in_image = 1;
29682970
}
29692971
arraylist_grow(&cleanup_list, -cleanup_list.len);
29702972
// finally cache all our new types now
@@ -3032,6 +3034,7 @@ static void jl_restore_system_image_from_stream_(ios_t *f, jl_image_t *image, jl
30323034
jl_value_t *t = jl_typeof(item);
30333035
if (t == (jl_value_t*)jl_method_instance_type)
30343036
memset(o, 0xba, sizeof(jl_value_t*) * 3); // only specTypes and sparams fields stored
3037+
o->bits.in_image = 1;
30353038
}
30363039
arraylist_free(&cleanup_list);
30373040
for (size_t i = 0; i < s.fixup_objs.len; i++) {

0 commit comments

Comments
 (0)