diff --git a/source/toy_ast_node.c b/source/toy_ast_node.c index ebe4ca4..24669b1 100644 --- a/source/toy_ast_node.c +++ b/source/toy_ast_node.c @@ -40,17 +40,21 @@ static void freeASTNodeCustom(Toy_ASTNode* node, bool freeSelf) { break; case TOY_AST_NODE_BLOCK: - for (int i = 0; i < node->block.count; i++) { - freeASTNodeCustom(node->block.nodes + i, false); + if (node->block.capacity > 0) { + for (int i = 0; i < node->block.count; i++) { + freeASTNodeCustom(node->block.nodes + i, false); + } + TOY_FREE_ARRAY(Toy_ASTNode, node->block.nodes, node->block.capacity); } - TOY_FREE_ARRAY(Toy_ASTNode, node->block.nodes, node->block.capacity); break; case TOY_AST_NODE_COMPOUND: - for (int i = 0; i < node->compound.count; i++) { - freeASTNodeCustom(node->compound.nodes + i, false); + if (node->compound.capacity > 0) { + for (int i = 0; i < node->compound.count; i++) { + freeASTNodeCustom(node->compound.nodes + i, false); + } + TOY_FREE_ARRAY(Toy_ASTNode, node->compound.nodes, node->compound.capacity); } - TOY_FREE_ARRAY(Toy_ASTNode, node->compound.nodes, node->compound.capacity); break; case TOY_AST_NODE_PAIR: @@ -71,10 +75,12 @@ static void freeASTNodeCustom(Toy_ASTNode* node, bool freeSelf) { break; case TOY_AST_NODE_FN_COLLECTION: - for (int i = 0; i < node->fnCollection.count; i++) { - freeASTNodeCustom(node->fnCollection.nodes + i, false); + if (node->fnCollection.capacity > 0) { + for (int i = 0; i < node->fnCollection.count; i++) { + freeASTNodeCustom(node->fnCollection.nodes + i, false); + } + TOY_FREE_ARRAY(Toy_ASTNode, node->fnCollection.nodes, node->fnCollection.capacity); } - TOY_FREE_ARRAY(Toy_ASTNode, node->fnCollection.nodes, node->fnCollection.capacity); break; case TOY_AST_NODE_FN_DECL: diff --git a/source/toy_common.h b/source/toy_common.h index 88b2f08..d4f73c2 100644 --- a/source/toy_common.h +++ b/source/toy_common.h @@ -6,7 +6,7 @@ #define TOY_VERSION_MAJOR 1 #define TOY_VERSION_MINOR 1 -#define TOY_VERSION_PATCH 0 +#define TOY_VERSION_PATCH 1 #define TOY_VERSION_BUILD __DATE__ " " __TIME__ //platform/compiler-specific instructions diff --git a/source/toy_literal.c b/source/toy_literal.c index 28a7d67..ba37f67 100644 --- a/source/toy_literal.c +++ b/source/toy_literal.c @@ -62,7 +62,7 @@ void Toy_freeLiteral(Toy_Literal literal) { TOY_FREE_ARRAY(unsigned char, TOY_AS_FUNCTION(literal).inner.bytecode, TOY_AS_FUNCTION_BYTECODE_LENGTH(literal)); } - if (TOY_IS_TYPE(literal)) { + if (TOY_IS_TYPE(literal) && TOY_AS_TYPE(literal).capacity > 0) { for (int i = 0; i < TOY_AS_TYPE(literal).count; i++) { Toy_freeLiteral(((Toy_Literal*)(TOY_AS_TYPE(literal).subtypes))[i]); } diff --git a/source/toy_literal_array.c b/source/toy_literal_array.c index 10c4b50..6de2d38 100644 --- a/source/toy_literal_array.c +++ b/source/toy_literal_array.c @@ -18,8 +18,10 @@ void Toy_freeLiteralArray(Toy_LiteralArray* array) { Toy_freeLiteral(array->literals[i]); } - TOY_FREE_ARRAY(Toy_Literal, array->literals, array->capacity); - Toy_initLiteralArray(array); + if (array->capacity > 0) { + TOY_FREE_ARRAY(Toy_Literal, array->literals, array->capacity); + Toy_initLiteralArray(array); + } } int Toy_pushLiteralArray(Toy_LiteralArray* array, Toy_Literal literal) { diff --git a/source/toy_literal_dictionary.c b/source/toy_literal_dictionary.c index 0d89545..355aeca 100644 --- a/source/toy_literal_dictionary.c +++ b/source/toy_literal_dictionary.c @@ -73,7 +73,9 @@ static void adjustEntryCapacity(Toy_private_dictionary_entry** dictionaryHandle, } //clear the old array - TOY_FREE_ARRAY(Toy_private_dictionary_entry, *dictionaryHandle, oldCapacity); + if (oldCapacity > 0) { + TOY_FREE_ARRAY(Toy_private_dictionary_entry, *dictionaryHandle, oldCapacity); + } *dictionaryHandle = newEntries; } @@ -133,9 +135,11 @@ void Toy_initLiteralDictionary(Toy_LiteralDictionary* dictionary) { } void Toy_freeLiteralDictionary(Toy_LiteralDictionary* dictionary) { - freeEntryArray(dictionary->entries, dictionary->capacity); - dictionary->capacity = 0; - dictionary->contains = 0; + if (dictionary->capacity > 0) { + freeEntryArray(dictionary->entries, dictionary->capacity); + dictionary->capacity = 0; + dictionary->contains = 0; + } } void Toy_setLiteralDictionary(Toy_LiteralDictionary* dictionary, Toy_Literal key, Toy_Literal value) { diff --git a/source/toy_memory.c b/source/toy_memory.c index a8920e7..80d6172 100644 --- a/source/toy_memory.c +++ b/source/toy_memory.c @@ -8,10 +8,10 @@ //default allocator void* Toy_private_defaultMemoryAllocator(void* pointer, size_t oldSize, size_t newSize) { - if (newSize == 0 && oldSize == 0) { - //causes issues, so just skip out with a NO-OP - return NULL; - } + //causes issues, so just skip out with a NO-OP (DISABLED for performance reasons) + // if (newSize == 0 && oldSize == 0) { + // return NULL; + // } if (newSize == 0) { free(pointer); diff --git a/tools/memusage/main.c b/tools/memusage/main.c index 082d495..52edcd1 100644 --- a/tools/memusage/main.c +++ b/tools/memusage/main.c @@ -10,25 +10,32 @@ int currentMemoryUsed = 0; int maxMemoryUsed = 0; int memoryAllocCalls = 0; +int memoryAllocFree = 0; +int memoryAllocRealloc = 0; static void* trackerAllocator(void* pointer, size_t oldSize, size_t newSize) { + //the number of raw calls + memoryAllocCalls++; + + //causes issues, so just skip out with a NO-OP if (newSize == 0 && oldSize == 0) { - //causes issues, so just skip out with a NO-OP return NULL; } - memoryAllocCalls++; - //track the changes currentMemoryUsed = currentMemoryUsed - oldSize + newSize; maxMemoryUsed = currentMemoryUsed > maxMemoryUsed ? currentMemoryUsed : maxMemoryUsed; if (newSize == 0) { + //the number of frees + memoryAllocFree++; free(pointer); return NULL; } + //the number of reallocations + memoryAllocRealloc++; void* mem = realloc(pointer, newSize); if (mem == NULL) { @@ -69,7 +76,7 @@ int main(int argc, const char* argv[]) { Toy_freeDriveDictionary(); //report output - printf("Memory report: %d max bytes, %d calls\n", maxMemoryUsed, memoryAllocCalls); + printf("Heap Memory Report:\n\t%d max bytes\n\t%d calls to the allocator\n\t%d calls to realloc()\n\t%d calls to free()\n\t%d discrepancies\n", maxMemoryUsed, memoryAllocCalls, memoryAllocRealloc, memoryAllocFree, memoryAllocCalls - memoryAllocRealloc - memoryAllocFree); return 0; }