#ifndef GC_API_H_ #define GC_API_H_ #include #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; enum { GC_OPTION_FIXED_HEAP_SIZE, GC_OPTION_PARALLELISM }; struct gc_option { int option; double value; }; // FIXME: Conflict with bdw-gc GC_API. Switch prefix? #ifndef GC_API_ #define GC_API_ static #endif GC_API_ int gc_option_from_string(const char *str); GC_API_ int gc_init(int argc, struct gc_option argv[], struct heap **heap, struct mutator **mutator); GC_API_ struct mutator* gc_init_for_thread(uintptr_t *stack_base, struct heap *heap); 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; }; #endif // GC_API_H_