#undef HANDLE_PTR
#define HANDLE_PTR(ptr,obj) do { \
if (*(ptr) && !sgen_ptr_in_nursery ((char*)*(ptr)) && !is_major_or_los_object_marked ((GCObject*)*(ptr))) { \
- if (!sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \
+ if (!cards || !sgen_get_remset ()->find_address_with_cards (start, cards, (char*)(ptr))) { \
GCVTable __vt = SGEN_LOAD_VTABLE (obj); \
SGEN_LOG (0, "major->major reference %p at offset %zd in object %p (%s.%s) not found in remsets.", *(ptr), (char*)(ptr) - (char*)(obj), (obj), sgen_client_vtable_get_namespace (__vt), sgen_client_vtable_get_name (__vt)); \
binary_protocol_missing_remset ((obj), __vt, (int) ((char*)(ptr) - (char*)(obj)), *(ptr), (gpointer)LOAD_VTABLE(*(ptr)), object_is_pinned (*(ptr))); \
else
cards = sgen_get_major_collector ()->get_cardtable_mod_union_for_reference (start);
- SGEN_ASSERT (0, cards, "we must have mod union for marked major objects");
-
#include "sgen-scan-object.h"
}
{
missing_remsets = FALSE;
- major_collector.iterate_objects (ITERATE_OBJECTS_ALL, (IterateObjectCallbackFunc)check_mod_union_callback, (void*)FALSE);
+ major_collector.iterate_objects (ITERATE_OBJECTS_SWEEP_ALL, (IterateObjectCallbackFunc)check_mod_union_callback, (void*)FALSE);
sgen_los_iterate_objects ((IterateObjectCallbackFunc)check_mod_union_callback, (void*)TRUE);
{
char *start = (char*)obj;
gboolean allow_missing_pinned = (gboolean) (size_t) data;
- SgenDescriptor desc = sgen_obj_get_descriptor (obj);
+ SgenDescriptor desc = sgen_obj_get_descriptor_safe (obj);
#include "sgen-scan-object.h"
}
* Return whether any objects were late-pinned due to being out of memory.
*/
static gboolean
-collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
+collect_nursery (const char *reason, gboolean is_overflow, SgenGrayQueue *unpin_queue)
{
gboolean needs_major;
size_t max_garbage_amount;
gc_stats.minor_gc_count ++;
- if (whole_heap_check_before_collection) {
- sgen_clear_nursery_fragments ();
- sgen_check_whole_heap (finish_up_concurrent_mark);
- }
-
sgen_process_fin_stage_entries ();
/* pin from pinned handles */
if (remset_consistency_checks)
sgen_check_remset_consistency ();
+ if (whole_heap_check_before_collection) {
+ sgen_clear_nursery_fragments ();
+ sgen_check_whole_heap (FALSE);
+ }
+
TV_GETTIME (atv);
time_minor_pinning += TV_ELAPSED (btv, atv);
SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (btv, atv));
sgen_clear_nursery_fragments ();
if (whole_heap_check_before_collection)
- sgen_check_whole_heap (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT);
+ sgen_check_whole_heap (TRUE);
TV_GETTIME (btv);
time_major_pre_collection_fragment_clear += TV_ELAPSED (atv, btv);
if (old_next_pin_slot)
*old_next_pin_slot = sgen_get_pinned_count ();
- /*
- * We don't actually pin when starting a concurrent collection, so the remset
- * consistency check won't work.
- */
- if (remset_consistency_checks && mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT)
- sgen_check_remset_consistency ();
-
TV_GETTIME (btv);
time_major_pinning += TV_ELAPSED (atv, btv);
SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), (long long)TV_ELAPSED (atv, btv));
reset_heap_boundaries ();
sgen_update_heap_boundaries ((mword)sgen_get_nursery_start (), (mword)sgen_get_nursery_end ());
- if (whole_heap_check_before_collection)
- sgen_check_whole_heap (FALSE);
-
/* walk the pin_queue, build up the fragment list of free memory, unmark
* pinned objects as we go, memzero() the empty fragments so they are ready for the
* next allocations.
if (concurrent_collection_in_progress)
major_update_concurrent_collection ();
- if (collect_nursery (reason, FALSE, NULL, FALSE) && !concurrent_collection_in_progress) {
+ if (collect_nursery (reason, FALSE, NULL) && !concurrent_collection_in_progress) {
overflow_generation_to_collect = GENERATION_OLD;
overflow_reason = "Minor overflow";
}
} else {
SGEN_ASSERT (0, generation_to_collect == GENERATION_OLD, "We should have handled nursery collections above");
if (major_collector.is_concurrent && !wait_to_finish) {
- collect_nursery ("Concurrent start", FALSE, NULL, FALSE);
+ collect_nursery ("Concurrent start", FALSE, NULL);
major_start_concurrent_collection (reason);
oldest_generation_collected = GENERATION_NURSERY;
} else if (major_do_collection (reason, FALSE, wait_to_finish)) {
*/
if (overflow_generation_to_collect == GENERATION_NURSERY)
- collect_nursery (overflow_reason, TRUE, NULL, FALSE);
+ collect_nursery (overflow_reason, TRUE, NULL);
else
major_do_collection (overflow_reason, TRUE, wait_to_finish);
{
sgen_stop_world (0);
sgen_clear_nursery_fragments ();
- sgen_check_whole_heap (FALSE);
+ sgen_check_whole_heap (TRUE);
sgen_restart_world (0);
}
gboolean pinned = flags & ITERATE_OBJECTS_PINNED;
MSBlockInfo *block;
+ /* No actual sweeping will take place if we are in the middle of a major collection. */
major_finish_sweep_checking ();
FOREACH_BLOCK_NO_LOCK (block) {
int count = MS_BLOCK_FREE / block->obj_size;
continue;
if (!block->pinned && !non_pinned)
continue;
- if (sweep && lazy_sweep) {
+ if (sweep && lazy_sweep && !block_is_swept_or_marking (block)) {
sweep_block (block);
SGEN_ASSERT (6, block->state == BLOCK_STATE_SWEPT, "Block must be swept after sweeping");
}
for (i = 0; i < count; ++i) {
void **obj = (void**) MS_BLOCK_OBJ (block, i);
- /*
- * We've finished sweep checking, but if we're sweeping lazily and
- * the flags don't require us to sweep, the block might still need
- * sweeping. In that case, we need to consult the mark bits to tell
- * us whether an object slot is live.
- */
- if (!block_is_swept_or_marking (block)) {
- int word, bit;
- SGEN_ASSERT (6, !sweep && block->state == BLOCK_STATE_NEED_SWEEPING, "Has sweeping not finished?");
- MS_CALC_MARK_BIT (word, bit, obj);
- if (!MS_MARK_BIT (block, word, bit))
- continue;
- }
if (MS_OBJ_ALLOCED (obj, block))
callback ((GCObject*)obj, block->obj_size, data);
}