[dmd-internals] DMD internal memory management issue

Denis 2korden at gmail.com
Tue Dec 8 09:37:05 PST 2009


I came across one memory allocation related problem in DMD and decided
to make a post about it in this list.

It looks like at some point Walter decided to introduce some kind of a
garbage collector by wrapping all allocations with
mem.malloc()/mem.free()/mem.mark()/mem.fullcollect() etc. Problem is,
the feature is somewhat half-implemented (not the Garbage collection
itself, but moving all the memory allocations to a proxy object): half
of DMD uses mem.malloc, and the other half uses raw ::malloc. In some
cases it even allocates using mem.malloc() but deallocates with
::free().

I came across this issue while porting code to D.

Naturally, I forward mem.malloc() to GC.malloc() so that memory gets
garbage collected. But in some cases memory gets allocated in
front-end using mem.malloc(), but deallocated in backend using ::free.
That's where my application either hangs or causes Access Violations.

I strongly believe this is a (logical) bug, but a minor one. It
doesn't showup in DMD so it's somewhat pointless to put into bugzilla.
Nevertheless, I believe it would be nice to get this bug fixed.

So far I only noticed it in one place, but I suspect it might appear
in other areas, too.

Here it is:

s2ir.c, FuncDeclaration::toObj() (handling switch statement)

targ_llong *pu = (targ_llong *) mem.malloc(sizeof(*pu) * (numcases +
1)); // allocating using mem.malloc()
mystate.switchBlock.BS.Bswitch = pu;

backend/blockopt.c, void block_free(block *b) (memory cleanup)

switch (b.BC)
 {
    case BCswitch:
    case BCifthen:
    case BCjmptab:
        MEM_PH_FREE(b.BS.Bswitch); // freeing using ::free()
        break;

---
Denis Koroskin


More information about the dmd-internals mailing list