/* re-registering dynamic libraries. */ void GC_add_roots_inner(ptr_t b, ptr_t e, GC_bool tmp) { GC_ASSERT((word)b <= (word)e); b = (ptr_t)(((word)b + (sizeof(word) - 1)) & ~(word)(sizeof(word) - 1)); /* round b up to word boundary */ e = (ptr_t)((word)e & ~(word)(sizeof(word) - 1)); /* round e down to word boundary */ if ((word)b >= (word)e) return; /* nothing to do */ # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) /* Spend the time to ensure that there are no overlapping */ /* or adjacent intervals. */ /* This could be done faster with e.g. a */ /* balanced tree. But the execution time here is */ /* virtually guaranteed to be dominated by the time it */ /* takes to scan the roots. */ { int i; struct roots * old = NULL; /* initialized to prevent warning. */ for (i = 0; i < n_root_sets; i++) { old = GC_static_roots + i; if ((word)b <= (word)old->r_end && (word)e >= (word)old->r_start) { if ((word)b < (word)old->r_start) { GC_root_size += old->r_start - b; old -> r_start = b; } if ((word)e > (word)old->r_end) { GC_root_size += e - old->r_end; old -> r_end = e; } old -> r_tmp &= tmp; break; } } if (i < n_root_sets) { /* merge other overlapping intervals */ struct roots *other; for (i++; i < n_root_sets; i++) { other = GC_static_roots + i; b = other -> r_start; e = other -> r_end; if ((word)b <= (word)old->r_end && (word)e >= (word)old->r_start) { if ((word)b < (word)old->r_start) { GC_root_size += old->r_start - b; old -> r_start = b; } if ((word)e > (word)old->r_end) { GC_root_size += e - old->r_end; old -> r_end = e; } old -> r_tmp &= other -> r_tmp; /* Delete this entry. */ GC_root_size -= (other -> r_end - other -> r_start); other -> r_start = GC_static_roots[n_root_sets-1].r_start; other -> r_end = GC_static_roots[n_root_sets-1].r_end; n_root_sets--; } } return; } } # else { struct roots * old = (struct roots *)GC_roots_present(b); if (old != 0) { if ((word)e <= (word)old->r_end) { old -> r_tmp &= tmp; return; /* already there */ } if (old -> r_tmp == tmp || !tmp) { /* Extend the existing root. */ GC_root_size += e - old -> r_end; old -> r_end = e; old -> r_tmp = tmp; return; } b = old -> r_end; } } # endif if (n_root_sets == MAX_ROOT_SETS) { ABORT("Too many root sets"); } # ifdef DEBUG_ADD_DEL_ROOTS GC_log_printf("Adding data root section %d: %p .. %p%s\n", n_root_sets, (void *)b, (void *)e, tmp ? " (temporary)" : ""); # endif GC_static_roots[n_root_sets].r_start = (ptr_t)b; GC_static_roots[n_root_sets].r_end = (ptr_t)e; GC_static_roots[n_root_sets].r_tmp = tmp; # if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) GC_static_roots[n_root_sets].r_next = 0; add_roots_to_index(GC_static_roots + n_root_sets); # endif GC_root_size += e - b; n_root_sets++; }
/* re-registering dynamic libraries. */ void GC_add_roots_inner(ptr_t b, ptr_t e, GC_bool tmp) { struct roots * old; /* Adjust and check range boundaries for safety */ GC_ASSERT((word)b % sizeof(word) == 0); e = (ptr_t)((word)e & ~(sizeof(word) - 1)); GC_ASSERT(b <= e); if (b == e) return; /* nothing to do? */ # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) /* Spend the time to ensure that there are no overlapping */ /* or adjacent intervals. */ /* This could be done faster with e.g. a */ /* balanced tree. But the execution time here is */ /* virtually guaranteed to be dominated by the time it */ /* takes to scan the roots. */ { register int i; old = 0; /* initialized to prevent warning. */ for (i = 0; i < n_root_sets; i++) { old = GC_static_roots + i; if (b <= old -> r_end && e >= old -> r_start) { if (b < old -> r_start) { old -> r_start = b; GC_root_size += (old -> r_start - b); } if (e > old -> r_end) { old -> r_end = e; GC_root_size += (e - old -> r_end); } old -> r_tmp &= tmp; break; } } if (i < n_root_sets) { /* merge other overlapping intervals */ struct roots *other; for (i++; i < n_root_sets; i++) { other = GC_static_roots + i; b = other -> r_start; e = other -> r_end; if (b <= old -> r_end && e >= old -> r_start) { if (b < old -> r_start) { old -> r_start = b; GC_root_size += (old -> r_start - b); } if (e > old -> r_end) { old -> r_end = e; GC_root_size += (e - old -> r_end); } old -> r_tmp &= other -> r_tmp; /* Delete this entry. */ GC_root_size -= (other -> r_end - other -> r_start); other -> r_start = GC_static_roots[n_root_sets-1].r_start; other -> r_end = GC_static_roots[n_root_sets-1].r_end; n_root_sets--; } } return; } } # else old = GC_roots_present(b); if (old != 0) { if (e <= old -> r_end) /* already there */ return; /* else extend */ GC_root_size += e - old -> r_end; old -> r_end = e; return; } # endif if (n_root_sets == MAX_ROOT_SETS) { ABORT("Too many root sets"); } GC_static_roots[n_root_sets].r_start = (ptr_t)b; GC_static_roots[n_root_sets].r_end = (ptr_t)e; GC_static_roots[n_root_sets].r_tmp = tmp; # if !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) GC_static_roots[n_root_sets].r_next = 0; add_roots_to_index(GC_static_roots + n_root_sets); # endif GC_root_size += e - b; n_root_sets++; }