Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Concurrent sweep #1681

Merged
merged 50 commits into from
Apr 9, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
1fbaf72
[sgen] Split sweeping into three parts: start, block loop, finish.
schani Oct 28, 2014
207f2a7
[sgen] Function for querying whether world is stopped.
schani Jan 21, 2015
788b784
[sgen] Guard allocated block array with a mutex.
schani Jan 21, 2015
0caf65b
[sgen] Make slots free list lock-free.
schani Jan 21, 2015
e6699ba
[sgen] Sweep state instead of `have_swept`.
schani Jan 21, 2015
bfdfbe1
[sgen] Make memory governor ready for concurrent sweep.
schani Jan 22, 2015
8e8efe3
[sgen] On forced major collections, free blocks.
schani Feb 27, 2015
7412b44
[sgen] Replace `swept` with more detailed block state.
schani Jan 22, 2015
fdfaade
[sgen] Concurrent sweep
schani Jan 22, 2015
3b1059b
[sgen] Card clearing and moving to shadow cards don't require sweep.
schani Jan 26, 2015
60078ae
[sgen] Binary protocol entries for block alloc/free/change state.
schani Jan 26, 2015
9cabf9a
[sgen] Factor out function that checks individual blocks for sweeping.
schani Jan 26, 2015
86eb54d
[sgen] Traverse block array from high to low in sweep thread.
schani Jan 26, 2015
b5682e3
[sgen] Set the block state to CHECKING with the allocated blocks lock…
schani Jan 26, 2015
079804f
[sgen] Fix M&S heap consistency checks.
schani Jan 29, 2015
24262e0
[sgen] Make function for block checking wait for another potential th…
schani Jan 29, 2015
440ca36
[sgen] Comments.
schani Jan 29, 2015
7627baa
[sgen] Fix initial block state.
schani Jan 29, 2015
fcdb3a9
[sgen] Allow card table scanning to do block checking work.
schani Jan 29, 2015
0a4d98c
[sgen] Remove dead parameter to `sweep_block()`.
schani Jan 29, 2015
37068c1
[sgen] Don't iterate over block array while it's being compacted.
schani Jan 30, 2015
98d93ad
[sgen] Write binary protocol for card scan before scanning the card.
schani Feb 5, 2015
216713e
[sgen] `num_major_sections` must be updated atomically.
schani Feb 5, 2015
f38b8ae
[sgen] Count major sections before/after sweep correctly.
schani Feb 5, 2015
b36a81c
[sgen] Simplify allowance logic.
schani Feb 6, 2015
dc9f7f0
[sgen] Whenever we wait for sweep, help the sweeping thread.
schani Feb 6, 2015
b5b493d
[sgen] Assert world is stopped and not sweeping when iterating blocks.
schani Feb 9, 2015
c24e166
[sgen] Remove dead macros.
schani Feb 9, 2015
578e66c
[sgen] Just one iteration over the blocks at start of major collection.
schani Feb 10, 2015
68ba43a
[sgen] Clean up FIXMEs.
schani Feb 10, 2015
f5f2d2f
[sgen] Lock-free block array.
schani Feb 11, 2015
14626e1
[sgen] `sweep_block()` returns whether it actually swept.
schani Feb 11, 2015
75cfa06
[sgen] Rename a function to better reflect what it does.
schani Feb 11, 2015
c4b9b5c
[sgen] Don't repeat code and don't load multiple times.
schani Feb 11, 2015
1639bef
[sgen] Comments.
schani Feb 11, 2015
ec2572d
[sgen] Only do a debug block iteration on a higher assert level.
schani Feb 11, 2015
55a2ff8
[sgen] Don't unnecessarily compute object size index.
schani Feb 11, 2015
8333c2f
[sgen] Fix a comment.
schani Feb 12, 2015
6fb229a
[sgen] Implement a simple thread pool and do concurrent sweep with it.
schani Feb 13, 2015
183dc29
[sgen] Wait for the sweep job properly.
schani Feb 13, 2015
83dfb12
[sgen] Workers use thread pool.
schani Feb 18, 2015
01930f5
[sgen] Have the worker state just be an integer.
schani Feb 18, 2015
9bcdbf2
[sgen] Remove some dead code and data.
schani Feb 18, 2015
c1385d2
[sgen] Reinstate old M&S section reserve.
schani Feb 24, 2015
74065cb
[sgen] Don't CAS when setting block state.
schani Feb 25, 2015
d62f8e2
[sgen] Mark a function inline.
schani Feb 25, 2015
8278dd3
[sgen] Increase assert levels.
schani Feb 25, 2015
a4e8ad3
[sgen] Remove a debug printf.
schani Apr 3, 2015
ae4c1ef
[sgen] Format block iteration macros.
schani Apr 3, 2015
1a43231
[sgen] Don't assert in GC.GetTotalMemory.
schani Apr 3, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 10 additions & 3 deletions man/mono.1
Original file line number Diff line number Diff line change
Expand Up @@ -1129,9 +1129,16 @@ to 100 percent. A value of 0 turns evacuation off.
.TP
\fB(no-)lazy-sweep\fR
Enables or disables lazy sweep for the Mark&Sweep collector. If
enabled, the sweep phase of the garbage collection is done piecemeal
whenever the need arises, typically during nursery collections. Lazy
sweeping is enabled by default.
enabled, the sweeping of individual major heap blocks is done
piecemeal whenever the need arises, typically during nursery
collections. Lazy sweeping is enabled by default.
.TP
\fB(no-)concurrent-sweep\fR
Enables or disables concurrent sweep for the Mark&Sweep collector. If
enabled, the iteration of all major blocks to determine which ones can
be freed and which ones have to be kept and swept, is done
concurrently with the running program. Concurrent sweeping is enabled
by default.
.TP
\fBstack-mark=\fImark-mode\fR
Specifies how application threads should be scanned. Options are
Expand Down
2 changes: 2 additions & 0 deletions mono/metadata/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ sgen_sources = \
sgen-layout-stats.h \
sgen-qsort.c \
sgen-qsort.h \
sgen-thread-pool.c \
sgen-thread-pool.h \
sgen-tagged-pointer.h

libmonoruntime_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(null_gc_sources) $(boehm_sources)
Expand Down
266 changes: 106 additions & 160 deletions mono/metadata/sgen-gc.c

Large diffs are not rendered by default.

27 changes: 16 additions & 11 deletions mono/metadata/sgen-gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ extern LOCK_DECLARE (sgen_interruption_mutex);
#define UNLOCK_INTERRUPTION mono_mutex_unlock (&sgen_interruption_mutex)

/* FIXME: Use InterlockedAdd & InterlockedAdd64 to reduce the CAS cost. */
#define SGEN_CAS InterlockedCompareExchange
#define SGEN_CAS_PTR InterlockedCompareExchangePointer
#define SGEN_ATOMIC_ADD(x,i) do { \
int __old_x; \
Expand Down Expand Up @@ -391,8 +392,6 @@ gboolean sgen_resume_thread (SgenThreadInfo *info);
void sgen_wait_for_suspend_ack (int count);
void sgen_os_init (void);

gboolean sgen_is_worker_thread (MonoNativeThreadId thread);

void sgen_update_heap_boundaries (mword low, mword high);

void sgen_scan_area_with_callback (char *start, char *end, IterateObjectCallbackFunc callback, void *data, gboolean allow_flags);
Expand Down Expand Up @@ -420,7 +419,7 @@ enum {
INTERNAL_MEM_MS_BLOCK_INFO_SORT,
INTERNAL_MEM_EPHEMERON_LINK,
INTERNAL_MEM_WORKER_DATA,
INTERNAL_MEM_WORKER_JOB_DATA,
INTERNAL_MEM_THREAD_POOL_JOB,
INTERNAL_MEM_BRIDGE_DATA,
INTERNAL_MEM_OLD_BRIDGE_HASH_TABLE,
INTERNAL_MEM_OLD_BRIDGE_HASH_TABLE_ENTRY,
Expand All @@ -432,7 +431,6 @@ enum {
INTERNAL_MEM_TARJAN_BRIDGE_HASH_TABLE_ENTRY,
INTERNAL_MEM_TARJAN_OBJ_BUCKET,
INTERNAL_MEM_BRIDGE_DEBUG,
INTERNAL_MEM_JOB_QUEUE_ENTRY,
INTERNAL_MEM_TOGGLEREF_DATA,
INTERNAL_MEM_CARDTABLE_MOD_UNION,
INTERNAL_MEM_BINARY_PROTOCOL,
Expand Down Expand Up @@ -612,12 +610,13 @@ void sgen_split_nursery_init (SgenMinorCollector *collector);
/* Updating references */

#ifdef SGEN_CHECK_UPDATE_REFERENCE
gboolean sgen_thread_pool_is_thread_pool_thread (MonoNativeThreadId some_thread) MONO_INTERNAL;
static inline void
sgen_update_reference (void **p, void *o, gboolean allow_null)
{
if (!allow_null)
SGEN_ASSERT (0, o, "Cannot update a reference with a NULL pointer");
SGEN_ASSERT (0, !sgen_is_worker_thread (mono_native_thread_id_get ()), "Can't update a reference in the worker thread");
SGEN_ASSERT (0, !sgen_thread_pool_is_thread_pool_thread (mono_native_thread_id_get ()), "Can't update a reference in the worker thread");
*p = o;
}

Expand Down Expand Up @@ -653,6 +652,7 @@ typedef struct _SgenMajorCollector SgenMajorCollector;
struct _SgenMajorCollector {
size_t section_size;
gboolean is_concurrent;
gboolean needs_thread_pool;
gboolean supports_cardtable;
gboolean sweeps_lazily;

Expand All @@ -673,7 +673,13 @@ struct _SgenMajorCollector {

void* (*alloc_object) (MonoVTable *vtable, size_t size, gboolean has_references);
void (*free_pinned_object) (char *obj, size_t size);

/*
* This is used for domain unloading, heap walking from the logging profiler, and
* debugging. Can assume the world is stopped.
*/
void (*iterate_objects) (IterateObjectsFlags flags, IterateObjectCallbackFunc callback, void *data);

void (*free_non_pinned_object) (char *obj, size_t size);
void (*pin_objects) (SgenGrayQueue *queue);
void (*pin_major_object) (char *obj, SgenGrayQueue *queue);
Expand All @@ -682,8 +688,9 @@ struct _SgenMajorCollector {
void (*update_cardtable_mod_union) (void);
void (*init_to_space) (void);
void (*sweep) (void);
gboolean (*have_finished_sweeping) (void);
void (*free_swept_blocks) (void);
gboolean (*have_swept) (void);
void (*finish_sweeping) (void);
void (*free_swept_blocks) (size_t allowance);
void (*check_scan_starts) (void);
void (*dump_heap) (FILE *heap_dump_file);
gint64 (*get_used_size) (void);
Expand All @@ -696,13 +703,10 @@ struct _SgenMajorCollector {
gboolean (*obj_is_from_pinned_alloc) (char *obj);
void (*report_pinned_memory_usage) (void);
size_t (*get_num_major_sections) (void);
size_t (*get_bytes_survived_last_sweep) (void);
gboolean (*handle_gc_param) (const char *opt);
void (*print_gc_param_usage) (void);
gboolean (*is_worker_thread) (MonoNativeThreadId thread);
void (*post_param_init) (SgenMajorCollector *collector);
void* (*alloc_worker_data) (void);
void (*init_worker_thread) (void *data);
void (*reset_worker_data) (void *data);
gboolean (*is_valid_object) (char *object);
MonoVTable* (*describe_pointer) (char *pointer);
guint8* (*get_cardtable_mod_union_for_object) (char *object);
Expand Down Expand Up @@ -959,6 +963,7 @@ typedef struct {

int sgen_stop_world (int generation);
int sgen_restart_world (int generation, GGTimingInfo *timing);
gboolean sgen_is_world_stopped (void);
void sgen_init_stw (void);

/* LOS */
Expand Down
3 changes: 1 addition & 2 deletions mono/metadata/sgen-internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ description_for_type (int type)
case INTERNAL_MEM_MS_BLOCK_INFO_SORT: return "marksweep-block-info-sort";
case INTERNAL_MEM_EPHEMERON_LINK: return "ephemeron-link";
case INTERNAL_MEM_WORKER_DATA: return "worker-data";
case INTERNAL_MEM_WORKER_JOB_DATA: return "worker-job-data";
case INTERNAL_MEM_THREAD_POOL_JOB: return "thread-pool-job";
case INTERNAL_MEM_BRIDGE_DATA: return "bridge-data";
case INTERNAL_MEM_OLD_BRIDGE_HASH_TABLE: return "old-bridge-hash-table";
case INTERNAL_MEM_OLD_BRIDGE_HASH_TABLE_ENTRY: return "old-bridge-hash-table-entry";
Expand All @@ -146,7 +146,6 @@ description_for_type (int type)
case INTERNAL_MEM_BRIDGE_ALIVE_HASH_TABLE: return "bridge-alive-hash-table";
case INTERNAL_MEM_BRIDGE_ALIVE_HASH_TABLE_ENTRY: return "bridge-alive-hash-table-entry";
case INTERNAL_MEM_BRIDGE_DEBUG: return "bridge-debug";
case INTERNAL_MEM_JOB_QUEUE_ENTRY: return "job-queue-entry";
case INTERNAL_MEM_TOGGLEREF_DATA: return "toggleref-data";
case INTERNAL_MEM_CARDTABLE_MOD_UNION: return "cardtable-mod-union";
case INTERNAL_MEM_BINARY_PROTOCOL: return "binary-protocol";
Expand Down