Skip to content

Commit

Permalink
Add garbage collection example and improve free_store()
Browse files Browse the repository at this point in the history
Related to #18.
  • Loading branch information
ldilley committed Jul 17, 2020
1 parent 28fcfcc commit a1777e7
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 22 deletions.
5 changes: 4 additions & 1 deletion include/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ size_t get_object_size(Object* object);
size_t get_store_objects_size();

// Returns total size of object store in bytes
size_t get_store_total_size();
static inline size_t get_store_total_size() { return get_store_objects_size() + sizeof(ObjectStore) + sizeof(Object *) * get_store_capacity(); }

// Prints total size of objects in object store
void print_store_objects_size();
Expand Down Expand Up @@ -113,4 +113,7 @@ void free_object(Object** object);
// Clones object
Object* clone_object(Object* object);

// Collects garbage and returns number of objects collected
size_t collect_garbage();

#endif // MEMORY_H
32 changes: 25 additions & 7 deletions src/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ void realloc_store(size_t new_size)
// Frees object store
void free_store()
{
for(size_t slot = 0; slot < get_store_capacity(); slot++)
{
if(object_store.objects[slot] != NULL)
free_object(&object_store.objects[slot]);
}
free(object_store.objects);
if(debug_mode)
debug_print("Object store freed.");
Expand All @@ -97,7 +102,7 @@ size_t get_store_used_slots()
for(size_t slot = 0; slot < get_store_capacity(); slot++)
{
if(object_store.objects[slot] != NULL)
used_slots += 1;
used_slots += 1;
}
return used_slots;
}
Expand Down Expand Up @@ -126,12 +131,6 @@ size_t get_store_objects_size()
return total_size;
}

// Returns total size of object store in bytes
size_t get_store_total_size()
{
return get_store_objects_size() + sizeof(ObjectStore) + sizeof(Object *) * get_store_capacity();
}

// Prints total size of objects in object store
void print_store_objects_size()
{
Expand Down Expand Up @@ -300,3 +299,22 @@ Object* clone_object(Object* object)

return new_object;
}

// Collects garbage and returns number of objects collected
size_t collect_garbage()
{
size_t collect_count = 0;
if(debug_mode)
debug_print("Collecting garbage...");
for(size_t slot = 0; slot < get_store_capacity(); slot++)
{
if(object_store.objects[slot] != NULL && object_store.objects[slot]->marked)
{
free_object(&object_store.objects[slot]);
collect_count++;
}
}
if(debug_mode)
debug_print("%zu objects collected.", collect_count);
return collect_count;
}
42 changes: 28 additions & 14 deletions src/tests/objtest.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,33 @@

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h> // rand(), srand()
#include <time.h> // time()
#include "debug.h"
#include "memory.h"
#include "types.h"

// Proof of concept to demonstrate garbage collection
void mark_objects()
{
srand(time(0));
size_t mark_count = 0;
if(debug_mode)
{
debug_print("Marking objects...");
}
for(size_t slot = 0; slot < get_store_capacity(); slot++)
{
if(object_store.objects[slot] != NULL && rand() % 2) // each object has a 50% chance of being marked
{
object_store.objects[slot]->marked = true;
mark_count++;
}
}
if(debug_mode)
debug_print("%zu objects marked.", mark_count);
}

int main()
{
debug_mode = true;
Expand All @@ -46,44 +69,37 @@ int main()

for(size_t i = 0; i < 1024; i++)
{
printf("Object store free/size: %zu/%zu\n", get_store_free_slots(), get_store_capacity());
printf("Used slots: %zu/%zu\n\n", get_store_used_slots(), get_store_capacity());
printf("Data type at slot #%zu: %s\n", i, get_data_type(object_store.objects[i]));
printf("Object size: %zu bytes\n", get_object_size(object_store.objects[i]));
free_object(&object_store.objects[i]);
print_store_total_size();
printf("Object of data type %s at slot #%zu is %zu bytes.\n", get_data_type(object_store.objects[i]), i, get_object_size(object_store.objects[i]));
}
puts("");
mark_objects();
collect_garbage(); // free only marked objects
printf("Object store free/capacity: %zu/%zu\n", get_store_free_slots(), get_store_capacity());
printf("Used slots: %zu/%zu\n\n", get_store_used_slots(), get_store_capacity());

Object* object = new_object("null");
printf("Data type: %s\n", get_data_type(object));
print_object_value(object);
printf("%s\n\n", (char *)get_object_value(object));
free_object(&object);

object = new_object("true");
printf("Data type: %s\n", get_data_type(object));
print_object_value(object);
printf("%d\n\n", *(Bool *)get_object_value(object));
free_object(&object);

object = new_object("100");
printf("Data type: %s\n", get_data_type(object));
print_object_value(object);
printf("%" PRId32 "\n\n", *(Number *)get_object_value(object));
free_object(&object);

object = new_object("5721452096347253");
printf("Data type: %s\n", get_data_type(object));
print_object_value(object);
printf("%" PRId64 "\n\n", *(BigNum *)get_object_value(object));
free_object(&object);

object = new_object("77.715");
printf("Data type: %s\n", get_data_type(object));
print_object_value(object);
printf("%f\n\n", *(Decimal *)get_object_value(object));
free_object(&object);

object = new_object("Greetings, Concocter!");
printf("Data type: %s\nString value: %s\nString length: %zu\n", get_data_type(object), object->value.strobj.strval, object->value.strobj.length);
Expand All @@ -100,8 +116,6 @@ int main()

puts("\nCloned object:");
printf("Data type: %s\nString value: %s\nString length: %zu\n", get_data_type(object2), object2->value.strobj.strval, object2->value.strobj.length);
free_object(&object);
free_object(&object2);
free_store();

return 0;
Expand Down

0 comments on commit a1777e7

Please sign in to comment.