@@ -1,4 +1,5 @@
1#include "idris_heap.h"
1#include "idris_heap.h"
3#include <stdlib.h>
4#include <stdlib.h>
4#include <stddef.h>
5#include <stddef.h>
@@ -8,7 +9,9 @@ void alloc_heap(Heap * h, size_t heap_size)
9 char * mem = malloc(heap_size);
10 char * mem = malloc(heap_size);
10 if (mem == NULL) {
11 if (mem == NULL) {
11− fprintf(stderr, "Unable to allocate heap. Requested %d bytes.\n", heap_size);
13+ "RTS ERROR: Unable to allocate heap. Requested %d bytes.\n",
12 exit(EXIT_FAILURE);
15 exit(EXIT_FAILURE);
@@ -29,3 +32,94 @@ void free_heap(Heap * h) {
29 free(h->old);
32 free(h->old);
37+/******************** Heap testing ********************************************/
38+void heap_check_underflow(Heap * heap) {
39+ if (!(heap->heap <= heap->next)) {
40+ fprintf(stderr, "RTS ERROR: HEAP UNDERFLOW <bot %p> <cur %p>\n",
41+ heap->heap, heap->next);
46+void heap_check_overflow(Heap * heap) {
47+ if (!(heap->next <= heap->end)) {
48+ fprintf(stderr, "RTS ERROR: HEAP OVERFLOW <cur %p> <end %p>\n",
49+ heap->next, heap->end);
54+int is_valid_ref(VAL v) {
55+ return (v != NULL) && !(ISINT(v));
58+int ref_in_heap(Heap * heap, VAL v) {
59+ return ((VAL)heap->heap <= v) && (v < (VAL)heap->next);
62+// Checks three important properties:
64+// Check if all pointers in the _heap_ points only to heap.
65+// 2. Unidirectionality. (if compact gc)
66+// All references in the heap should be are unidirectional. In other words,
67+// more recently allocated closure can point only to earlier allocated one.
68+// 3. After gc there should be no forward references.
70+void heap_check_pointers(Heap * heap) {
73+ size_t item_size = 0;
74+ for(scan = heap->heap; scan < heap->next; scan += item_size) {
75+ item_size = *((size_t*)scan);
76+ VAL heap_item = (VAL)(scan + sizeof(size_t));
78+ switch(GETTY(heap_item)) {
81+ int ar = ARITY(heap_item);
83+ for(i = 0; i < ar; ++i) {
84+ VAL ptr = heap_item->info.c.args[i];
86+ if (is_valid_ref(ptr)) {
87+ // Check for closure.
88+ if (!ref_in_heap(heap, ptr)) {
90+ "RTS ERROR: heap closure broken. "\
91+ "<HEAP %p %p %p> <REF %p>\n",
92+ heap->heap, heap->next, heap->end, ptr);
96+ // Check for unidirectionality.
97+ if (!(ptr < heap_item)) {
99+ "RTS ERROR: heap unidirectionality broken:" \
100+ "<CON %p> <FIELD %p>\n",
110+ // Check for artifacts after cheney gc.
111+ fprintf(stderr, "RTS ERROR: FWD in working heap.\n");
120+void heap_check_all(Heap * heap)
122+ heap_check_underflow(heap);
123+ heap_check_overflow(heap);
124+ heap_check_pointers(heap);