roots.c cleanup
svn: r12244
This commit is contained in:
parent
8a70bde3c1
commit
6a4576c161
|
@ -1038,14 +1038,14 @@ unsigned long GC_get_stack_base()
|
||||||
|
|
||||||
#define traverse_roots(gcMUCK, set_bt_src) { \
|
#define traverse_roots(gcMUCK, set_bt_src) { \
|
||||||
unsigned long j; \
|
unsigned long j; \
|
||||||
if(roots) { \
|
if(roots->roots) { \
|
||||||
sort_and_merge_roots(); \
|
sort_and_merge_roots(); \
|
||||||
for(j = 0; j < roots_count; j += 2) { \
|
for(j = 0; j < roots->count; j += 2) { \
|
||||||
void **start = (void**)roots[j]; \
|
void **start = (void**)roots->roots[j]; \
|
||||||
void **end = (void**)roots[j+1]; \
|
void **end = (void**)roots->roots[j+1]; \
|
||||||
while(start < end) { \
|
while(start < end) { \
|
||||||
set_bt_src(start, BT_ROOT); \
|
set_bt_src(start, BT_ROOT); \
|
||||||
gcMUCK(*start++); \
|
gcMUCK(*start++); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
|
@ -11,10 +11,32 @@
|
||||||
#define ROOTS_PTR_ALIGNMENT WORD_SIZE
|
#define ROOTS_PTR_ALIGNMENT WORD_SIZE
|
||||||
#define ROOTS_PTR_TO_INT(x) ((unsigned long)x)
|
#define ROOTS_PTR_TO_INT(x) ((unsigned long)x)
|
||||||
|
|
||||||
static long roots_count;
|
typedef struct Roots {
|
||||||
static long roots_size;
|
long count;
|
||||||
static unsigned long *roots;
|
long size;
|
||||||
static int nothing_new = 0;
|
/* roots is a array of longs, logically grouped into start and end pairs.
|
||||||
|
* [ start0, end0, start1, end1, ... ]
|
||||||
|
*/
|
||||||
|
unsigned long *roots;
|
||||||
|
int nothing_new;
|
||||||
|
} Roots;
|
||||||
|
|
||||||
|
static Roots *roots = &(Roots) { 0 ,0, 0, 0, };
|
||||||
|
|
||||||
|
|
||||||
|
static void grow_roots(Roots *roots) {
|
||||||
|
unsigned long *new_roots;
|
||||||
|
|
||||||
|
roots->size = roots->size ? ( 2 * roots->size ) : 500;
|
||||||
|
new_roots = (unsigned long *)malloc(sizeof(unsigned long) * (roots->size + 1));
|
||||||
|
|
||||||
|
memcpy((void *)new_roots, (void *)roots->roots, sizeof(unsigned long) * roots->count);
|
||||||
|
|
||||||
|
if (roots->roots)
|
||||||
|
free(roots->roots);
|
||||||
|
|
||||||
|
roots->roots = new_roots;
|
||||||
|
}
|
||||||
|
|
||||||
static int compare_roots(const void *a, const void *b)
|
static int compare_roots(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
|
@ -26,57 +48,56 @@ static int compare_roots(const void *a, const void *b)
|
||||||
|
|
||||||
static void sort_and_merge_roots()
|
static void sort_and_merge_roots()
|
||||||
{
|
{
|
||||||
int i, offset, top;
|
if (roots->nothing_new)
|
||||||
|
|
||||||
if (nothing_new)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (roots_count < 4)
|
if (roots->count < 4)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
my_qsort(roots, roots_count >> 1, 2 * sizeof(unsigned long), compare_roots);
|
my_qsort(roots->roots, roots->count >> 1, 2 * sizeof(unsigned long), compare_roots);
|
||||||
offset = 0;
|
|
||||||
top = roots_count;
|
{
|
||||||
for (i = 2; i < top; i += 2) {
|
int i;
|
||||||
if ((roots[i - 2 - offset] <= roots[i])
|
int offset = 0;
|
||||||
&& ((roots[i - 1 - offset] + (ROOTS_PTR_ALIGNMENT - 1)) >= roots[i])) {
|
int top = roots->count;
|
||||||
/* merge: */
|
for (i = 2; i < top; i += 2) {
|
||||||
if (roots[i + 1] > roots[i - 1 - offset])
|
int astart = i - 2 - offset;
|
||||||
roots[i - 1 - offset] = roots[i + 1];
|
int aend = i - 1 - offset;
|
||||||
offset += 2;
|
int bstart = i;
|
||||||
roots_count -= 2;
|
int bend = i + 1;
|
||||||
} else if (roots[i] == roots[i + 1]) {
|
/*|----a----|
|
||||||
/* Remove empty range: */
|
* |----b----| */
|
||||||
offset += 2;
|
if ( (roots->roots[astart] <= roots->roots[bstart])
|
||||||
roots_count -= 2;
|
&& ((roots->roots[aend] + (ROOTS_PTR_ALIGNMENT - 1)) >= roots->roots[bstart])) {
|
||||||
} else if (offset) {
|
/* merge overlapping roots: */
|
||||||
/* compact: */
|
if (roots->roots[bend] > roots->roots[aend])
|
||||||
roots[i - offset] = roots[i];
|
roots->roots[aend] = roots->roots[bend];
|
||||||
roots[i + 1 - offset] = roots[i + 1];
|
offset += 2;
|
||||||
|
roots->count -= 2;
|
||||||
|
} else if (roots->roots[bstart] == roots->roots[bend]) {
|
||||||
|
/* Remove empty range: */
|
||||||
|
offset += 2;
|
||||||
|
roots->count -= 2;
|
||||||
|
} else if (offset) {
|
||||||
|
/* compact: */
|
||||||
|
int emptystart = i - offset;
|
||||||
|
int emptyend = i + 1 - offset;
|
||||||
|
roots->roots[emptystart] = roots->roots[bstart];
|
||||||
|
roots->roots[emptyend] = roots->roots[bend];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nothing_new = 1;
|
roots->nothing_new = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GC_add_roots(void *start, void *end)
|
void GC_add_roots(void *start, void *end)
|
||||||
{
|
{
|
||||||
if (roots_count >= roots_size) {
|
if (roots->count >= roots->size) {
|
||||||
unsigned long *naya;
|
grow_roots(roots);
|
||||||
|
|
||||||
roots_size = roots_size ? 2 * roots_size : 500;
|
|
||||||
naya = (unsigned long *)malloc(sizeof(unsigned long) * (roots_size + 1));
|
|
||||||
|
|
||||||
memcpy((void *)naya, (void *)roots,
|
|
||||||
sizeof(unsigned long) * roots_count);
|
|
||||||
|
|
||||||
if (roots)
|
|
||||||
free(roots);
|
|
||||||
|
|
||||||
roots = naya;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
roots[roots_count++] = ROOTS_PTR_TO_INT(start);
|
roots->roots[roots->count++] = ROOTS_PTR_TO_INT(start);
|
||||||
roots[roots_count++] = ROOTS_PTR_TO_INT(end) - ROOTS_PTR_ALIGNMENT;
|
roots->roots[roots->count++] = ROOTS_PTR_TO_INT(end) - ROOTS_PTR_ALIGNMENT;
|
||||||
nothing_new = 0;
|
roots->nothing_new = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user