mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Add separate extents header
Will be useful to let slab heaps grow.
This commit is contained in:
parent
c949e4e4a9
commit
1a7d08baac
2 changed files with 93 additions and 16 deletions
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "assert.h"
|
||||
#include "debug.h"
|
||||
#include "extents.h"
|
||||
#include "gc-align.h"
|
||||
#include "gc-attrs.h"
|
||||
#include "gc-inline.h"
|
||||
|
@ -100,11 +101,6 @@ copy_space_object_region(struct gc_ref obj) {
|
|||
return (gc_ref_value(obj) / COPY_SPACE_REGION_SIZE) & 1;
|
||||
}
|
||||
|
||||
struct copy_space_extent {
|
||||
uintptr_t low_addr;
|
||||
uintptr_t high_addr;
|
||||
};
|
||||
|
||||
struct copy_space {
|
||||
struct copy_space_block *empty;
|
||||
struct copy_space_block *partly_full;
|
||||
|
@ -119,8 +115,7 @@ struct copy_space {
|
|||
uint8_t atomic_forward;
|
||||
size_t allocated_bytes_at_last_gc;
|
||||
size_t fragmentation_at_last_gc;
|
||||
struct copy_space_extent *extents;
|
||||
size_t nextents;
|
||||
struct extents *extents;
|
||||
struct copy_space_slab *slabs;
|
||||
size_t nslabs;
|
||||
};
|
||||
|
@ -542,11 +537,7 @@ copy_space_forward_if_traced(struct copy_space *space, struct gc_edge edge,
|
|||
|
||||
static inline int
|
||||
copy_space_contains(struct copy_space *space, struct gc_ref ref) {
|
||||
for (size_t i = 0; i < space->nextents; i++)
|
||||
if (space->extents[i].low_addr <= gc_ref_value(ref) &&
|
||||
gc_ref_value(ref) < space->extents[i].high_addr)
|
||||
return 1;
|
||||
return 0;
|
||||
return extents_contain_addr(space->extents, gc_ref_value(ref));
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -607,10 +598,8 @@ copy_space_init(struct copy_space *space, size_t size, int atomic) {
|
|||
space->atomic_forward = atomic;
|
||||
space->allocated_bytes_at_last_gc = 0;
|
||||
space->fragmentation_at_last_gc = 0;
|
||||
space->extents = calloc(1, sizeof(struct copy_space_extent));
|
||||
space->extents[0].low_addr = (uintptr_t) slabs;
|
||||
space->extents[0].high_addr = space->extents[0].low_addr + reserved;
|
||||
space->nextents = 1;
|
||||
space->extents = extents_allocate(10);
|
||||
extents_adjoin(space->extents, slabs, reserved);
|
||||
space->slabs = slabs;
|
||||
space->nslabs = nslabs;
|
||||
for (size_t slab = 0; slab < nslabs; slab++) {
|
||||
|
|
88
src/extents.h
Normal file
88
src/extents.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
#ifndef EXTENTS_H
|
||||
#define EXTENTS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gc-assert.h"
|
||||
|
||||
struct extent_range {
|
||||
uintptr_t lo_addr;
|
||||
uintptr_t hi_addr;
|
||||
};
|
||||
|
||||
struct extents {
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
struct extent_range ranges[];
|
||||
};
|
||||
|
||||
static inline int
|
||||
extents_contain_addr(struct extents *extents, uintptr_t addr) {
|
||||
size_t lo = 0;
|
||||
size_t hi = extents->size;
|
||||
while (lo != hi) {
|
||||
size_t mid = (lo + hi) / 2;
|
||||
struct extent_range range = extents->ranges[mid];
|
||||
if (addr < range.lo_addr) {
|
||||
hi = mid;
|
||||
} else if (addr < range.hi_addr) {
|
||||
return 1;
|
||||
} else {
|
||||
lo = mid + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct extents*
|
||||
extents_allocate(size_t capacity) {
|
||||
size_t byte_size =
|
||||
sizeof(struct extents) + sizeof(struct extent_range) * capacity;
|
||||
struct extents *ret = malloc(byte_size);
|
||||
if (!ret) __builtin_trap();
|
||||
memset(ret, 0, byte_size);
|
||||
ret->capacity = capacity;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct extents*
|
||||
extents_insert(struct extents *old, size_t idx, struct extent_range range) {
|
||||
if (old->size < old->capacity) {
|
||||
size_t bytes_to_move = sizeof(struct extent_range) * (old->size - idx);
|
||||
memmove(&old->ranges[idx + 1], &old->ranges[idx], bytes_to_move);
|
||||
old->ranges[idx] = range;
|
||||
old->size++;
|
||||
return old;
|
||||
} else {
|
||||
struct extents *new_ = extents_allocate(old->capacity * 2 + 1);
|
||||
memcpy(&new_->ranges[0], &old->ranges[0],
|
||||
sizeof(struct extent_range) * idx);
|
||||
memcpy(&new_->ranges[idx + 1], &old->ranges[idx],
|
||||
sizeof(struct extent_range) * (old->size - idx));
|
||||
new_->ranges[idx] = range;
|
||||
new_->size = old->size + 1;
|
||||
free(old);
|
||||
return new_;
|
||||
}
|
||||
}
|
||||
|
||||
static struct extents*
|
||||
extents_adjoin(struct extents *extents, void *lo_addr, size_t size) {
|
||||
size_t i;
|
||||
struct extent_range range = { (uintptr_t)lo_addr, (uintptr_t)lo_addr + size };
|
||||
for (i = 0; i < extents->size; i++) {
|
||||
if (range.hi_addr < extents->ranges[i].lo_addr) {
|
||||
break;
|
||||
} else if (range.hi_addr == extents->ranges[i].lo_addr) {
|
||||
extents->ranges[i].lo_addr = range.lo_addr;
|
||||
return extents;
|
||||
} else if (range.lo_addr == extents->ranges[i].hi_addr) {
|
||||
extents->ranges[i].hi_addr = range.hi_addr;
|
||||
return extents;
|
||||
}
|
||||
}
|
||||
return extents_insert(extents, i, range);
|
||||
}
|
||||
|
||||
#endif // EXTENTS_H
|
Loading…
Add table
Add a link
Reference in a new issue