* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+#include "config.h"
+#ifdef HAVE_SGEN_GC
+
+#include "metadata/sgen-gc.h"
+#include "metadata/sgen-cardtable.h"
+#include "utils/mono-counters.h"
+#include "utils/mono-time.h"
+
#ifdef SGEN_HAVE_CARDTABLE
//#define CARDTABLE_STATS
return mask;
}
-static gboolean
-sgen_card_table_address_is_marked (mword address)
-{
- return *sgen_card_table_get_card_address (address) != 0;
-}
-
-void
-sgen_card_table_mark_address (mword address)
-{
- *sgen_card_table_get_card_address (address) = 1;
-}
-
void*
sgen_card_table_align_pointer (void *ptr)
{
}
-static void
-card_table_init (void)
+void
+sgen_card_table_init (void)
{
sgen_cardtable = mono_sgen_alloc_os_memory (CARD_COUNT_IN_BYTES, TRUE);
#endif
-static void
-card_table_clear (void)
+void
+sgen_card_table_clear (void)
{
/*XXX we could do this in 2 ways. using mincore or iterating over all sections/los objects */
- if (use_cardtable) {
- major_collector.iterate_live_block_ranges (clear_cards);
- mono_sgen_los_iterate_live_block_ranges (clear_cards);
- }
+ sgen_major_collector_iterate_live_block_ranges (clear_cards);
+ mono_sgen_los_iterate_live_block_ranges (clear_cards);
}
-static void
-scan_from_card_tables (void *start_nursery, void *end_nursery, GrayQueue *queue)
+
+void
+sgen_scan_from_card_tables (void *start_nursery, void *end_nursery, SgenGrayQueue *queue)
{
- if (use_cardtable) {
- TV_DECLARE (atv);
- TV_DECLARE (btv);
+ SGEN_TV_DECLARE (atv);
+ SGEN_TV_DECLARE (btv);
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
/*FIXME we should have a bit on each block/los object telling if the object have marked cards.*/
/*First we copy*/
- major_collector.iterate_live_block_ranges (move_cards_to_shadow_table);
+ sgen_major_collector_iterate_live_block_ranges (move_cards_to_shadow_table);
mono_sgen_los_iterate_live_block_ranges (move_cards_to_shadow_table);
/*Then we clear*/
- card_table_clear ();
+ sgen_card_table_clear ();
#endif
- TV_GETTIME (atv);
- major_collector.scan_card_table (queue);
- TV_GETTIME (btv);
- last_major_scan_time = TV_ELAPSED_MS (atv, btv);
- major_card_scan_time += last_major_scan_time;
- mono_sgen_los_scan_card_table (queue);
- TV_GETTIME (atv);
- last_los_scan_time = TV_ELAPSED_MS (btv, atv);
- los_card_scan_time += last_los_scan_time;
- }
+ SGEN_TV_GETTIME (atv);
+ sgen_major_collector_scan_card_table (queue);
+ SGEN_TV_GETTIME (btv);
+ last_major_scan_time = SGEN_TV_ELAPSED_MS (atv, btv);
+ major_card_scan_time += last_major_scan_time;
+ mono_sgen_los_scan_card_table (queue);
+ SGEN_TV_GETTIME (atv);
+ last_los_scan_time = SGEN_TV_ELAPSED_MS (btv, atv);
+ los_card_scan_time += last_los_scan_time;
}
guint8*
mono_gc_get_card_table (int *shift_bits, gpointer *mask)
{
- if (!use_cardtable)
+ if (!sgen_cardtable)
return NULL;
- g_assert (sgen_cardtable);
*shift_bits = CARD_BITS;
#ifdef SGEN_HAVE_OVERLAPPING_CARDS
*mask = (gpointer)CARD_MASK;
void
sgen_cardtable_scan_object (char *obj, mword block_obj_size, guint8 *cards, SgenGrayQueue *queue)
{
- MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (obj);
+ MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (obj);
MonoClass *klass = vt->klass;
CopyOrMarkObjectFunc copy_func = mono_sgen_get_copy_object ();
ScanObjectFunc scan_object_func = mono_sgen_get_minor_scan_object ();
HEAVY_STAT (++los_array_cards);
for (; elem < card_end; elem += SIZEOF_VOID_P) {
gpointer new, old = *(gpointer*)elem;
- if (G_UNLIKELY (ptr_in_nursery (old))) {
+ if (G_UNLIKELY (sgen_ptr_in_nursery (old))) {
HEAVY_STAT (++los_array_remsets);
copy_func ((void**)elem, queue);
new = *(gpointer*)elem;
- if (G_UNLIKELY (ptr_in_nursery (new)))
+ if (G_UNLIKELY (sgen_ptr_in_nursery (new)))
mono_sgen_add_to_global_remset (elem);
}
}
#endif
-static void
-card_tables_collect_stats (gboolean begin)
+void
+sgen_card_tables_collect_stats (gboolean begin)
{
#ifdef CARDTABLE_STATS
if (begin) {
memset (&major_stats, 0, sizeof (card_stats));
memset (&los_stats, 0, sizeof (card_stats));
cur_stats = &major_stats;
- major_collector.iterate_live_block_ranges (count_marked_cards);
+ sgen_major_collector_iterate_live_block_ranges (count_marked_cards);
cur_stats = &los_stats;
mono_sgen_los_iterate_live_block_ranges (count_marked_cards);
} else {
cur_stats = &major_stats;
- major_collector.iterate_live_block_ranges (count_marked_cards);
+ sgen_major_collector_iterate_live_block_ranges (count_marked_cards);
cur_stats = &los_stats;
mono_sgen_los_iterate_live_block_ranges (count_remarked_cards);
printf ("cards major (t %d m %d r %d) los (t %d m %d r %d) major_scan %lld los_scan %lld\n",
g_assert_not_reached ();
}
-#define sgen_card_table_address_is_marked(p) FALSE
-#define scan_from_card_tables(start,end,queue)
-#define card_table_clear()
-#define card_table_init()
-#define card_tables_collect_stats(begin)
-
guint8*
mono_gc_get_card_table (int *shift_bits, gpointer *mask)
{
}
#endif
+
+#endif /*HAVE_SGEN_GC*/
\ No newline at end of file
void sgen_card_table_reset_region (mword start, mword end) MONO_INTERNAL;
void* sgen_card_table_align_pointer (void *ptr) MONO_INTERNAL;
-void sgen_card_table_mark_address (mword address) MONO_INTERNAL;
void sgen_card_table_mark_range (mword address, mword size) MONO_INTERNAL;
void sgen_cardtable_scan_object (char *obj, mword obj_size, guint8 *cards, SgenGrayQueue *queue) MONO_INTERNAL;
+
gboolean sgen_card_table_get_card_data (guint8 *dest, mword address, mword cards) MONO_INTERNAL;
+void sgen_scan_from_card_tables (void *start_nursery, void *end_nursery, SgenGrayQueue *queue) MONO_INTERNAL;
+void sgen_card_tables_collect_stats (gboolean begin) MONO_INTERNAL;
+void sgen_card_table_clear (void) MONO_INTERNAL;
+void sgen_card_table_init (void) MONO_INTERNAL;
+gboolean sgen_ptr_in_nursery (void *p) MONO_INTERNAL;
+
/*How many bytes a single card covers*/
#define CARD_BITS 9
#endif
+static inline gboolean
+sgen_card_table_address_is_marked (mword address)
+{
+ return *sgen_card_table_get_card_address (address) != 0;
+}
+
+static inline void
+sgen_card_table_mark_address (mword address)
+{
+ *sgen_card_table_get_card_address (address) = 1;
+}
+
+
+#elif
+
+#else
+
+void
+sgen_card_table_mark_address (mword address)
+{
+ g_assert_not_reached ();
+}
+
+void
+sgen_card_table_mark_range (mword address, mword size)
+{
+ g_assert_not_reached ();
+}
+
+#define sgen_card_table_address_is_marked(p) FALSE
+#define sgen_scan_from_card_tables(start,end,queue)
+#define sgen_card_table_clear()
+#define sgen_card_table_init()
+#define sgen_card_tables_collect_stats(begin)
+
+guint8*
+mono_gc_get_card_table (int *shift_bits, gpointer *mask)
+{
+ return NULL;
+}
+
#endif
#include "metadata/mempool-internals.h"
#include "metadata/marshal.h"
#include "metadata/runtime.h"
+#include "metadata/sgen-cardtable.h"
#include "utils/mono-mmap.h"
#include "utils/mono-time.h"
#include "utils/mono-semaphore.h"
#include "sgen-pinning-stats.c"
#include "sgen-gray.c"
#include "sgen-workers.c"
-#include "sgen-cardtable.c"
static gboolean
is_xdomain_ref_allowed (gpointer *ptr, char *obj, MonoDomain *domain)
if (use_cardtable) {
atv = btv;
- card_tables_collect_stats (TRUE);
- scan_from_card_tables (nursery_start, nursery_next, WORKERS_DISTRIBUTE_GRAY_QUEUE);
+ sgen_card_tables_collect_stats (TRUE);
+ sgen_scan_from_card_tables (nursery_start, nursery_next, WORKERS_DISTRIBUTE_GRAY_QUEUE);
TV_GETTIME (btv);
time_minor_scan_card_table += TV_ELAPSED_MS (atv, btv);
}
g_assert (gray_object_queue_is_empty (&gray_queue));
if (use_cardtable)
- card_tables_collect_stats (FALSE);
+ sgen_card_tables_collect_stats (FALSE);
check_scan_starts ();
clear_remsets ();
global_remset_cache_clear ();
if (use_cardtable)
- card_table_clear ();
+ sgen_card_table_clear ();
process_fin_stage_entries ();
process_dislink_stage_entries ();
global_remset->next = NULL;
if (use_cardtable)
- card_table_init ();
+ sgen_card_table_init ();
gc_initialized = 1;
}
UNLOCK_GC;
}
+void
+sgen_major_collector_iterate_live_block_ranges (sgen_cardtable_block_callback callback)
+{
+ major_collector.iterate_live_block_ranges (callback);
+}
+
+void
+sgen_major_collector_scan_card_table (SgenGrayQueue *queue)
+{
+ major_collector.scan_card_table (queue);
+}
+
+gboolean
+sgen_ptr_in_nursery (void *p)
+{
+ return SGEN_PTR_IN_NURSERY ((p), DEFAULT_NURSERY_BITS, nursery_start, nursery_end);
+}
+
#endif /* HAVE_SGEN_GC */