diff --git a/druntime/mak/COPY b/druntime/mak/COPY index 30a69609ee36..29846cbffe5a 100644 --- a/druntime/mak/COPY +++ b/druntime/mak/COPY @@ -33,6 +33,9 @@ COPY=\ $(IMPDIR)\core\internal\atomic.d \ $(IMPDIR)\core\internal\attributes.d \ $(IMPDIR)\core\internal\cast_.d \ + $(IMPDIR)\core\internal\config\memory.d \ + $(IMPDIR)\core\internal\config\opt.d \ + $(IMPDIR)\core\internal\config\package.d \ $(IMPDIR)\core\internal\convert.d \ $(IMPDIR)\core\internal\dassert.d \ $(IMPDIR)\core\internal\destruction.d \ diff --git a/druntime/mak/SRCS b/druntime/mak/SRCS index 1f2afa2515be..6b6604058150 100644 --- a/druntime/mak/SRCS +++ b/druntime/mak/SRCS @@ -30,6 +30,9 @@ SRCS=\ src\core\internal\atomic.d \ src\core\internal\attributes.d \ src\core\internal\cast_.d \ + src\core\internal\config\memory.d \ + src\core\internal\config\opt.d \ + src\core\internal\config\package.d \ src\core\internal\convert.d \ src\core\internal\dassert.d \ src\core\internal\destruction.d \ diff --git a/druntime/src/core/gc/config.d b/druntime/src/core/gc/config.d index c3b79e0926b5..b0b9e54c8090 100644 --- a/druntime/src/core/gc/config.d +++ b/druntime/src/core/gc/config.d @@ -9,12 +9,24 @@ module core.gc.config; import core.internal.parseoptions; import core.stdc.stdio : printf; +import core.internal.config : Sys; +import core.internal.config.opt : Opt; + +alias Config = Opt.GcConfig; __gshared Config config; private __gshared bool _initialized; -struct Config +package(core) bool initialize(ref Config cfg) nothrow @nogc +{ + if (!_initialized) + _initialized = cfg.tryToInitialize(); + + return _initialized; +} + +struct ConfigT() { bool disable; // start disabled bool fork = false; // optional concurrent behaviour @@ -37,32 +49,30 @@ struct Config @nogc nothrow: - bool initialize() + private bool tryToInitialize() { - if (!_initialized) - _initialized = initConfigOptions(this, "gcopt"); - return _initialized; + return initConfigOptions(this, "gcopt"); } void help() @nogc nothrow { import core.gc.registry : registeredGCFactories; - printf("GC options are specified as white space separated assignments: + Sys.printf("GC options are specified as white space separated assignments: disable:0|1 - start disabled (%d) fork:0|1 - set fork behaviour (%d) profile:0|1|2 - enable profiling with summary when terminating program (%d) - gc:".ptr, disable, fork, profile); + gc:", disable, fork, profile); foreach (i, entry; registeredGCFactories) { - if (i) printf("|"); - printf("%.*s", cast(int) entry.name.length, entry.name.ptr); + if (i) Sys.print("|"); + Sys.printf("%.*s", cast(int) entry.name.length, entry.name.ptr); } auto _initReserve = initReserve.bytes2prettyStruct; auto _minPoolSize = minPoolSize.bytes2prettyStruct; auto _maxPoolSize = maxPoolSize.bytes2prettyStruct; auto _incPoolSize = incPoolSize.bytes2prettyStruct; - printf(" - select gc implementation (default = conservative) + Sys.printf(" - select gc implementation (default = conservative) initReserve:N - initial memory to reserve in MB (%lld%c) minPoolSize:N - initial and minimum pool size in MB (%lld%c) @@ -73,7 +83,7 @@ struct Config cleanup:none|collect|finalize - how to treat live objects when terminating (collect) Memory-related values can use B, K, M or G suffixes. -".ptr, +", _initReserve.v, _initReserve.u, _minPoolSize.v, _minPoolSize.u, _maxPoolSize.v, _maxPoolSize.u, diff --git a/druntime/src/core/gc/registry.d b/druntime/src/core/gc/registry.d index 2e6edf09c3e7..64c7f89869ea 100644 --- a/druntime/src/core/gc/registry.d +++ b/druntime/src/core/gc/registry.d @@ -60,9 +60,9 @@ alias GCThreadInitFunction = void function(ThreadBase base) nothrow @nogc; void registerGCFactory(string name, GCFactory factory, GCThreadInitFunction threadInit = null) nothrow @nogc { - import core.stdc.stdlib : realloc; + import core.internal.config.memory : reallocate; - auto ptr = cast(Entry*)realloc(entries.ptr, (entries.length + 1) * Entry.sizeof); + auto ptr = cast(Entry*) reallocate(entries.ptr, (entries.length + 1) * Entry.sizeof); entries = ptr[0 .. entries.length + 1]; entries[$ - 1] = Entry(name, factory, threadInit); } @@ -77,7 +77,7 @@ void registerGCFactory(string name, GCFactory factory, */ GC createGCInstance(string name) { - import core.stdc.stdlib : free; + import core.internal.config.memory : freeMem; foreach (entry; entries) { @@ -85,7 +85,7 @@ GC createGCInstance(string name) continue; auto instance = entry.factory(); // only one GC at a time for now, so free the registry to not leak - free(entries.ptr); + freeMem(entries.ptr); entries = null; return instance; } diff --git a/druntime/src/core/internal/array/utils.d b/druntime/src/core/internal/array/utils.d index 103a87bcd278..1020f3984373 100644 --- a/druntime/src/core/internal/array/utils.d +++ b/druntime/src/core/internal/array/utils.d @@ -11,6 +11,7 @@ module core.internal.array.utils; import core.internal.traits : Parameters; import core.memory : GC; +debug(PRINTF) import core.stdc.stdio : printf; alias BlkAttr = GC.BlkAttr; diff --git a/druntime/src/core/internal/config/memory.d b/druntime/src/core/internal/config/memory.d new file mode 100644 index 000000000000..0c3d107cbf1a --- /dev/null +++ b/druntime/src/core/internal/config/memory.d @@ -0,0 +1,17 @@ +/// +module core.internal.config.memory; + +// libc version +version (all) +{ + import core.stdc.stdlib; + + alias allocateOne = malloc; + alias allocateFew = (size_t num, size_t size) nothrow @nogc => allocateOne(num * size); + void* allocateOneBlank(size_t size) nothrow @nogc => allocateFewBlank(1, size); + alias allocateFewBlank = calloc; + alias reallocate = realloc; + alias freeMem = core.stdc.stdlib.free; + + alias allocateOnStack = alloca; +} diff --git a/druntime/src/core/internal/config/opt.d b/druntime/src/core/internal/config/opt.d new file mode 100644 index 000000000000..16f6db1041b2 --- /dev/null +++ b/druntime/src/core/internal/config/opt.d @@ -0,0 +1,9 @@ +/// +module core.internal.config.opt; + +struct Opt +{ + import core.gc.config: ConfigT; + + alias GcConfig = ConfigT!(); +} diff --git a/druntime/src/core/internal/config/package.d b/druntime/src/core/internal/config/package.d new file mode 100644 index 000000000000..0b004bd907f0 --- /dev/null +++ b/druntime/src/core/internal/config/package.d @@ -0,0 +1,32 @@ +/// +module core.internal.config; + +struct Sys +{ + static import core.stdc.stdlib; + import core.stdc.stdio; + + alias abort = core.stdc.stdlib.abort; + + static void print(scope const char[] str) nothrow @nogc + { + // This is a silly approach, but it's a simple way to print non-null-terminated strings + // TODO: implement using write() or so + foreach(c; str) + { + auto r = fputc(c, stdout); + if(r == EOF) + Sys.abort(); + } + } + + /// C-formatted print + static void printf(T...)(scope const char[] fmt, T vals) nothrow @nogc + { + static assert(T.length > 0); + + int r = core.stdc.stdio.printf(fmt.ptr, vals); + if(r < fmt.length) + Sys.abort(); + } +} diff --git a/druntime/src/core/internal/gc/bits.d b/druntime/src/core/internal/gc/bits.d index 8aabf9e393d7..82f1c1660ff4 100644 --- a/druntime/src/core/internal/gc/bits.d +++ b/druntime/src/core/internal/gc/bits.d @@ -11,7 +11,7 @@ import core.internal.gc.os; import core.bitop; import core.exception : onOutOfMemoryError; -import core.stdc.stdlib : calloc, free; +import core.internal.config.memory : allocateOneBlank, freeMem; import core.stdc.string : memcpy, memset; // use version gcbitsSingleBitOperation to disable optimizations that use @@ -38,7 +38,7 @@ struct GCBits if (data) { if (!AllocSupportsShared || !share) - free(data); + freeMem(data); else static if (AllocSupportsShared) os_mem_unmap_shared(data, nwords * data[0].sizeof); else @@ -51,7 +51,7 @@ struct GCBits { this.nbits = nbits; if (!AllocSupportsShared || !share) - data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof); + data = cast(typeof(data[0])*) allocateOneBlank(nwords * data[0].sizeof); else static if (AllocSupportsShared) data = cast(typeof(data[0])*)os_mem_map_shared(nwords * data[0].sizeof); // Allocate as MAP_SHARED else diff --git a/druntime/src/core/internal/gc/impl/manual/gc.d b/druntime/src/core/internal/gc/impl/manual/gc.d index 5f9c04187ed9..0a8ba42bf4a6 100644 --- a/druntime/src/core/internal/gc/impl/manual/gc.d +++ b/druntime/src/core/internal/gc/impl/manual/gc.d @@ -25,7 +25,7 @@ import core.internal.container.array; import core.thread.threadbase : ThreadBase; -import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc; +import core.internal.config.memory; static import core.memory; extern (C) noreturn onOutOfMemoryError(void* pretend_sideffect = null, string file = __FILE__, size_t line = __LINE__) @trusted pure nothrow @nogc; /* dmd @@@BUG11461@@@ */ @@ -46,7 +46,7 @@ private GC initialize() { import core.lifetime : emplace; - auto gc = cast(ManualGC) cstdlib.malloc(__traits(classInstanceSize, ManualGC)); + auto gc = cast(ManualGC) allocateOne(__traits(classInstanceSize, ManualGC)); if (!gc) onOutOfMemoryError(); @@ -102,7 +102,7 @@ class ManualGC : GC void* malloc(size_t size, uint bits, const TypeInfo ti) nothrow { - void* p = cstdlib.malloc(size); + void* p = allocateOne(size); if (size && p is null) onOutOfMemoryError(); @@ -120,7 +120,7 @@ class ManualGC : GC void* calloc(size_t size, uint bits, const TypeInfo ti) nothrow { - void* p = cstdlib.calloc(1, size); + void* p = allocateOneBlank(size); if (size && p is null) onOutOfMemoryError(); @@ -129,7 +129,7 @@ class ManualGC : GC void* realloc(void* p, size_t size, uint bits, const TypeInfo ti) nothrow { - p = cstdlib.realloc(p, size); + p = reallocate(p, size); if (size && p is null) onOutOfMemoryError(); @@ -148,7 +148,7 @@ class ManualGC : GC void free(void* p) nothrow @nogc { - cstdlib.free(p); + freeMem(p); } /** diff --git a/druntime/src/core/runtime.d b/druntime/src/core/runtime.d index 8cdb999c92fd..5ff94fd7fd38 100644 --- a/druntime/src/core/runtime.d +++ b/druntime/src/core/runtime.d @@ -10,6 +10,8 @@ module core.runtime; +import core.internal.config.memory : allocateOne, freeMem; + version (OSX) version = Darwin; else version (iOS) @@ -209,7 +211,6 @@ struct Runtime */ static void* loadLibrary()(const scope char[] name) { - import core.stdc.stdlib : free, malloc; version (Windows) { import core.sys.windows.winnls : CP_UTF8, MultiByteToWideChar; @@ -222,9 +223,9 @@ struct Runtime if (len == 0) return null; - auto buf = cast(WCHAR*)malloc((len+1) * WCHAR.sizeof); + auto buf = cast(WCHAR*) allocateOne((len+1) * WCHAR.sizeof); if (buf is null) return null; - scope (exit) free(buf); + scope (exit) freeMem(buf); len = MultiByteToWideChar( CP_UTF8, 0, name.ptr, cast(int)name.length, buf, len); @@ -240,9 +241,9 @@ struct Runtime /* Need a 0-terminated C string for the dll name */ immutable len = name.length; - auto buf = cast(char*)malloc(len + 1); + auto buf = cast(char*) allocateOne(len + 1); if (!buf) return null; - scope (exit) free(buf); + scope (exit) freeMem(buf); buf[0 .. len] = name[]; buf[len] = 0; @@ -743,8 +744,7 @@ Throwable.TraceInfo defaultTraceHandler( void* ptr = null ) // @nogc static T allocate(T, Args...)(auto ref Args args) @nogc { import core.lifetime : emplace; - import core.stdc.stdlib : malloc; - auto result = cast(T)malloc(__traits(classInstanceSize, T)); + auto result = cast(T) allocateOne(__traits(classInstanceSize, T)); return emplace(result, args); } version (Windows) @@ -803,8 +803,7 @@ void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow return; auto obj = cast(Object)info; destroy(obj); - import core.stdc.stdlib : free; - free(cast(void *)obj); + freeMem(cast(void *)obj); } /// Default implementation for most POSIX systems @@ -812,7 +811,6 @@ version (WASI) {} else version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo { import core.demangle; - import core.stdc.stdlib : free; import core.stdc.string : strlen, memchr, memmove; this() @nogc @@ -879,7 +877,7 @@ else version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo static if (hasExecinfo) { const framelist = backtrace_symbols( callstack.ptr, numframes ); - scope(exit) free(cast(void*) framelist); + scope(exit) freeMem(cast(void*) framelist); static if (enableDwarf) { diff --git a/druntime/src/rt/dmain2.d b/druntime/src/rt/dmain2.d index 2a4d9beb80af..d895b51598a4 100644 --- a/druntime/src/rt/dmain2.d +++ b/druntime/src/rt/dmain2.d @@ -15,11 +15,12 @@ import core.atomic; import core.internal.parseoptions : rt_parseOption; import core.stdc.errno : errno; import core.stdc.stdio : fflush, fprintf, fwrite, stderr, stdout; -import core.stdc.stdlib : alloca, EXIT_FAILURE, EXIT_SUCCESS, free, malloc, realloc; +import core.stdc.stdlib : EXIT_FAILURE, EXIT_SUCCESS; import core.stdc.string : strerror; import rt.config : rt_cmdline_enabled, rt_configOption; import rt.memory; import rt.sections; +import core.internal.config.memory; version (Windows) { @@ -49,7 +50,7 @@ else version (WASI) } version (DigitalMars) version (AArch64) - version = UseMalloc; // cuz alloca() is not implemented yet + version = UseMalloc; // cuz allocateOnStack is not implemented yet // not sure why we can't define this in one place, but this is to keep this // module from importing core.runtime. @@ -288,13 +289,13 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc) // Allocate args[] on the stack - use wargc version (UseMalloc) { - char[][] args = (cast(char[]*) malloc(wargc * (char[]).sizeof))[0 .. wargc]; + char[][] args = (cast(char[]*) allocateOne(wargc * (char[]).sizeof))[0 .. wargc]; if (wargc) assert(args.ptr); scope (exit) free(args.ptr); } else - char[][] args = (cast(char[]*) alloca(wargc * (char[]).sizeof))[0 .. wargc]; + char[][] args = (cast(char[]*) allocateOnStack(wargc * (char[]).sizeof))[0 .. wargc]; // This is required because WideCharToMultiByte requires int as input. assert(wCommandLineLength <= cast(size_t) int.max, "Wide char command line length must not exceed int.max"); @@ -303,13 +304,13 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc) { version (UseMalloc) { - char* totalArgsBuff = cast(char*) malloc(totalArgsLength); + char* totalArgsBuff = cast(char*) allocateOne(totalArgsLength); if (totalArgsLength) assert(totalArgsBuff); scope (exit) free(totalArgsBuff); } else - char* totalArgsBuff = cast(char*) alloca(totalArgsLength); + char* totalArgsBuff = cast(char*) allocateOnStack(totalArgsLength); size_t j = 0; foreach (i; 0 .. wargc) { @@ -333,13 +334,13 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc) // Allocate args[] on the stack version (UseMalloc) { - char[][] args = (cast(char[]*) malloc(argc * (char[]).sizeof))[0 .. argc]; + char[][] args = (cast(char[]*) allocateOne(argc * (char[]).sizeof))[0 .. argc]; if (argc) assert(args.ptr); scope (exit) free(args.ptr); } else - char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc]; + char[][] args = (cast(char[]*) allocateOnStack(argc * (char[]).sizeof))[0 .. argc]; size_t totalArgsLength = 0; foreach (i, ref arg; args) @@ -351,7 +352,7 @@ extern (C) int _d_run_main(int argc, char** argv, MainFunc mainFunc) else version (WASI) { // Allocate args[] on the stack - char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc]; + char[][] args = (cast(char[]*) allocateOnStack(argc * (char[]).sizeof))[0 .. argc]; size_t totalArgsLength = 0; foreach (i, ref arg; args) @@ -376,7 +377,7 @@ version (Windows) extern (C) int _d_wrun_main(int argc, wchar** wargv, MainFunc mainFunc) { // Allocate args[] on the stack - char[][] args = (cast(char[]*) alloca(argc * (char[]).sizeof))[0 .. argc]; + char[][] args = (cast(char[]*) allocateOnStack(argc * (char[]).sizeof))[0 .. argc]; // 1st pass: compute each argument's length as UTF-16 and UTF-8 size_t totalArgsLength = 0; @@ -391,7 +392,7 @@ extern (C) int _d_wrun_main(int argc, wchar** wargv, MainFunc mainFunc) } // Allocate a single buffer for all (null-terminated) argument strings in UTF-8 on the stack - char* utf8Buffer = cast(char*) alloca(totalArgsLength); + char* utf8Buffer = cast(char*) allocateOnStack(totalArgsLength); // 2nd pass: convert to UTF-8 and finalize `args` char* utf8 = utf8Buffer; @@ -405,7 +406,7 @@ extern (C) int _d_wrun_main(int argc, wchar** wargv, MainFunc mainFunc) } // Set C argc/argv; argv is a new stack-allocated array of UTF-8 C strings - char*[] argv = (cast(char**) alloca(argc * (char*).sizeof))[0 .. argc]; + char*[] argv = (cast(char**) allocateOnStack(argc * (char*).sizeof))[0 .. argc]; foreach (i, ref arg; argv) arg = args[i].ptr; _cArgs.argc = argc; @@ -481,13 +482,13 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF auto length = args.length * (char[]).sizeof + totalArgsLength; version (UseMalloc) { - auto buff = cast(char[]*) malloc(length); + auto buff = cast(char[]*) allocateOne(length); if (length) assert(buff); //scope (exit) buff; } else - auto buff = cast(char[]*) alloca(length); + auto buff = cast(char[]*) allocateOnStack(length); char[][] argsCopy = buff[0 .. args.length]; auto argBuff = cast(char*) (buff + args.length); @@ -660,7 +661,7 @@ extern (C) void _d_print_throwable(Throwable t) CP_UTF8, 0, s.ptr, cast(int)s.length, null, 0); if (!swlen) return; - auto newPtr = cast(WCHAR*)realloc(ptr, + auto newPtr = cast(WCHAR*) reallocate(ptr, (this.len + swlen + 1) * WCHAR.sizeof); if (!newPtr) return; ptr = newPtr; @@ -671,7 +672,7 @@ extern (C) void _d_print_throwable(Throwable t) typeof(ptr) get() { if (ptr) ptr[len] = 0; return ptr; } - void free() { .free(ptr); } + void free() { freeMem(ptr); } } HANDLE windowsHandle(int fd) @@ -720,12 +721,12 @@ extern (C) void _d_print_throwable(Throwable t) uint codepage = GetConsoleOutputCP(); const slen = WideCharToMultiByte(codepage, 0, buf.ptr, cast(int)buf.len, null, 0, null, null); - if (auto sptr = cast(char*)malloc(slen * char.sizeof)) + if (auto sptr = cast(char*) allocateOne(slen * char.sizeof)) { WideCharToMultiByte(codepage, 0, buf.ptr, cast(int)buf.len, sptr, slen, null, null); WriteFile(hStdErr, sptr, slen, null, null); - free(sptr); + freeMem(sptr); } buf.free(); } diff --git a/druntime/src/rt/minfo.d b/druntime/src/rt/minfo.d index a70aabbeb648..b7f12e50936a 100644 --- a/druntime/src/rt/minfo.d +++ b/druntime/src/rt/minfo.d @@ -13,7 +13,7 @@ module rt.minfo; import core.stdc.stdio : fprintf, stderr; -import core.stdc.stdlib : free, malloc, realloc; +import core.internal.config.memory : freeMem, allocateOne, reallocate; import core.stdc.string : memcpy, memset; import rt.sections; @@ -66,11 +66,11 @@ struct ModuleGroup import core.bitop : bt, btc, bts; // set up all the arrays. - size_t[] cyclePath = (cast(size_t*)malloc(size_t.sizeof * _modules.length * 2))[0 .. _modules.length * 2]; + size_t[] cyclePath = (cast(size_t*) allocateOne(size_t.sizeof * _modules.length * 2))[0 .. _modules.length * 2]; size_t totalMods; - int[] distance = (cast(int*)malloc(int.sizeof * _modules.length))[0 .. _modules.length]; + int[] distance = (cast(int*) allocateOne(int.sizeof * _modules.length))[0 .. _modules.length]; scope(exit) - .free(distance.ptr); + freeMem(distance.ptr); // determine the shortest path between two modules. Uses dijkstra // without a priority queue. (we can be a bit slow here, in order to @@ -221,14 +221,14 @@ struct ModuleGroup // allocate some stack arrays that will be used throughout the process. immutable nwords = (len + 8 * size_t.sizeof - 1) / (8 * size_t.sizeof); immutable flagbytes = nwords * size_t.sizeof; - auto ctorstart = cast(size_t*) malloc(flagbytes); // ctor/dtor seen - auto ctordone = cast(size_t*) malloc(flagbytes); // ctor/dtor processed - auto relevant = cast(size_t*) malloc(flagbytes); // has ctors/dtors + auto ctorstart = cast(size_t*) allocateOne(flagbytes); // ctor/dtor seen + auto ctordone = cast(size_t*) allocateOne(flagbytes); // ctor/dtor processed + auto relevant = cast(size_t*) allocateOne(flagbytes); // has ctors/dtors scope (exit) { - .free(ctorstart); - .free(ctordone); - .free(relevant); + freeMem(ctorstart); + freeMem(ctordone); + freeMem(relevant); } void clearFlags(size_t* flags) @@ -239,15 +239,15 @@ struct ModuleGroup // build the edges between each module. We may need this for printing, // and also allows avoiding keeping a hash around for module lookups. - int[][] edges = (cast(int[]*)malloc((int[]).sizeof * _modules.length))[0 .. _modules.length]; + int[][] edges = (cast(int[]*) allocateOne((int[]).sizeof * _modules.length))[0 .. _modules.length]; { HashTab!(immutable(ModuleInfo)*, int) modIndexes; foreach (i, m; _modules) modIndexes[m] = cast(int) i; - auto reachable = cast(size_t*) malloc(flagbytes); + auto reachable = cast(size_t*) allocateOne(flagbytes); scope(exit) - .free(reachable); + freeMem(reachable); foreach (i, m; _modules) { @@ -255,7 +255,7 @@ struct ModuleGroup // https://issues.dlang.org/show_bug.cgi?id=16208 clearFlags(reachable); // preallocate enough space to store all the indexes - int *edge = cast(int*)malloc(int.sizeof * _modules.length); + int *edge = cast(int*) allocateOne(int.sizeof * _modules.length); size_t nEdges = 0; foreach (imp; m.importedModules) { @@ -270,12 +270,12 @@ struct ModuleGroup if (nEdges > 0) { // trim space to what is needed - edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges]; + edges[i] = (cast(int*) reallocate(edge, int.sizeof * nEdges))[0 .. nEdges]; } else { edges[i] = null; - .free(edge); + freeMem(edge); } } } @@ -285,8 +285,8 @@ struct ModuleGroup { foreach (e; edges) if (e.ptr) - .free(e.ptr); - .free(edges.ptr); + freeMem(e.ptr); + freeMem(edges.ptr); } void buildCycleMessage(size_t sourceIdx, size_t cycleIdx, scope void delegate(string) nothrow sink) @@ -302,7 +302,7 @@ struct ModuleGroup sink(_modules[cycleIdx].name); sink(EOL); auto cyclePath = genCyclePath(sourceIdx, cycleIdx, edges); - scope(exit) .free(cyclePath.ptr); + scope(exit) freeMem(cyclePath.ptr); sink(_modules[sourceIdx].name); sink("* ->" ~ EOL); @@ -330,9 +330,9 @@ struct ModuleGroup } // initialize "stack" - auto stack = cast(stackFrame*) malloc(stackFrame.sizeof * len); + auto stack = cast(stackFrame*) allocateOne(stackFrame.sizeof * len); scope (exit) - .free(stack); + freeMem(stack); auto stacktop = stack + len; auto sp = stack; sp.curMod = cast(int) idx; @@ -423,9 +423,9 @@ struct ModuleGroup immutable ModuleInfo* current = _modules[curidx]; // First, determine what modules are reachable. - auto reachable = cast(size_t*) malloc(flagbytes); + auto reachable = cast(size_t*) allocateOne(flagbytes); scope (exit) - .free(reachable); + freeMem(reachable); if (!findDeps(curidx, reachable)) return false; // deprecated cycle error @@ -468,7 +468,7 @@ struct ModuleGroup clearFlags(ctordone); // pre-allocate enough space to hold all modules. - ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof)); + ctors = cast(immutable(ModuleInfo)**) allocateOne(len * (void*).sizeof); ctoridx = 0; foreach (idx, m; _modules) { @@ -493,7 +493,7 @@ struct ModuleGroup { if (!processMod(idx)) { - .free(ctors); + freeMem(ctors); return false; } } @@ -502,11 +502,11 @@ struct ModuleGroup if (ctoridx == 0) { // no ctors in the list. - .free(ctors); + freeMem(ctors); } else { - ctors = cast(immutable(ModuleInfo)**).realloc(ctors, ctoridx * (void*).sizeof); + ctors = cast(immutable(ModuleInfo)**) reallocate(ctors, ctoridx * (void*).sizeof); if (ctors is null) assert(0); result = ctors[0 .. ctoridx]; @@ -561,10 +561,10 @@ struct ModuleGroup void free() { if (_ctors.ptr) - .free(_ctors.ptr); + freeMem(_ctors.ptr); _ctors = null; if (_tlsctors.ptr) - .free(_tlsctors.ptr); + freeMem(_tlsctors.ptr); _tlsctors = null; // _modules = null; // let the owner free it }