Page MenuHomePhorge

ropes.c
No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None
#include "internal.h"
#include "gc/ropes.h"
#include "pool.h"
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
uintptr_t base;
uintptr_t end;
ant_pool_block_t *block;
bool has_live;
} gc_rope_mark_t;
static gc_rope_mark_t *g_rope_marks = NULL;
static int g_rope_mark_count = 0;
static int g_rope_mark_cap = 0;
static int rope_mark_cmp(const void *a, const void *b) {
const gc_rope_mark_t *ma = (const gc_rope_mark_t *)a;
const gc_rope_mark_t *mb = (const gc_rope_mark_t *)b;
if (ma->base < mb->base) return -1;
if (ma->base > mb->base) return 1;
return 0;
}
void gc_ropes_begin(ant_t *js) {
g_rope_mark_count = 0;
for (ant_pool_block_t *b = js->pool.rope.head; b; b = b->next) {
if (b->used == 0) continue;
if (g_rope_mark_count >= g_rope_mark_cap) {
int cap = g_rope_mark_cap ? g_rope_mark_cap * 2 : 32;
g_rope_marks = realloc(g_rope_marks, (size_t)cap * sizeof(gc_rope_mark_t));
g_rope_mark_cap = cap;
}
gc_rope_mark_t *m = &g_rope_marks[g_rope_mark_count++];
m->base = (uintptr_t)b->data;
m->end = m->base + b->used;
m->block = b;
m->has_live = false;
}
if (g_rope_mark_count > 1)
qsort(g_rope_marks, (size_t)g_rope_mark_count, sizeof(gc_rope_mark_t), rope_mark_cmp);
}
bool gc_ropes_mark(const void *ptr) {
if (!ptr || g_rope_mark_count == 0) return false;
uintptr_t p = (uintptr_t)ptr;
int lo = 0, hi = g_rope_mark_count - 1;
while (lo <= hi) {
int mid = lo + (hi - lo) / 2;
gc_rope_mark_t *m = &g_rope_marks[mid];
if (p < m->base) hi = mid - 1;
else if (p >= m->end) lo = mid + 1;
else {
m->has_live = true;
return true;
}
}
return false;
}
static void unlink_rope_block(ant_pool_t *pool, ant_pool_block_t *block) {
if (block->prev) block->prev->next = block->next;
else pool->head = block->next;
if (block->next) block->next->prev = block->prev;
}
void gc_ropes_sweep(ant_t *js) {
for (int i = 0; i < g_rope_mark_count; i++) {
gc_rope_mark_t *m = &g_rope_marks[i];
if (!m->has_live) {
unlink_rope_block(&js->pool.rope, m->block);
m->block->used = 0;
m->block->next = NULL;
pool_free_set_next(m->block, js->pool.rope.free_head);
pool_block_madvise_free(m->block);
js->pool.rope.free_head = m->block;
}}
ant_pool_block_t *f = js->pool.rope.free_head;
int kept = 0;
while (f && kept < 2) {
f = pool_free_next(f);
kept++;
}
while (f) {
ant_pool_block_t *next = pool_free_next(f);
pool_block_free(f);
f = next;
}
if (kept > 0) {
f = js->pool.rope.free_head;
for (int k = 1; k < kept && f; k++) f = pool_free_next(f);
if (f) pool_free_set_next(f, NULL);
} else js->pool.rope.free_head = NULL;
g_rope_mark_count = 0;
}

File Metadata

Mime Type
text/x-c
Expires
Fri, Apr 3, 12:43 PM (1 d, 22 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
520465
Default Alt Text
ropes.c (2 KB)

Event Timeline