Skip to content

Commit

Permalink
Add allocation tracing mode
Browse files Browse the repository at this point in the history
  • Loading branch information
LunaTheFoxgirl committed May 26, 2024
1 parent 693ada7 commit f1f2468
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,8 @@ This is a incomplete and unordered roadmap of features I want to add and have ad
\*: Implemented but untested.
\*\*: Partially implemented.

# Tracing leaks
You can build numem with the `--debug=trace` flag to trace destruction of types via stdout.

# Note
Some parts of the library will pretend GC'ed types are no-gc, as such you should be careful about mixing GCed code in.
1 change: 1 addition & 0 deletions source/numem/all.d
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ public import numem.mem.string;
public import numem.mem.vector;
public import numem.mem.map;
public import numem.mem.set;
public import numem.mem.exception;
public import numem.io;
4 changes: 1 addition & 3 deletions source/numem/mem/exception.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module numem.mem.exception;
import numem.mem.string;
import numem.mem;
import core.stdc.stdio;
import numem.mem.internal.trace;

@nogc:

Expand All @@ -19,9 +20,6 @@ private:
public:

~this() {
// Debug build printing
debug printf("Exception freed! (msg=%s)\n", _msg.toCString());

nogc_delete(_msg);

// Free next-in-chain
Expand Down
37 changes: 37 additions & 0 deletions source/numem/mem/internal/trace.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright © 2023, Inochi2D Project
Distributed under the 2-Clause BSD License, see LICENSE file.
Authors: Luna Nielsen
*/

/**
Debug tracing module
*/
module numem.mem.internal.trace;
import core.stdc.stdio;

pragma(inline, true)
void dbg_alloc(T)(T item) if (is(T == class)) {
debug(trace) printf("Allocated "~T.stringof~" @ %p\n", cast(void*)item);
}

pragma(inline, true)
void dbg_alloc(T)(T* item) if (is(T == struct)) {
debug(trace) printf("Allocated "~T.stringof~" @ %p\n", cast(void*)item);
}

pragma(inline, true)
void dbg_alloc(T)(T* item) if (!is(T == struct) && !is(T == class)) {
debug(trace) printf("Allocated "~T.stringof~" @ %p\n", cast(void*)item);
}

pragma(inline, true)
void dbg_dealloc(T)(ref T item) if (is(T == class)) {
debug(trace) printf("Freed "~T.stringof~" @ %p\n", cast(void*)item);
}

pragma(inline, true)
void dbg_dealloc(T)(ref T item) if (!is(T == class)) {
debug(trace) printf("Freed "~T.stringof~"\n");
}
17 changes: 16 additions & 1 deletion source/numem/mem/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module numem.mem;
import core.stdc.stdlib : free, exit, malloc;
import std.traits;
import numem.mem.utils;
import numem.mem.internal.trace;

version(Have_tinyd_rt) {
private __gshared
Expand Down Expand Up @@ -97,6 +98,7 @@ T nogc_construct(T, Args...)(Args args) if (is(T == struct) || is(T == class) ||
Immediately exits the application if out of memory.
*/
T* nogc_new(T, Args...)(Args args) if (is(T == struct)) {

version(Have_tinyd_rt) {
return (assumeNothrowNoGC(&__gc_new!(T, Args)))(args);
} else {
Expand All @@ -112,6 +114,9 @@ T* nogc_new(T, Args...)(Args args) if (is(T == struct)) {
nogc_emplace!T(obj, args);
}

// Tracing
debug(trace) dbg_alloc(obj);

return obj;
}
}
Expand All @@ -121,6 +126,7 @@ T* nogc_new(T, Args...)(Args args) if (is(T == struct)) {
Immediately exits the application if out of memory.
*/
T nogc_new(T, Args...)(Args args) if (is(T == class)) {

alias emplaceFunc = typeof(&emplace!T);

version(Have_tinyd_rt) {
Expand All @@ -140,8 +146,11 @@ T nogc_new(T, Args...)(Args args) if (is(T == class)) {

// Allocate class
T obj = nogc_emplace!T(rawMemory[destructorObjSize .. allocSize], args);
return obj;

// Tracing
debug(trace) dbg_alloc(obj);

return obj;
} else {
immutable size_t allocSize = __traits(classInstanceSize, T);
void* rawMemory = malloc(allocSize);
Expand All @@ -163,6 +172,9 @@ T* nogc_new(T)(T value = T.init) if (isBasicType!T) {
exit(-1);
}

// Tracing
debug(trace) dbg_alloc(rawMemory);

*rawMemory = value;
return rawMemory;
}
Expand All @@ -173,6 +185,9 @@ T* nogc_new(T)(T value = T.init) if (isBasicType!T) {
For structs this will call the struct's destructor if it has any.
*/
void nogc_delete(T)(ref T obj_) {

// Tracing
debug(trace) dbg_dealloc(obj_);

version(minimal_rt) {
static if (isPointer!T || is(T == class)) {
Expand Down

0 comments on commit f1f2468

Please sign in to comment.