X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-simple-nursery.c;h=29ab4ed135ddd54d93b74ef707d9bca63e7a6303;hb=HEAD;hp=56a235aa30f42473511957269500bc45a86870c1;hpb=58e8a9f85176c9607e605b888ef45db01a0f6997;p=mono.git diff --git a/mono/sgen/sgen-simple-nursery.c b/mono/sgen/sgen-simple-nursery.c index 56a235aa30f..29ab4ed135d 100644 --- a/mono/sgen/sgen-simple-nursery.c +++ b/mono/sgen/sgen-simple-nursery.c @@ -1,5 +1,6 @@ -/* - * sgen-simple-nursery.c: Simple always promote nursery. +/** + * \file + * Simple always promote nursery. * * Copyright 2001-2003 Ximian, Inc * Copyright 2003-2010 Novell, Inc. @@ -18,13 +19,30 @@ #include "mono/sgen/sgen-protocol.h" #include "mono/sgen/sgen-layout-stats.h" #include "mono/sgen/sgen-client.h" +#include "mono/sgen/sgen-workers.h" +#include "mono/utils/mono-memory-model.h" +#include "mono/utils/mono-proclib.h" static inline GCObject* alloc_for_promotion (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references) { + total_promoted_size += objsize; return major_collector.alloc_object (vtable, objsize, has_references); } +static inline GCObject* +alloc_for_promotion_par (GCVTable vtable, GCObject *obj, size_t objsize, gboolean has_references) +{ + /* + * FIXME + * Note that the stat is not precise. total_promoted_size incrementing is not atomic and + * even in that case, the same object might be promoted simultaneously by different workers + * leading to one of the allocated major object to be discarded. + */ + total_promoted_size += objsize; + return major_collector.alloc_object_par (vtable, objsize, has_references); +} + static SgenFragment* build_fragments_get_exclude_head (void) { @@ -54,26 +72,86 @@ clear_fragments (void) static void init_nursery (SgenFragmentAllocator *allocator, char *start, char *end) { - sgen_fragment_allocator_add (allocator, start, end); + char *nursery_limit = sgen_nursery_start + sgen_nursery_size; + + if (start < nursery_limit && end > nursery_limit) { + sgen_fragment_allocator_add (allocator, start, nursery_limit); + sgen_fragment_allocator_add (allocator, nursery_limit, end); + } else { + sgen_fragment_allocator_add (allocator, start, end); + } } /******************************************Copy/Scan functins ************************************************/ +#define collector_pin_object(obj, queue) sgen_pin_object (obj, queue); +#define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion +#define COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION alloc_for_promotion_par + +#define COPY_OR_MARK_PARALLEL +#include "sgen-copy-object.h" + #define SGEN_SIMPLE_NURSERY -#define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object -#define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj +#include "sgen-minor-copy-object.h" +#include "sgen-minor-scan-object.h" + +static void +fill_serial_ops (SgenObjectOperations *ops) +{ + ops->copy_or_mark_object = SERIAL_COPY_OBJECT; + FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops); +} + +#define SGEN_SIMPLE_PAR_NURSERY + +#include "sgen-minor-copy-object.h" +#include "sgen-minor-scan-object.h" + +static void +fill_parallel_ops (SgenObjectOperations *ops) +{ + ops->copy_or_mark_object = SERIAL_COPY_OBJECT; + FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops); +} + +#undef SGEN_SIMPLE_PAR_NURSERY +#define SGEN_CONCURRENT_MAJOR #include "sgen-minor-copy-object.h" #include "sgen-minor-scan-object.h" +static void +fill_serial_with_concurrent_major_ops (SgenObjectOperations *ops) +{ + ops->copy_or_mark_object = SERIAL_COPY_OBJECT; + FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops); +} + +#define SGEN_SIMPLE_PAR_NURSERY + +#include "sgen-minor-copy-object.h" +#include "sgen-minor-scan-object.h" + +static void +fill_parallel_with_concurrent_major_ops (SgenObjectOperations *ops) +{ + ops->copy_or_mark_object = SERIAL_COPY_OBJECT; + FILL_MINOR_COLLECTOR_SCAN_OBJECT (ops); +} + void -sgen_simple_nursery_init (SgenMinorCollector *collector) +sgen_simple_nursery_init (SgenMinorCollector *collector, gboolean parallel) { + if (mono_cpu_count () <= 1) + parallel = FALSE; + collector->is_split = FALSE; + collector->is_parallel = parallel; collector->alloc_for_promotion = alloc_for_promotion; + collector->alloc_for_promotion_par = alloc_for_promotion_par; collector->prepare_to_space = prepare_to_space; collector->clear_fragments = clear_fragments; @@ -82,8 +160,17 @@ sgen_simple_nursery_init (SgenMinorCollector *collector) collector->build_fragments_finish = build_fragments_finish; collector->init_nursery = init_nursery; - FILL_MINOR_COLLECTOR_COPY_OBJECT (collector); - FILL_MINOR_COLLECTOR_SCAN_OBJECT (collector); + fill_serial_ops (&collector->serial_ops); + fill_serial_with_concurrent_major_ops (&collector->serial_ops_with_concurrent_major); + fill_parallel_ops (&collector->parallel_ops); + fill_parallel_with_concurrent_major_ops (&collector->parallel_ops_with_concurrent_major); + + /* + * The nursery worker context is created first so it will have priority over + * concurrent mark and concurrent sweep. + */ + if (parallel) + sgen_workers_create_context (GENERATION_NURSERY, mono_cpu_count ()); }