mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-15 10:10:21 +02:00
Separate tagging from collector
The collector now has an abstract interface onto the embedder. The embedder has to supply some functionality, such as tracing and forwarding. This is a pretty big change in terms of lines but it's supposed to have no functional or performance change.
This commit is contained in:
parent
cacc28b577
commit
fb71c4c363
20 changed files with 452 additions and 306 deletions
70
gc-api.h
70
gc-api.h
|
@ -1,67 +1,13 @@
|
|||
#ifndef GC_API_H_
|
||||
#define GC_API_H_
|
||||
|
||||
#include "gc-config.h"
|
||||
#include "gc-assert.h"
|
||||
#include "gc-ref.h"
|
||||
#include "gc-edge.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef GC_DEBUG
|
||||
#define GC_DEBUG 0
|
||||
#endif
|
||||
|
||||
#define GC_ALWAYS_INLINE __attribute__((always_inline))
|
||||
#define GC_NEVER_INLINE __attribute__((noinline))
|
||||
|
||||
#define GC_UNLIKELY(e) __builtin_expect(e, 0)
|
||||
#define GC_LIKELY(e) __builtin_expect(e, 1)
|
||||
|
||||
#if GC_DEBUG
|
||||
#define GC_ASSERT(x) do { if (GC_UNLIKELY(!(x))) __builtin_trap(); } while (0)
|
||||
#else
|
||||
#define GC_ASSERT(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
struct gc_ref {
|
||||
uintptr_t value;
|
||||
};
|
||||
|
||||
static inline struct gc_ref gc_ref(uintptr_t value) {
|
||||
return (struct gc_ref){value};
|
||||
}
|
||||
static inline uintptr_t gc_ref_value(struct gc_ref ref) {
|
||||
return ref.value;
|
||||
}
|
||||
|
||||
static inline struct gc_ref gc_ref_null(void) {
|
||||
return gc_ref(0);
|
||||
}
|
||||
static inline int gc_ref_is_heap_object(struct gc_ref ref) {
|
||||
return ref.value != 0;
|
||||
}
|
||||
static inline struct gc_ref gc_ref_from_heap_object_or_null(void *obj) {
|
||||
return gc_ref((uintptr_t) obj);
|
||||
}
|
||||
static inline struct gc_ref gc_ref_from_heap_object(void *obj) {
|
||||
GC_ASSERT(obj);
|
||||
return gc_ref_from_heap_object_or_null(obj);
|
||||
}
|
||||
static inline void* gc_ref_heap_object(struct gc_ref ref) {
|
||||
GC_ASSERT(gc_ref_is_heap_object(ref));
|
||||
return (void *) gc_ref_value(ref);
|
||||
}
|
||||
|
||||
struct gc_edge {
|
||||
struct gc_ref *dst;
|
||||
};
|
||||
|
||||
static inline struct gc_edge gc_edge(void* addr) {
|
||||
return (struct gc_edge){addr};
|
||||
}
|
||||
static inline struct gc_ref gc_edge_ref(struct gc_edge edge) {
|
||||
return *edge.dst;
|
||||
}
|
||||
static inline void gc_edge_update(struct gc_edge edge, struct gc_ref ref) {
|
||||
*edge.dst = ref;
|
||||
}
|
||||
|
||||
// FIXME: prefix with gc_
|
||||
struct heap;
|
||||
struct mutator;
|
||||
|
@ -91,8 +37,8 @@ GC_API_ void gc_finish_for_thread(struct mutator *mut);
|
|||
GC_API_ void* gc_call_without_gc(struct mutator *mut, void* (*f)(void*),
|
||||
void *data) GC_NEVER_INLINE;
|
||||
|
||||
struct gc_header {
|
||||
uintptr_t tag;
|
||||
};
|
||||
GC_API_ inline void* gc_allocate(struct mutator *mut, size_t bytes);
|
||||
// FIXME: remove :P
|
||||
GC_API_ inline void* gc_allocate_pointerless(struct mutator *mut, size_t bytes);
|
||||
|
||||
#endif // GC_API_H_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue