mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-13 01:00:21 +02:00
Record object sizes in metadata byte array
This will let us avoid paging in objects when sweeping.
This commit is contained in:
parent
3a04078044
commit
ce69e9ed4c
1 changed files with 17 additions and 18 deletions
35
mark-sweep.h
35
mark-sweep.h
|
@ -646,19 +646,11 @@ static void unlink_medium_object(struct gcobj_free_medium **prev,
|
|||
*prev = medium->next;
|
||||
}
|
||||
|
||||
static size_t live_object_granules(struct gcobj *obj) {
|
||||
size_t bytes;
|
||||
switch (tag_live_alloc_kind (obj->tag)) {
|
||||
#define COMPUTE_SIZE(name, Name, NAME) \
|
||||
case ALLOC_KIND_##NAME: \
|
||||
bytes = name##_size((Name*)obj); \
|
||||
break;
|
||||
FOR_EACH_HEAP_OBJECT_KIND(COMPUTE_SIZE)
|
||||
#undef COMPUTE_SIZE
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
return size_to_granules(bytes);
|
||||
static size_t mark_space_live_object_granules(uint8_t *metadata) {
|
||||
size_t n = 0;
|
||||
while ((metadata[n] & METADATA_BYTE_END) == 0)
|
||||
n++;
|
||||
return n + 1;
|
||||
}
|
||||
|
||||
static size_t sweep_and_check_live(uint8_t *loc, uint8_t live_mask) {
|
||||
|
@ -752,7 +744,7 @@ static int sweep(struct mutator *mut,
|
|||
}
|
||||
// Object survived collection; skip over it and continue sweeping.
|
||||
ASSERT((*mark) & live_mask);
|
||||
sweep += live_object_granules((struct gcobj *)sweep) * GRANULE_SIZE;
|
||||
sweep += mark_space_live_object_granules(mark) * GRANULE_SIZE;
|
||||
}
|
||||
|
||||
mut->sweep = sweep;
|
||||
|
@ -772,8 +764,6 @@ static void finish_sweeping(struct mutator *mut) {
|
|||
size_t free_granules = next_mark(mark, limit_granules, live_mask);
|
||||
if (free_granules) {
|
||||
ASSERT(free_granules <= limit_granules);
|
||||
size_t free_bytes = free_granules * GRANULE_SIZE;
|
||||
sweep += free_bytes;
|
||||
mark += free_granules;
|
||||
limit_granules -= free_granules;
|
||||
if (limit_granules == 0)
|
||||
|
@ -781,8 +771,7 @@ static void finish_sweeping(struct mutator *mut) {
|
|||
}
|
||||
// Object survived collection; skip over it and continue sweeping.
|
||||
ASSERT((*mark) & live_mask);
|
||||
size_t live_granules = live_object_granules((struct gcobj *)sweep);
|
||||
sweep += live_granules * GRANULE_SIZE;
|
||||
size_t live_granules = mark_space_live_object_granules(mark);
|
||||
limit_granules -= live_granules;
|
||||
mark += live_granules;
|
||||
}
|
||||
|
@ -839,6 +828,9 @@ static void* allocate_medium(struct mutator *mut, enum alloc_kind kind,
|
|||
split_medium_object(mut, medium, granules);
|
||||
struct gcobj *obj = (struct gcobj *)medium;
|
||||
obj->tag = tag_live(kind);
|
||||
uint8_t *metadata = object_metadata_byte(obj);
|
||||
metadata[0] = METADATA_BYTE_YOUNG;
|
||||
metadata[granules - 1] = METADATA_BYTE_END;
|
||||
return medium;
|
||||
}
|
||||
}
|
||||
|
@ -933,6 +925,13 @@ static inline void* allocate_small(struct mutator *mut, enum alloc_kind kind,
|
|||
if (!*loc)
|
||||
fill_small(mut, granules);
|
||||
struct gcobj_free *ret = *loc;
|
||||
uint8_t *metadata = object_metadata_byte(ret);
|
||||
if (granules == 1) {
|
||||
metadata[0] = METADATA_BYTE_YOUNG | METADATA_BYTE_END;
|
||||
} else {
|
||||
metadata[0] = METADATA_BYTE_YOUNG;
|
||||
metadata[granules - 1] = METADATA_BYTE_END;
|
||||
}
|
||||
*loc = ret->next;
|
||||
struct gcobj *obj = (struct gcobj *)ret;
|
||||
obj->tag = tag_live(kind);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue