I decided to boil going without gc down to one simple move: put this code into a file called nogc.d and then add it to your dmd command line:

===

import core.stdc.stdio;
import core.stdc.stdlib;

extern(C):

void* gc_malloc() {
fprintf(stderr, "GC allocations are disabled\nProgram terminated\n");
        asm { hlt; }
        assert(0);
}

// druntime calls these, but we can just stub them out
void gc_init() { }
void gc_addRange() { }
void gc_term() { }

// druntime makes some classes too. we'll malloc them. This technically // leaks but since it is startup code I'm pretty sure it doesn't matter.

// this also makes new class available to user code, but remember to free your classes and call the destructor:
/*
void free(Object object) {
auto dtor = cast(void function(Object o)) object.classinfo.destructor;
        if(dtor)
                dtor(object);
        free(cast(void*) object);
}
*/
extern(C) Object _d_newclass(const ClassInfo ci) {
        void* memory = malloc(ci.init.length);
        if(memory is null) {
fprintf(stderr, "Out of memory to allocate class\n");
                asm { hlt; }
                assert(0);
        }
        (cast(byte*) memory)[0 .. ci.init.length] = ci.init[];
        return cast(Object) memory;
}

===



You shouldn't have to modify your code nor druntime/phobos (though you'll probably find them being killed by hidden allocations!), unlike the minimal D stuff I've been talking about the last few weeks which replaces them entirely.

The reason it works is the gc functions come from a library file. .lib functions are overridden by functions with the same name in an object file.

So this redefines crucial gc functions, and then the linker uses them instead of the ones druntime provides.Thereby stubbing out the garbage collector in this individual exe. I tried it on both Windows and Linux and it seemed to work as I expected.

The resulting executable is slightly smaller too, since the linker can dump more functions that are never called by the stubs:

$ dmd test2.d
You have mail in /var/spool/mail/me
$ ls -lh test2
-rwxr-xr-x 1 me users 683K 2013-06-10 15:06 test2
$ dmd test2.d nogc.d
$ ls -lh test2
-rwxr-xr-x 1 me users 626K 2013-06-10 15:06 test2

(test2.d is just a random program that does writeln("ctor") and writeln("dtor") on a few classes to see when/if they are still running, nothing special there)


On IRC someone suggested an even simpler solution to me too: set a breakpoint at gc_malloc in your debugger. Then you can see where it is called and continue/stop at any time.



I found a hidden allocation in druntime using this instantly and already filed to bugzilla. If you are on an AMD processor you'll probably see it too if you try to run a program
http://d.puremagic.com/issues/show_bug.cgi?id=10323

so you won't get far with nogc.d! But if you fix that up and try again I was able to get my test to run.

Reply via email to