From: Aditya Mandaleeka Date: Fri, 24 Feb 2017 17:41:32 +0000 (-0800) Subject: Clean up some GC code. X-Git-Tag: submit/tizen/20210909.063632~11030^2~7895^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2ec9ddfcf0d5b37842dff88bbfb39e904a520a1a;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Clean up some GC code. Commit migrated from https://github.com/dotnet/coreclr/commit/cc315c9663d340e704d994808eb298447a84fd59 --- diff --git a/src/coreclr/src/gc/gc.cpp b/src/coreclr/src/gc/gc.cpp index 66c8b6a..f5a5405 100644 --- a/src/coreclr/src/gc/gc.cpp +++ b/src/coreclr/src/gc/gc.cpp @@ -3697,8 +3697,6 @@ heap_segment* seg_mapping_table_segment_of (uint8_t* o) if (seg) { - // Can't assert this when it's callled by everyone (it's true when it's called by mark cards). - //assert (in_range_for_segment (o, seg)); if (in_range_for_segment (o, seg)) { dprintf (2, ("obj %Ix belongs to segment %Ix(-%Ix)", o, (uint8_t*)heap_segment_mem(seg), (uint8_t*)heap_segment_reserved(seg))); @@ -3735,7 +3733,6 @@ heap_segment* seg_mapping_table_segment_of (uint8_t* o) #endif //SEG_MAPPING_TABLE size_t gcard_of ( uint8_t*); -void gset_card (size_t card); #define memref(i) *(uint8_t**)(i) @@ -5226,9 +5223,9 @@ bool gc_heap::create_gc_thread () #if !defined(FEATURE_PAL) if (!gc_thread_no_affinitize_p) { - //We are about to set affinity for GC threads, it is a good place to setup NUMA and - //CPU groups, because the process mask, processor number, group number are all - //readyly available. + // We are about to set affinity for GC threads. It is a good place to set up NUMA and + // CPU groups because the process mask, processor number, and group number are all + // readily available. if (CPUGroupInfo::CanEnableGCCPUGroups()) set_thread_group_affinity_for_heap(heap_number, &affinity); else @@ -6612,6 +6609,7 @@ short*& card_table_brick_table (uint32_t* c_table) } #ifdef CARD_BUNDLE +// Get the card bundle table for the specified card table. inline uint32_t*& card_table_card_bundle_table (uint32_t* c_table) { @@ -18530,9 +18528,9 @@ gc_heap::scan_background_roots (promote_func* fn, int hn, ScanContext *pSC) #endif //BACKGROUND_GC - void gc_heap::fix_card_table () { +#ifdef NO_WRITE_BARRIER #ifdef WRITE_WATCH heap_segment* seg = heap_segment_rw (generation_start_segment (generation_of (max_generation))); @@ -18598,7 +18596,8 @@ void gc_heap::fix_card_table () dprintf (3,("Found %Id pages written", bcount)); for (unsigned i = 0; i < bcount; i++) { - for (unsigned j = 0; j< (card_size*card_word_width)/OS_PAGE_SIZE; j++) + // Set the card words corresponding to the entire page. + for (unsigned j = 0; j < (card_size*card_word_width)/OS_PAGE_SIZE; j++) { card_table [card_word (card_of (g_addresses [i]))+j] = ~0u; } @@ -18606,6 +18605,7 @@ void gc_heap::fix_card_table () card_of (g_addresses [i]), (size_t)g_addresses [i], card_of (g_addresses [i]+OS_PAGE_SIZE), (size_t)g_addresses [i]+OS_PAGE_SIZE)); } + if (bcount >= array_size){ base_address = g_addresses [array_size-1] + OS_PAGE_SIZE; bcount = array_size; @@ -18626,6 +18626,7 @@ void gc_heap::fix_card_table () } #endif //BACKGROUND_GC #endif //WRITE_WATCH +#endif //NO_WRITE_BARRIER } #ifdef BACKGROUND_GC @@ -21190,7 +21191,7 @@ void gc_heap::convert_to_pinned_plug (BOOL& last_npinned_plug_p, artificial_pinned_size = ps; } -// Because we have the artifical pinning, we can't gaurantee that pinned and npinned +// Because we have the artificial pinning, we can't guarantee that pinned and npinned // plugs are always interleaved. void gc_heap::store_plug_gap_info (uint8_t* plug_start, uint8_t* plug_end, @@ -26941,6 +26942,7 @@ void gc_heap::clear_cards (size_t start_card, size_t end_card) size_t end_word = card_word (end_card); if (start_word < end_word) { + // Figure out the bit positions of the cards within their words unsigned bits = card_bit (start_card); card_table [start_word] &= lowbits (~0, bits); for (size_t i = start_word+1; i < end_word; i++) @@ -26954,6 +26956,8 @@ void gc_heap::clear_cards (size_t start_card, size_t end_card) } else { + // If the start and end cards are in the same word, just clear the appropriate card + // bits in that word. card_table [start_word] &= (lowbits (~0, card_bit (start_card)) | highbits (~0, card_bit (end_card))); } @@ -26981,8 +26985,10 @@ void gc_heap::clear_card_for_addresses (uint8_t* start_address, uint8_t* end_add // copy [srccard, ...[ to [dst_card, end_card[ // This will set the same bit twice. Can be optimized. inline -void gc_heap::copy_cards (size_t dst_card, size_t src_card, - size_t end_card, BOOL nextp) +void gc_heap::copy_cards (size_t dst_card, + size_t src_card, + size_t end_card, + BOOL nextp) { // If the range is empty, this function is a no-op - with the subtlety that // either of the accesses card_table[srcwrd] or card_table[dstwrd] could be @@ -26996,22 +27002,26 @@ void gc_heap::copy_cards (size_t dst_card, size_t src_card, size_t dstwrd = card_word (dst_card); unsigned int srctmp = card_table[srcwrd]; unsigned int dsttmp = card_table[dstwrd]; + for (size_t card = dst_card; card < end_card; card++) { if (srctmp & (1 << srcbit)) dsttmp |= 1 << dstbit; else dsttmp &= ~(1 << dstbit); + if (!(++srcbit % 32)) { srctmp = card_table[++srcwrd]; srcbit = 0; } + if (nextp) { if (srctmp & (1 << srcbit)) dsttmp |= 1 << dstbit; } + if (!(++dstbit % 32)) { card_table[dstwrd] = dsttmp; @@ -27020,6 +27030,7 @@ void gc_heap::copy_cards (size_t dst_card, size_t src_card, dstbit = 0; } } + card_table[dstwrd] = dsttmp; } @@ -27229,6 +27240,9 @@ uint8_t* gc_heap::find_first_object (uint8_t* start, uint8_t* first_object) } #ifdef CARD_BUNDLE + +// Find the first non-zero card word between cardw and cardw_end. +// The index of the word we find is returned in cardw. BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end) { dprintf (3, ("gc: %d, find_card_dword cardw: %Ix, cardw_end: %Ix", @@ -27240,26 +27254,26 @@ BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end) size_t end_cardb = cardw_card_bundle (align_cardw_on_bundle (cardw_end)); while (1) { - //find a non null bundle - while ((cardb < end_cardb) && - (card_bundle_set_p (cardb)==0)) + // Find a non-zero bundle + while ((cardb < end_cardb) && (card_bundle_set_p (cardb) == 0)) { cardb++; } + if (cardb == end_cardb) return FALSE; - //find a non empty card word + // We found a bundle, so go through its words and find a non-zero card word uint32_t* card_word = &card_table[max(card_bundle_cardw (cardb),cardw)]; uint32_t* card_word_end = &card_table[min(card_bundle_cardw (cardb+1),cardw_end)]; - while ((card_word < card_word_end) && - !(*card_word)) + while ((card_word < card_word_end) && !(*card_word)) { card_word++; } + if (card_word != card_word_end) { - cardw = (card_word - &card_table [0]); + cardw = (card_word - &card_table[0]); return TRUE; } else if ((cardw <= card_bundle_cardw (cardb)) && @@ -27272,6 +27286,7 @@ BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end) card_bundle_cardw (cardb+1))); card_bundle_clear (cardb); } + cardb++; } } @@ -27282,96 +27297,122 @@ BOOL gc_heap::find_card_dword (size_t& cardw, size_t cardw_end) while (card_word < card_word_end) { - if ((*card_word) != 0) + if (*card_word != 0) { cardw = (card_word - &card_table [0]); return TRUE; } + card_word++; } - return FALSE; + return FALSE; } - } #endif //CARD_BUNDLE -BOOL gc_heap::find_card (uint32_t* card_table, size_t& card, - size_t card_word_end, size_t& end_card) +// Find cards that are set between two points in a card table. +// Parameters +// card_table : The card table. +// card : [in/out] As input, the card to start searching from. +// As output, the first card that's set. +// card_word_end : The card word at which to stop looking. +// end_card : [out] The last card which is set. +BOOL gc_heap::find_card(uint32_t* card_table, + size_t& card, + size_t card_word_end, + size_t& end_card) { uint32_t* last_card_word; - uint32_t y; - uint32_t z; + uint32_t card_word_value; + uint32_t bit_position; + // Find the first card which is set - last_card_word = &card_table [card_word (card)]; - z = card_bit (card); - y = (*last_card_word) >> z; - if (!y) + bit_position = card_bit (card); + card_word_value = (*last_card_word) >> bit_position; + if (!card_word_value) { - z = 0; + bit_position = 0; #ifdef CARD_BUNDLE - size_t lcw = card_word(card)+1; + // Using the card bundle, go through the remaining card words between here and + // card_word_end until we find one that is non-zero. + size_t lcw = card_word(card) + 1; if (gc_heap::find_card_dword (lcw, card_word_end) == FALSE) + { return FALSE; + } else { last_card_word = &card_table [lcw]; - y = *last_card_word; + card_word_value = *last_card_word; } #else //CARD_BUNDLE + // Go through the remaining card words between here and card_word_end until we find + // one that is non-zero. do { ++last_card_word; } + while ((last_card_word < &card_table [card_word_end]) && !(*last_card_word)); - while ((last_card_word < &card_table [card_word_end]) && - !(*last_card_word)); if (last_card_word < &card_table [card_word_end]) - y = *last_card_word; + { + card_word_value = *last_card_word; + } else + { + // We failed to find any non-zero card words before we got to card_word_end return FALSE; + } #endif //CARD_BUNDLE } - // Look for the lowest bit set - if (y) + if (card_word_value) { - while (!(y & 1)) + while (!(card_word_value & 1)) { - z++; - y = y / 2; + bit_position++; + card_word_value = card_word_value / 2; } } - card = (last_card_word - &card_table [0])* card_word_width + z; + + // card is the card word index * card size + the bit index within the card + card = (last_card_word - &card_table[0]) * card_word_width + bit_position; + do { - z++; - y = y / 2; - if ((z == card_word_width) && - (last_card_word < &card_table [card_word_end])) - { + // Keep going until we get to an un-set card. + bit_position++; + card_word_value = card_word_value / 2; + // If we reach the end of the card word and haven't hit a 0 yet, start going + // card word by card word until we get to one that's not fully set (0xFFFF...) + // or we reach card_word_end. + if ((bit_position == card_word_width) && (last_card_word < &card_table [card_word_end])) + { do { - y = *(++last_card_word); - }while ((last_card_word < &card_table [card_word_end]) && + card_word_value = *(++last_card_word); + } while ((last_card_word < &card_table [card_word_end]) && + #ifdef _MSC_VER - (y == (1 << card_word_width)-1) + (card_word_value == (1 << card_word_width)-1) #else // if left shift count >= width of type, // gcc reports error. - (y == ~0u) + (card_word_value == ~0u) #endif // _MSC_VER ); - z = 0; + bit_position = 0; } - } while (y & 1); + } while (card_word_value & 1); - end_card = (last_card_word - &card_table [0])* card_word_width + z; + end_card = (last_card_word - &card_table [0])* card_word_width + bit_position; + //dprintf (3, ("find_card: [%Ix, %Ix[ set", card, end_card)); dprintf (3, ("fc: [%Ix, %Ix[", card, end_card)); return TRUE; @@ -27533,49 +27574,49 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating) #ifdef BACKGROUND_GC dprintf (3, ("current_sweep_pos is %Ix, saved_sweep_ephemeral_seg is %Ix(%Ix)", current_sweep_pos, saved_sweep_ephemeral_seg, saved_sweep_ephemeral_start)); + heap_segment* soh_seg = heap_segment_rw (generation_start_segment (generation_of (max_generation))); - PREFIX_ASSUME(soh_seg != NULL); - while (soh_seg ) + PREFIX_ASSUME(soh_seg != NULL); + + while (soh_seg) { dprintf (3, ("seg %Ix, bgc_alloc: %Ix, alloc: %Ix", soh_seg, heap_segment_background_allocated (soh_seg), heap_segment_allocated (soh_seg))); + soh_seg = heap_segment_next_rw (soh_seg); } #endif //BACKGROUND_GC uint8_t* low = gc_low; uint8_t* high = gc_high; - size_t end_card = 0; + size_t end_card = 0; + generation* oldest_gen = generation_of (max_generation); int curr_gen_number = max_generation; - uint8_t* gen_boundary = generation_allocation_start - (generation_of (curr_gen_number - 1)); - uint8_t* next_boundary = (compute_next_boundary - (gc_low, curr_gen_number, relocating)); + uint8_t* gen_boundary = generation_allocation_start(generation_of(curr_gen_number - 1)); + uint8_t* next_boundary = compute_next_boundary(gc_low, curr_gen_number, relocating); + heap_segment* seg = heap_segment_rw (generation_start_segment (oldest_gen)); - PREFIX_ASSUME(seg != NULL); - uint8_t* beg = generation_allocation_start (oldest_gen); - uint8_t* end = compute_next_end (seg, low); - uint8_t* last_object = beg; + uint8_t* beg = generation_allocation_start (oldest_gen); + uint8_t* end = compute_next_end (seg, low); + uint8_t* last_object = beg; size_t cg_pointers_found = 0; - size_t card_word_end = (card_of (align_on_card_word (end)) / - card_word_width); + size_t card_word_end = (card_of (align_on_card_word (end)) / card_word_width); size_t n_eph = 0; size_t n_gen = 0; size_t n_card_set = 0; - uint8_t* nhigh = (relocating ? - heap_segment_plan_allocated (ephemeral_heap_segment) : high); + uint8_t* nhigh = (relocating ? heap_segment_plan_allocated (ephemeral_heap_segment) : high); BOOL foundp = FALSE; - uint8_t* start_address = 0; - uint8_t* limit = 0; + uint8_t* start_address = 0; + uint8_t* limit = 0; size_t card = card_of (beg); #ifdef BACKGROUND_GC BOOL consider_bgc_mark_p = FALSE; @@ -27591,6 +27632,7 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating) { if (card_of(last_object) > card) { + // cg means cross-generational dprintf (3, ("Found %Id cg pointers", cg_pointers_found)); if (cg_pointers_found == 0) { @@ -27599,23 +27641,29 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating) n_card_set -= (card_of (last_object) - card); total_cards_cleared += (card_of (last_object) - card); } - n_eph +=cg_pointers_found; + + n_eph += cg_pointers_found; cg_pointers_found = 0; card = card_of (last_object); } + if (card >= end_card) { - foundp = find_card (card_table, card, card_word_end, end_card); + // Find the first card that's set (between card and card_word_end) + foundp = find_card(card_table, card, card_word_end, end_card); if (foundp) { - n_card_set+= end_card - card; + // We found card(s) set. + n_card_set += end_card - card; start_address = max (beg, card_address (card)); } + limit = min (end, card_address (end_card)); } - if ((!foundp) || (last_object >= end) || (card_address (card) >= end)) + + if (!foundp || (last_object >= end) || (card_address (card) >= end)) { - if ((foundp) && (cg_pointers_found == 0)) + if (foundp && (cg_pointers_found == 0)) { dprintf(3,(" Clearing cards [%Ix, %Ix[ ", (size_t)card_address(card), (size_t)end)); @@ -27623,8 +27671,10 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating) n_card_set -= (card_of (end) - card); total_cards_cleared += (card_of (end) - card); } - n_eph +=cg_pointers_found; + + n_eph += cg_pointers_found; cg_pointers_found = 0; + if ((seg = heap_segment_next_in_range (seg)) != 0) { #ifdef BACKGROUND_GC @@ -27644,17 +27694,17 @@ void gc_heap::mark_through_cards_for_segments (card_fn fn, BOOL relocating) } } + // We've found a card and will now go through the objects in it. assert (card_set_p (card)); { - uint8_t* o = last_object; - + uint8_t* o = last_object; o = find_first_object (start_address, last_object); - //Never visit an object twice. - assert (o >= last_object); + // Never visit an object twice. + assert (o >= last_object); - //dprintf(3,("Considering card %Ix start object: %Ix, %Ix[ boundary: %Ix", - dprintf(3, ("c: %Ix, o: %Ix, l: %Ix[ boundary: %Ix", - card, (size_t)o, (size_t)limit, (size_t)gen_boundary)); + //dprintf(3,("Considering card %Ix start object: %Ix, %Ix[ boundary: %Ix", + dprintf(3, ("c: %Ix, o: %Ix, l: %Ix[ boundary: %Ix", + card, (size_t)o, (size_t)limit, (size_t)gen_boundary)); while (o < limit) { @@ -33291,7 +33341,7 @@ HRESULT GCHeap::Shutdown () if (card_table_refcount (ct) == 0) { destroy_card_table (ct); - g_gc_card_table = 0; + g_gc_card_table = nullptr; #ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP SoftwareWriteWatch::StaticClose(); #endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP @@ -35690,9 +35740,6 @@ void GCHeap::SetFinalizationRun (Object* obj) ((CObjectHeader*)obj)->GetHeader()->SetBit(BIT_SBLK_FINALIZER_RUN); } -#endif // FEATURE_PREMORTEM_FINALIZATION - -#ifdef FEATURE_PREMORTEM_FINALIZATION //-------------------------------------------------------------------- // diff --git a/src/coreclr/src/gc/gcpriv.h b/src/coreclr/src/gc/gcpriv.h index 1f97d7f..056b3839 100644 --- a/src/coreclr/src/gc/gcpriv.h +++ b/src/coreclr/src/gc/gcpriv.h @@ -4329,12 +4329,14 @@ dynamic_data* gc_heap::dynamic_data_of (int gen_number) #define card_size ((size_t)(OS_PAGE_SIZE/card_word_width)) #endif // BIT64 +// Returns the index of the card word a card is in inline size_t card_word (size_t card) { return card / card_word_width; } +// Returns the index of a card within its card word inline unsigned card_bit (size_t card) {