Skip to content
Draft
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
327e916
core.system.Mem.reallocate alias added and used in registerGCFactory()
denizzzka Jul 31, 2026
2cb303c
core.system.Mem: allocate and free aliases added and used in Runtime.…
denizzzka Jul 31, 2026
90237dc
Mem.allocateBlank() added
denizzzka Jul 31, 2026
c8e5b4e
calloc() and free() replaced by Mem in core.internal.gc.os module
denizzzka Jul 31, 2026
f17cea9
Mem.allocateBlank() on Posix uses calloc()
denizzzka Jul 31, 2026
6c69083
module rt.minfo now uses core.system.Mem
denizzzka Jul 31, 2026
afb47cc
core.internal.gc.impl.manual.gc uses core.system.Mem
denizzzka Jul 31, 2026
80eff15
module core.runtime uses core.system.Mem
denizzzka Jul 31, 2026
95a13a7
core.gc.registry uses core.system.Mem
denizzzka Jul 31, 2026
f121ab9
rt.dmain2: core.stdc.stdlib.alloca() replaced by Mem.allocateOnStack
denizzzka Jul 31, 2026
6f8d22b
rt.dmain2: free, malloc, realloc replaced by Mem.* calls
denizzzka Jul 31, 2026
c2658a3
Merge branch 'master' into libc_gone
denizzzka Aug 1, 2026
8ae2a8f
allocateBlank() commented-out code removed
denizzzka Aug 1, 2026
01dc104
Mem.allocate -> Mem.allocateOne
denizzzka Aug 1, 2026
417361a
allocateBlank() -> allocateOneBlank()
denizzzka Aug 1, 2026
85de307
allocateFew() and allocateFewBlank() added
denizzzka Aug 1, 2026
76191c4
GC Config: initialization method does not need access to the outer scope
denizzzka Aug 1, 2026
a34c6de
Merge branch 'gc_cfg_init_changed' into libc_gone
denizzzka Aug 1, 2026
f20ede3
GC Config defined in core.system.Opt
denizzzka Aug 1, 2026
7075d9f
Opt.Config -> Opt.GcConfig
denizzzka Aug 1, 2026
21fb5a1
Attempt to fix build fo Windows by adding module core.system.opt
denizzzka Aug 1, 2026
4b9b386
druntime: -debug=PRINTF compilation fix
denizzzka Aug 2, 2026
b426feb
core.system: Sys.abort() and printf() added
denizzzka Aug 2, 2026
43eb8f8
core.system comment about debugging added, aliases added
denizzzka Aug 2, 2026
ec6e2ec
more correct printf result value check
denizzzka Aug 2, 2026
e79d4d2
Sys.print() added
denizzzka Aug 2, 2026
f82da6f
core.system.Sys.printf() implemented (depends on libc version) and used
denizzzka Aug 2, 2026
b8d39b9
Sys.print() can print non-null-terminated strings
denizzzka Aug 2, 2026
c188f6c
free() -> freeMem()
denizzzka Aug 3, 2026
3755f54
core.system.Mem code moved to new core.system.memory module
denizzzka Aug 3, 2026
8298709
Merge branch 'master' into libc_gone
denizzzka Aug 3, 2026
5de3953
modules renamed: core.system.* -> core.internal.config.*
denizzzka Aug 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions druntime/mak/COPY
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ COPY=\
$(IMPDIR)\core\memory.d \
$(IMPDIR)\core\runtime.d \
$(IMPDIR)\core\simd.d \
$(IMPDIR)\core\system\opt.d \
$(IMPDIR)\core\system\package.d \
$(IMPDIR)\core\time.d \
$(IMPDIR)\core\vararg.d \
$(IMPDIR)\core\volatile.d \
Expand Down
2 changes: 2 additions & 0 deletions druntime/mak/SRCS
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ SRCS=\
src\core\memory.d \
src\core\runtime.d \
src\core\simd.d \
src\core\system\opt.d \
src\core\system\package.d \
src\core\time.d \
src\core\vararg.d \
src\core\volatile.d \
Expand Down
32 changes: 21 additions & 11 deletions druntime/src/core/gc/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@ module core.gc.config;

import core.internal.parseoptions;
import core.stdc.stdio : printf;
import core.system : Sys;
import core.system.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
Expand All @@ -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)
Expand All @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions druntime/src/core/gc/registry.d
Original file line number Diff line number Diff line change
Expand Up @@ -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.system : Mem;

auto ptr = cast(Entry*)realloc(entries.ptr, (entries.length + 1) * Entry.sizeof);
auto ptr = cast(Entry*) Mem.reallocate(entries.ptr, (entries.length + 1) * Entry.sizeof);
entries = ptr[0 .. entries.length + 1];
entries[$ - 1] = Entry(name, factory, threadInit);
}
Expand All @@ -77,15 +77,15 @@ void registerGCFactory(string name, GCFactory factory,
*/
GC createGCInstance(string name)
{
import core.stdc.stdlib : free;
import core.system : Mem;

foreach (entry; entries)
{
if (entry.name != name)
continue;
auto instance = entry.factory();
// only one GC at a time for now, so free the registry to not leak
free(entries.ptr);
Mem.free(entries.ptr);
entries = null;
return instance;
}
Expand Down
1 change: 1 addition & 0 deletions druntime/src/core/internal/array/utils.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 3 additions & 3 deletions druntime/src/core/internal/gc/bits.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import core.internal.gc.os;

import core.bitop;
import core.exception : onOutOfMemoryError;
import core.stdc.stdlib : calloc, free;
import core.system : Mem;
import core.stdc.string : memcpy, memset;

// use version gcbitsSingleBitOperation to disable optimizations that use
Expand All @@ -38,7 +38,7 @@ struct GCBits
if (data)
{
if (!AllocSupportsShared || !share)
free(data);
Mem.free(data);
else static if (AllocSupportsShared)
os_mem_unmap_shared(data, nwords * data[0].sizeof);
else
Expand All @@ -51,7 +51,7 @@ struct GCBits
{
this.nbits = nbits;
if (!AllocSupportsShared || !share)
data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof);
Comment thread
denizzzka marked this conversation as resolved.
data = cast(typeof(data[0])*) Mem.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
Expand Down
12 changes: 6 additions & 6 deletions druntime/src/core/internal/gc/impl/manual/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -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.system: Mem;
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@@@ */
Expand All @@ -46,7 +46,7 @@ private GC initialize()
{
import core.lifetime : emplace;

auto gc = cast(ManualGC) cstdlib.malloc(__traits(classInstanceSize, ManualGC));
auto gc = cast(ManualGC) Mem.allocateOne(__traits(classInstanceSize, ManualGC));
if (!gc)
onOutOfMemoryError();

Expand Down Expand Up @@ -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 = Mem.allocateOne(size);

if (size && p is null)
onOutOfMemoryError();
Expand All @@ -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 = Mem.allocateOneBlank(size);

if (size && p is null)
onOutOfMemoryError();
Expand All @@ -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 = Mem.reallocate(p, size);

if (size && p is null)
onOutOfMemoryError();
Expand All @@ -148,7 +148,7 @@ class ManualGC : GC

void free(void* p) nothrow @nogc
{
cstdlib.free(p);
Mem.free(p);
}

/**
Expand Down
21 changes: 10 additions & 11 deletions druntime/src/core/runtime.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

module core.runtime;

import core.system : Mem;

version (OSX)
version = Darwin;
else version (iOS)
Expand Down Expand Up @@ -209,7 +211,7 @@ struct Runtime
*/
static void* loadLibrary()(const scope char[] name)
{
import core.stdc.stdlib : free, malloc;
import core.system : Mem;
version (Windows)
{
import core.sys.windows.winnls : CP_UTF8, MultiByteToWideChar;
Expand All @@ -222,9 +224,9 @@ struct Runtime
if (len == 0)
return null;

auto buf = cast(WCHAR*)malloc((len+1) * WCHAR.sizeof);
auto buf = cast(WCHAR*) Mem.allocateOne((len+1) * WCHAR.sizeof);
if (buf is null) return null;
scope (exit) free(buf);
scope (exit) Mem.free(buf);

len = MultiByteToWideChar(
CP_UTF8, 0, name.ptr, cast(int)name.length, buf, len);
Expand All @@ -240,9 +242,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*) Mem.allocateOne(len + 1);
if (!buf) return null;
scope (exit) free(buf);
scope (exit) Mem.free(buf);

buf[0 .. len] = name[];
buf[len] = 0;
Expand Down Expand Up @@ -743,8 +745,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) Mem.allocateOne(__traits(classInstanceSize, T));
return emplace(result, args);
}
version (Windows)
Expand Down Expand Up @@ -803,16 +804,14 @@ void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow
return;
auto obj = cast(Object)info;
destroy(obj);
import core.stdc.stdlib : free;
free(cast(void *)obj);
Mem.free(cast(void *)obj);
}

/// Default implementation for most POSIX systems
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
Expand Down Expand Up @@ -879,7 +878,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) Mem.free(cast(void*) framelist);

static if (enableDwarf)
{
Expand Down
11 changes: 11 additions & 0 deletions druntime/src/core/system/opt.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
///
module core.system.opt;

package(core):

struct Opt
{
import core.gc.config: ConfigT;

alias GcConfig = ConfigT!();
}
49 changes: 49 additions & 0 deletions druntime/src/core/system/package.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
///
module core.system;

//TODO: package
//package:
Comment thread
denizzzka marked this conversation as resolved.
Outdated

struct Mem
{
import core.stdc.stdlib;

alias allocateOne = malloc;
alias allocateFew = (size_t num, size_t size) => allocateOne(num * size);
static void* allocateOneBlank(size_t size) nothrow @nogc => allocateFewBlank(1, size);
alias allocateFewBlank = calloc;
alias reallocate = realloc;
alias free = core.stdc.stdlib.free;

alias allocateOnStack = alloca;
}

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();
}
}
Loading
Loading