SgenGrayQueue *gc_thread_gray_queue;
} ScanJob;
+typedef struct {
+ ScanJob scan_job;
+ int job_index;
+} ParallelScanJob;
+
static ScanCopyContext
scan_copy_context_for_scan_job (void *worker_data_untyped, ScanJob *job)
{
ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
g_assert (concurrent_collection_in_progress);
- major_collector.scan_card_table (CARDTABLE_SCAN_MOD_UNION, ctx);
+ major_collector.scan_card_table (CARDTABLE_SCAN_MOD_UNION, ctx, 0, 1);
}
static void
static void
job_major_mod_union_preclean (void *worker_data_untyped, SgenThreadPoolJob *job)
{
- ScanJob *job_data = (ScanJob*)job;
- ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
+ ParallelScanJob *job_data = (ParallelScanJob*)job;
+ ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, (ScanJob*)job_data);
g_assert (concurrent_collection_in_progress);
- major_collector.scan_card_table (CARDTABLE_SCAN_MOD_UNION_PRECLEAN, ctx);
+ major_collector.scan_card_table (CARDTABLE_SCAN_MOD_UNION_PRECLEAN, ctx, job_data->job_index, sgen_workers_get_job_split_count ());
}
static void
job_los_mod_union_preclean (void *worker_data_untyped, SgenThreadPoolJob *job)
{
- WorkerData *worker_data = (WorkerData *)worker_data_untyped;
ScanJob *job_data = (ScanJob*)job;
- ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+ ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
g_assert (concurrent_collection_in_progress);
static void
job_scan_last_pinned (void *worker_data_untyped, SgenThreadPoolJob *job)
{
- WorkerData *worker_data = (WorkerData *)worker_data_untyped;
ScanJob *job_data = (ScanJob*)job;
- ScanCopyContext ctx = CONTEXT_FROM_OBJECT_OPERATIONS (job_data->ops, sgen_workers_get_job_gray_queue (worker_data));
+ ScanCopyContext ctx = scan_copy_context_for_scan_job (worker_data_untyped, job_data);
g_assert (concurrent_collection_in_progress);
workers_finish_callback (void)
{
ScanJob *sj;
- /* Mod union preclean job */
- sj = (ScanJob*)sgen_thread_pool_job_alloc ("preclean mod union cardtable", job_major_mod_union_preclean, sizeof (ScanJob));
- sj->ops = sgen_workers_get_idle_func_object_ops ();
- sj->gc_thread_gray_queue = NULL;
- sgen_workers_enqueue_job (&sj->job, TRUE);
+ int split_count = sgen_workers_get_job_split_count ();
+ int i;
+ /* Mod union preclean jobs */
+ for (i = 0; i < split_count; i++) {
+ ParallelScanJob *psj;
+ psj = (ParallelScanJob*)sgen_thread_pool_job_alloc ("preclean major mod union cardtable", job_major_mod_union_preclean, sizeof (ParallelScanJob));
+ psj->scan_job.ops = sgen_workers_get_idle_func_object_ops ();
+ psj->scan_job.gc_thread_gray_queue = NULL;
+ psj->job_index = i;
+ sgen_workers_enqueue_job (&psj->scan_job.job, TRUE);
+ }
sj = (ScanJob*)sgen_thread_pool_job_alloc ("preclean los mod union cardtable", job_los_mod_union_preclean, sizeof (ScanJob));
sj->ops = sgen_workers_get_idle_func_object_ops ();
void (*free_non_pinned_object) (GCObject *obj, size_t size);
void (*pin_objects) (SgenGrayQueue *queue);
void (*pin_major_object) (GCObject *obj, SgenGrayQueue *queue);
- void (*scan_card_table) (CardTableScanType scan_type, ScanCopyContext ctx);
+ void (*scan_card_table) (CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count);
void (*iterate_live_block_ranges) (sgen_cardtable_block_callback callback);
void (*iterate_block_ranges) (sgen_cardtable_block_callback callback);
void (*update_cardtable_mod_union) (void);
}
static void
-major_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx)
+major_scan_card_table (CardTableScanType scan_type, ScanCopyContext ctx, int job_index, int job_split_count)
{
MSBlockInfo *block;
gboolean has_references, was_sweeping, skip_scan;
binary_protocol_major_card_table_scan_start (sgen_timestamp (), scan_type & CARDTABLE_SCAN_MOD_UNION);
FOREACH_BLOCK_HAS_REFERENCES_NO_LOCK (block, has_references) {
+ if (__index % job_split_count != job_index)
+ continue;
#ifdef PREFETCH_CARDS
- int prefetch_index = __index + 6;
+ int prefetch_index = __index + 6 * job_split_count;
if (prefetch_index < allocated_blocks.next_slot) {
MSBlockInfo *prefetch_block = BLOCK_UNTAG (*sgen_array_list_get_slot (&allocated_blocks, prefetch_index));
PREFETCH_READ (prefetch_block);