/* should be properly aligned and valid. */ GC_INNER void GC_exclude_static_roots_inner(void *start, void *finish) { struct exclusion * next; size_t next_index, i; GC_ASSERT((word)start % sizeof(word) == 0); GC_ASSERT(start < finish); if (0 == GC_excl_table_entries) { next = 0; } else { next = GC_next_exclusion(start); } if (0 != next) { if ((word)(next -> e_start) < (word) finish) { /* incomplete error check. */ ABORT("Exclusion ranges overlap"); } if ((word)(next -> e_start) == (word) finish) { /* extend old range backwards */ next -> e_start = (ptr_t)start; return; } next_index = next - GC_excl_table; for (i = GC_excl_table_entries; i > next_index; --i) { GC_excl_table[i] = GC_excl_table[i-1]; } } else { next_index = GC_excl_table_entries; } if (GC_excl_table_entries == MAX_EXCLUSIONS) ABORT("Too many exclusions"); GC_excl_table[next_index].e_start = (ptr_t)start; GC_excl_table[next_index].e_end = (ptr_t)finish; ++GC_excl_table_entries; }
/*ARGSUSED*/ STATIC void GC_push_conditional_with_exclusions(ptr_t bottom, ptr_t top, GC_bool all) { struct exclusion * next; ptr_t excl_start; while (bottom < top) { next = GC_next_exclusion(bottom); if (0 == next || (excl_start = next -> e_start) >= top) { GC_push_conditional(bottom, top, all); return; } if (excl_start > bottom) GC_push_conditional(bottom, excl_start, all); bottom = next -> e_end; } }
/* Invoke push_conditional on ranges that are not excluded. */ STATIC void GC_push_conditional_with_exclusions(ptr_t bottom, ptr_t top, GC_bool all GC_ATTR_UNUSED) { while ((word)bottom < (word)top) { struct exclusion *next = GC_next_exclusion(bottom); ptr_t excl_start; if (0 == next || (word)(excl_start = next -> e_start) >= (word)top) { GC_PUSH_CONDITIONAL(bottom, top, all); break; } if ((word)excl_start > (word)bottom) GC_PUSH_CONDITIONAL(bottom, excl_start, all); bottom = next -> e_end; } }