From 14be401b24f76e331e7297d2ef9e93457817593a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Fri, 9 Feb 2024 09:59:30 +0100 Subject: [PATCH] Add internal allocator functionality to prepare for refactoring in vibe-core. See vibe-d/vibe-core#383 and vibe-d/vibe.d#2777. --- .../vibe/container/internal/utilallocator.d | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/source/vibe/container/internal/utilallocator.d b/source/vibe/container/internal/utilallocator.d index c4881a1..b8a08ee 100644 --- a/source/vibe/container/internal/utilallocator.d +++ b/source/vibe/container/internal/utilallocator.d @@ -15,6 +15,52 @@ public import stdx.allocator.building_blocks.affix_allocator; return s_threadAllocator; } +auto makeGCSafe(T, Allocator, A...)(Allocator allocator, A args) +{ + import core.memory : GC; + import std.traits : hasIndirections; + + auto ret = allocator.make!T(args); + static if (is (T == class)) enum tsize = __traits(classInstanceSize, T); + else enum tsize = T.sizeof; + static if (hasIndirections!T) + () @trusted { GC.addRange(cast(void*)ret, tsize, typeid(T)); } (); + return ret; +} + +void disposeGCSafe(T, Allocator)(Allocator allocator, T obj) +{ + import core.memory : GC; + import std.traits : hasIndirections; + + static if (hasIndirections!T) + GC.removeRange(cast(void*)obj); + allocator.dispose(obj); +} + +void ensureNotInGC(T)(string info = null) nothrow +{ + import core.exception : InvalidMemoryOperationError; + try + { + import core.memory : GC; + cast(void) GC.malloc(1); + return; + } + catch(InvalidMemoryOperationError e) + { + import core.stdc.stdio : fprintf, stderr; + import core.stdc.stdlib : exit; + fprintf(stderr, + "Error: clean-up of %s incorrectly depends on destructors called by the GC.\n", + T.stringof.ptr); + if (info) + fprintf(stderr, "Info: %s\n", info.ptr); + assert(false); + } +} + + final class RegionListAllocator(Allocator, bool leak = false) : IAllocator { import vibe.internal.memory_legacy : AllocSize, alignedSize; import std.algorithm.comparison : min, max; @@ -113,9 +159,9 @@ final class RegionListAllocator(Allocator, bool leak = false) : IAllocator { override Ternary resolveInternalPointer(void* p, ref void[] result) { return Ternary.unknown; } } static if (is(Parameters!(IAllocator.owns)[0] == const(void[]))) { - override Ternary owns(const void[] b) { return Ternary.unknown; } + override Ternary owns(const void[] b) { return Ternary.unknown; } } else { - override Ternary owns(void[] b) { return Ternary.unknown; } + override Ternary owns(void[] b) { return Ternary.unknown; } }