]> git.mdlowis.com Git - archive/atc.git/commitdiff
finished testing heap.c
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 21 Apr 2015 01:36:29 +0000 (21:36 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 21 Apr 2015 01:36:29 +0000 (21:36 -0400)
source/runtime/gc.c
source/runtime/heap.c
source/runtime/heap.h
source/runtime/segment.c
tests/test_heap.c

index 985f7f93ed256291ac7d0b2119c083ca68a00785..a21f90972eae0ae5ba2cf3a6ab0b1499112e27a2 100644 (file)
@@ -4,10 +4,10 @@
 #include <stdlib.h>
 #include <setjmp.h>
 
-typedef struct {
-    uint64_t objmap;
-    uint8_t data[];
-} obj_t;
+//typedef struct {
+//    uint64_t objmap;
+//    uint8_t data[];
+//} obj_t;
 
 typedef struct root_t {
     struct root_t* next;
@@ -41,17 +41,20 @@ void gc_add_root(void* address, size_t size)
 
 void* gc_object(uint64_t objmap, size_t num_slots)
 {
-    obj_t* obj = heap_allocate(Heap, num_slots+1);
-    obj->objmap = objmap;
-    obj++;
-    return obj;
+    (void)objmap;
+    (void)num_slots;
+    return NULL;
+//    obj_t* obj = heap_allocate(Heap, num_slots+1);
+//    obj->objmap = objmap;
+//    obj++;
+//    return obj;
 }
 
 void* gc_allocate(size_t size)
 {
     size_t slot_sz   = sizeof(uintptr_t);
     size_t num_slots = (size + slot_sz - 1) / slot_sz;
-    return heap_allocate(Heap, num_slots + 1);
+    return heap_allocate(Heap, UINT16_MAX, num_slots + 1);
 }
 
 static void gc_scan_object(void* object) {
index 22e710f8f95bc52056800cd6d2253d4f9778ff4a..cc72f5c9cd3faf187e06d1beec26c6a3c0ad3a82 100644 (file)
@@ -52,9 +52,8 @@ void heap_destroy(heap_t* heap)
     free(heap);
 }
 
-static void* allocate_small_block(heap_t* heap, uintptr_t num_slots)
+static void* allocate_small_block(heap_t* heap, uint64_t ptrmap, uintptr_t num_slots)
 {
-    void* object;
     uintptr_t index = (num_slots >= MIN_NUM_SLOTS) ? (num_slots - HEAP_INDEX_OFFSET) : 0;
     /* If we dont have any available segments, allocate a new one */
     if (NULL == heap->heaps[index].available) {
@@ -62,7 +61,8 @@ static void* allocate_small_block(heap_t* heap, uintptr_t num_slots)
         splaytree_insert(heap->segments, (uintptr_t)&(heap->heaps[index].available->start[0]), heap->heaps[index].available);
     }
     /* Allocate the object */
-    object = segment_alloc(heap->heaps[index].available);
+    obj_t* obj = (obj_t*)segment_alloc(heap->heaps[index].available);
+    obj->objmap = ptrmap;
     /* If we filled it up then move it to the full list */
     if (segment_full(heap->heaps[index].available)) {
         segment_t* current = heap->heaps[index].available;
@@ -70,25 +70,27 @@ static void* allocate_small_block(heap_t* heap, uintptr_t num_slots)
         current->next = heap->heaps[index].full;
         heap->heaps[index].full = current;
     }
-    return object;
+    return (void*)(obj+1);
 }
 
-static void* allocate_large_block(heap_t* heap, uintptr_t num_slots)
+static void* allocate_large_block(heap_t* heap, uint64_t ptrmap, uintptr_t num_slots)
 {
     uintptr_t size = (num_slots * sizeof(uintptr_t));
     block_t* blk = (block_t*)malloc(sizeof(block_t) + size);
     blk->size = size;
     splaytree_insert(heap->blocks, (uintptr_t)&blk->data[0], blk);
-    return (&blk->data[0]);
+    obj_t* obj = (obj_t*)(&blk->data[0]);
+    obj->objmap = ptrmap;
+    return (obj_t*)(obj+1);
 }
 
-void* heap_allocate(heap_t* heap, uintptr_t num_slots)
+void* heap_allocate(heap_t* heap, uint64_t ptrmap, uintptr_t num_slots)
 {
     void* obj = NULL;
     if (num_slots <= MAX_NUM_SLOTS) {
-        obj = allocate_small_block(heap, num_slots);
+        obj = allocate_small_block(heap, ptrmap, num_slots);
     } else {
-        obj = allocate_large_block(heap, num_slots);
+        obj = allocate_large_block(heap, ptrmap, num_slots);
     }
     return obj;
 }
@@ -97,6 +99,10 @@ void heap_start_collection(heap_t* heap)
 {
     heap->greylist = heap->blocks;
     heap->blocks   = splaytree_create((del_fn_t)free, (cmp_fn_t)block_compare);
+    for (unsigned int i = 0; i < NUM_HEAP_STACKS; i++) {
+        segment_clear_map(heap->heaps[i].available);
+        segment_clear_map(heap->heaps[i].full);
+    }
 }
 
 void heap_finish_collection(heap_t* heap)
@@ -130,7 +136,7 @@ void heap_finish_collection(heap_t* heap)
 
 void* heap_find_and_mark(heap_t* heap, uintptr_t addr)
 {
-    void* obj = NULL;
+    obj_t* obj = NULL;
     segment_t* seg = splaytree_lookup(heap->segments, addr);
     if (NULL != seg) {
         obj = segment_find_and_mark(seg, addr);
@@ -138,9 +144,9 @@ void* heap_find_and_mark(heap_t* heap, uintptr_t addr)
         block_t* block = splaytree_delete(heap->greylist, addr);
         if (NULL != block) {
             splaytree_insert(heap->blocks, addr, block);
-            obj = &block->data[0];
+            obj = (obj_t*)&block->data[0];
         }
     }
-    return obj;
+    return (obj == NULL) ? NULL : (void*)(obj+1);
 }
 
index 7779c8ddb7d0873b8ef257b683a86838b3c2ac52..db1eaa8285ca420c1a42c7041f2bd7c8cddafb6b 100644 (file)
 
 #define NUM_HEAP_STACKS (MAX_NUM_SLOTS)
 
+typedef struct {
+    uint64_t objmap;
+    uint8_t data[];
+} obj_t;
+
 typedef struct block_t {
     uintptr_t size;
     uintptr_t data[];
@@ -35,7 +40,7 @@ heap_t* heap_create(void);
 
 void heap_destroy(heap_t* heap);
 
-void* heap_allocate(heap_t* heap, uintptr_t num_slots);
+void* heap_allocate(heap_t* heap, uint64_t ptrmap, uintptr_t num_slots);
 
 void heap_start_collection(heap_t* heap);
 
index 92e09f0846ab2d9bbd79ef291c43415776d8cafb..268f0f6712cda192edfb527ed9b004736fc3e330 100644 (file)
@@ -73,7 +73,10 @@ void* segment_alloc(segment_t* seg) {
 
 void segment_clear_map(segment_t* seg)
 {
-    memset(seg->blockmap, 0xFFu, sizeof(seg->blockmap));
+    while (NULL != seg) {
+        memset(seg->blockmap, 0xFFu, sizeof(seg->blockmap));
+        seg = seg->next;
+    }
 }
 
 void* segment_find_and_mark(segment_t* seg, uintptr_t addr) {
index e1a9cde2fc3db22a2abc231229efc17203e43150..b43fc46a03fa6f2a8f146318909e7c7f3ab78808 100644 (file)
@@ -1,15 +1,16 @@
 #include "atf.h"
 #include "heap.h"
-
 #include "gc.h"
+#include <stdio.h>
+
 TEST_SUITE(Heap) {
     /* Verify: heap_create
      *************************************************************************/
     TEST(Verify_Create_allocates_and_initializes_a_heap) {
         heap_t* heap = heap_create();
         CHECK(heap != NULL);
-        CHECK(NULL != heap_allocate(heap, 64));
-        CHECK(NULL != heap_allocate(heap, 65));
+        CHECK(NULL != heap_allocate(heap, 0, 64));
+        CHECK(NULL != heap_allocate(heap, 0, 65));
         heap_destroy(heap);
     }
 
@@ -17,17 +18,17 @@ TEST_SUITE(Heap) {
      *************************************************************************/
     TEST(Verify_Allocate_should_allocate_a_new_segment_if_the_subheap_is_empty) {
         heap_t* heap = heap_create();
-        CHECK(NULL != heap_allocate(heap, 1));
+        CHECK(NULL != heap_allocate(heap, 0, 1));
         CHECK(heap->heaps[0].available != NULL);
         heap_destroy(heap);
     }
 
     TEST(Verify_Allocate_should_allocate_a_new_segment_if_the_current_segment_is_full) {
         heap_t* heap = heap_create();
-        CHECK(NULL != heap_allocate(heap, 1));
+        CHECK(NULL != heap_allocate(heap, 0, 1));
         heap->heaps[0].available->blockmap[0] = 1 << ((sizeof(uint16_t) * 8) - 1);
         heap->heaps[0].available->blockmap[16] = 1 << ((sizeof(uint16_t) * 8) - 1);
-        CHECK(NULL != heap_allocate(heap, 1));
+        CHECK(NULL != heap_allocate(heap, 0, 1));
         CHECK(heap->heaps[0].available == NULL);
         CHECK(heap->heaps[0].full != NULL);
         CHECK(heap->heaps[0].full->next == NULL);
@@ -36,14 +37,14 @@ TEST_SUITE(Heap) {
 
     TEST(Verify_Allocate_should_allocate_the_minimum_size_if_num_slots_is_less_than_the_minimum) {
         heap_t* heap = heap_create();
-        CHECK(NULL != heap_allocate(heap, 0));
+        CHECK(NULL != heap_allocate(heap, 0, 0));
         CHECK(heap->heaps[0].available != NULL);
         heap_destroy(heap);
     }
 
     TEST(Verify_Allocate_should_allocate_a_large_block_if_the_number_of_slots_is_greater_than_the_max) {
         heap_t* heap = heap_create();
-        CHECK(NULL != heap_allocate(heap, 65));
+        CHECK(NULL != heap_allocate(heap, 0, 65));
         CHECK(NULL != heap->blocks->root->value);
         heap_destroy(heap);
     }
@@ -73,10 +74,10 @@ TEST_SUITE(Heap) {
     TEST(Verify_finish_collection_moves_segments_from_the_full_list_to_the_available_list_when_some_blocks_are_reclaimed) {
         heap_t* heap = heap_create();
         segment_t* seg = segment_create(2, NULL);
-        seg->blockmap[0] = 42;
         splaytree_t* blocks = heap->blocks;
         heap->heaps[1].full = seg;
         heap_start_collection(heap);
+        seg->blockmap[0] = 42;
         heap_finish_collection(heap);
         CHECK(blocks != heap->blocks);
         CHECK(heap->heaps[1].available == seg);
@@ -88,11 +89,11 @@ TEST_SUITE(Heap) {
         heap_t* heap = heap_create();
         segment_t* seg2 = segment_create(2, NULL);
         segment_t* seg1 = segment_create(2, seg2);
-        seg1->blockmap[0] = 0;
-        seg2->blockmap[0] = 42;
         splaytree_t* blocks = heap->blocks;
         heap->heaps[1].full = seg1;
         heap_start_collection(heap);
+        seg1->blockmap[0] = 0;
+        seg2->blockmap[0] = 42;
         heap_finish_collection(heap);
         CHECK(blocks != heap->blocks);
         CHECK(heap->heaps[1].available == seg2);
@@ -117,10 +118,10 @@ TEST_SUITE(Heap) {
         heap_t* heap = heap_create();
         segment_t* seg2 = segment_create(2, NULL);
         segment_t* seg1 = segment_create(2, seg2);
-        seg1->blockmap[0] = 0;
         splaytree_t* blocks = heap->blocks;
         heap->heaps[1].full = seg1;
         heap_start_collection(heap);
+        seg1->blockmap[0] = 0;
         heap_finish_collection(heap);
         CHECK(blocks != heap->blocks);
         CHECK(heap->heaps[1].available == NULL);
@@ -131,14 +132,52 @@ TEST_SUITE(Heap) {
     TEST(Verify_finish_collection_does_nothing_when_full_list_contains_only_full_segments) {
         heap_t* heap = heap_create();
         segment_t* seg = segment_create(2, NULL);
-        seg->blockmap[0] = 0;
         splaytree_t* blocks = heap->blocks;
         heap->heaps[1].full = seg;
         heap_start_collection(heap);
+        seg->blockmap[0] = 0;
         heap_finish_collection(heap);
         CHECK(blocks != heap->blocks);
         CHECK(heap->heaps[1].available == NULL);
         CHECK(heap->heaps[1].full == seg);
         heap_destroy(heap);
     }
+
+    /* Verify: heap_find_and_mark
+     *************************************************************************/
+    TEST(Verify_find_and_mark_should_find_and_return_the_indicated_small_block) {
+        heap_t* heap = heap_create();
+        void* addr = heap_allocate(heap, 0, 2);
+        heap_start_collection(heap);
+        CHECK(addr == heap_find_and_mark(heap, (uintptr_t)addr));
+        heap_finish_collection(heap);
+        heap_destroy(heap);
+    }
+
+    TEST(Verify_find_and_mark_should_fail_to_find_the_indicated_small_block) {
+        heap_t* heap = heap_create();
+        (void)heap_allocate(heap, 0, 2);
+        heap_start_collection(heap);
+        CHECK(NULL == heap_find_and_mark(heap, (uintptr_t)NULL));
+        heap_finish_collection(heap);
+        heap_destroy(heap);
+    }
+
+    TEST(Verify_find_and_mark_should_find_and_return_the_indicated_large_block) {
+        heap_t* heap = heap_create();
+        void* addr = heap_allocate(heap, 0, 65);
+        heap_start_collection(heap);
+        CHECK(addr == heap_find_and_mark(heap, (uintptr_t)addr));
+        heap_finish_collection(heap);
+        heap_destroy(heap);
+    }
+
+    TEST(Verify_find_and_mark_should_fail_to_find_the_indicated_large_block) {
+        heap_t* heap = heap_create();
+        (void)heap_allocate(heap, 0, 65);
+        heap_start_collection(heap);
+        CHECK(NULL == heap_find_and_mark(heap, (uintptr_t)NULL));
+        heap_finish_collection(heap);
+        heap_destroy(heap);
+    }
 }