Index: src/examples/gc_no_raii/internal/collector.h
===================================================================
--- src/examples/gc_no_raii/internal/collector.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
+++ src/examples/gc_no_raii/internal/collector.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tools.h"
+
+#include "gcpointers.h"
+#include "internal/collector.h"
+#include "internal/gc_tools.h"
+#include "internal/globals.h"
+#include "internal/object_header.h"
+#include "internal/state.h"
+
+typedef int worklist_t;
+
+inline bool gc_is_managed(void* address)
+{
+	return gc_is_in_heap(gc_get_state(), address);
+}
+
+inline gc_object_header* gc_get_object_ptr(void* ptr)
+{
+	void* clean = gc_get_aligned_ptr(ptr);
+	return ((gc_object_header*)clean) - 1;
+}
+
+inline struct gc_memory_pool* pool_of(void* address)
+{
+	return (struct gc_memory_pool*)(((intptr_t)address) & POOL_PTR_MASK);
+}
+
+inline void gc_conditional_collect()
+{
+	if(gc_needs_collect(gc_get_state()))
+	{
+		gc_collect(gc_get_state());
+	}
+}
+
+gcpointer_t** gc_find_previous_ref(gcpointer_t* target);
+
+void* gc_allocate(size_t size);
+
+void gc_process_reference(void** ref, worklist_t* worklist);
+
+struct gc_object_header* gc_copy_object(struct gc_object_header* ptr);
+
+void gc_scan_object(struct gc_object_header* object, worklist_t* worklist);
Index: src/examples/gc_no_raii/internal/gc_tools.h
===================================================================
--- src/examples/gc_no_raii/internal/gc_tools.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
+++ src/examples/gc_no_raii/internal/gc_tools.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tools.h"
+#include "globals.h"
+
+inline bool gc_is_aligned(void* address)
+{
+	return (((intptr_t)address) & (~OBJECT_PTR_MASK)) == 0;
+}
+
+inline void* gc_get_aligned_ptr(void* address)
+{
+	return (void*)(((intptr_t)address) & (OBJECT_PTR_MASK));
+}
+
+inline void* gc_write_aligned_ptr(void** reference, void* address)
+{
+	size_t ref_last_bits = ((intptr_t)*reference) & (~OBJECT_PTR_MASK);
+
+      size_t new_val = ((intptr_t)address) & OBJECT_PTR_MASK;
+
+      (*reference) = (void*)(new_val | ref_last_bits);
+
+	return *reference;
+}
+
+inline size_t gc_compute_size(size_t size)
+{
+	size_t word_size = ((size - 1) / OBJECT_ALLIGNMENT) + 1;
+	size_t ret = word_size * OBJECT_ALLIGNMENT;
+
+	check(ret >= size);
+	check((ret % OBJECT_ALLIGNMENT) == 0);
+	check( ((size % OBJECT_ALLIGNMENT) != 0) || (ret == size) );
+
+	return ret;
+}
Index: src/examples/gc_no_raii/internal/globals.h
===================================================================
--- src/examples/gc_no_raii/internal/globals.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
+++ src/examples/gc_no_raii/internal/globals.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+static const size_t POOL_SIZE_EXP = 24;
+static const size_t POOL_SIZE_BYTES = 0x1 << POOL_SIZE_EXP;
+static const size_t POOL_PTR_MASK = ~(POOL_SIZE_BYTES - 1);
+
+static const size_t CARDS_SIZE_EXP = 12;
+static const size_t CARDS_SIZE_BYTES = 0x1 << CARDS_SIZE_EXP;
+static const size_t CARDS_OFFSET_MASK = (~(CARDS_SIZE_BYTES - 1)) & (POOL_SIZE_BYTES - 1);
+static const size_t CARDS_COUNT = POOL_SIZE_BYTES / CARDS_SIZE_BYTES;
+
+static const size_t OBJECT_ALLIGNMENT = sizeof(size_t);
+static const size_t OBJECT_PTR_MASK = ~(OBJECT_ALLIGNMENT - 1);
Index: src/examples/gc_no_raii/internal/object_header.h
===================================================================
--- src/examples/gc_no_raii/internal/object_header.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
+++ src/examples/gc_no_raii/internal/object_header.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tools.h"
+
+static const void* CANARY_VALUE = (void*)0xCAFEBABACAFEBABA;
+
+struct gcpointer_t;
+
+struct gc_object_header
+{
+	#if _DEBUG
+		void* canary_start;
+	#endif
+
+	size_t				size;
+	gcpointer_t* 			root_chain;
+	gcpointer_t*			type_chain;
+	struct gc_object_header*	forward;
+	bool					is_forwarded;
+
+	#if _DEBUG
+		void* canary_end;
+	#endif
+};
Index: src/examples/gc_no_raii/internal/state.c
===================================================================
--- src/examples/gc_no_raii/internal/state.c	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
+++ src/examples/gc_no_raii/internal/state.c	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
@@ -0,0 +1,15 @@
+#include "state.h"
+
+void swap();
+
+void sweep_roots(std::vector<void**>& worklist);
+
+void clear();
+
+void calc_usage();
+
+
+#if DEBUG
+	bool roots_match();
+	bool no_from_space_ref();
+#endif
Index: src/examples/gc_no_raii/internal/state.h
===================================================================
--- src/examples/gc_no_raii/internal/state.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
+++ src/examples/gc_no_raii/internal/state.h	(revision e47f529d33f49f6a3d06c4a4bcde0fb84b62eab3)
@@ -0,0 +1,56 @@
+#pragma once
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "tools.h"
+
+struct gc_state
+{
+	bool is_initialized;
+	uint8_t from_code;
+	struct gc_memory_pool* to_space;
+	struct gc_memory_pool* from_space;
+
+	size_t total_space;
+	size_t used_space;
+
+	const struct memory_pool* 	pools_table;
+	size_t 				pools_table_count;
+};
+
+void gc_state_ctor(gc_state* state);
+
+inline gc_state* get_state()
+{
+	static gc_state s;
+	if(!s.is_initialized) gc_state_ctor(s);
+	return &s;
+}
+
+inline bool needs_collect(gc_state* state)
+{
+	return state->used_space * 2 > state->total_space;
+}
+
+void gc_collect(gc_state* state);
+
+void* gc_try_allocate(gc_state* state, size_t size);
+
+void gc_allocate_pool(gc_state* state);
+
+bool gc_is_in_heap(const gc_state* state, void* address);
+
+bool gc_is_in_to_space(const gc_state* state, void* address);
+
+inline uint8_t gc_from_space_code(const gc_state* state)
+{
+	return state->from_code;
+}
+
+struct gc_object_header* gc_get_object_for_ref(gc_state* state, void*);
+
+inline void gc_register_allocation(gc_state* state, size_t size)
+{
+	state->used_space += size;
+}
