[Issue 15353] New: std.experimental.allocator cannot free memory in its destructor if the GC is an ancestor
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Tue Nov 17 10:44:19 PST 2015
https://issues.dlang.org/show_bug.cgi?id=15353
Issue ID: 15353
Summary: std.experimental.allocator cannot free memory in its
destructor if the GC is an ancestor
Product: D
Version: D2
Hardware: All
OS: All
Status: NEW
Severity: normal
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: andrei at erdani.com
Brian Schott noticed this and wrote:
==============
I've discovered a problem with the interaction between CAllocatorImpl and
GCAllocator: CAllocatorImpl cannot have a parent allocator that uses
GCAllocator, or a parent that has a parent (and so on) that uses GCAllocator.
This is because several of the allocator implementations are structs that
deallocate their memory during their destructors.
In the case of CAllocatorImpl, this destructor call is often caused by the GC.
Calls to the GC fail during destructors called by the GC, so something needs to
be done to fix this. Maybe extra logic can be added to the various allocators
to check that they are not calling GCAllocator during a destructor, or we can
somehow disallow using GC-backed allocators from CAllocatorImpl.
Example:
https://gist.github.com/Hackerpilot/26c2d0e7b1aa0605b344
==============
To which I replied:
==============
I imagine there are a number of ways we can fix this:
(a) Allow freeing memory but not allocation during GC. I'm not sure but I
suspect that it's memory allocation that mustn't be allowed during a GC cycle.
Martin, could you please confirm/deny this?
(b) The GC has or should have a primitive that tells code whether a collection
is in progress. Then allocator destructors can test that and do nothing if
that's the case.
(c) Have the GC itself ignore calls to free during a collection cycle.
==============
To which Martin Nowak replied:
==============
Free also manipulates internal structures.
https://github.com/D-Programming-Language/druntime/blob/12ea1075fc24a5389a4e1aa24ae9e177903f85d2/src/gc/gc.d#L873
https://github.com/D-Programming-Language/druntime/blob/12ea1075fc24a5389a4e1aa24ae9e177903f85d2/src/gc/gc.d#L2245
With the current code, it would be very delicate to allow free during
finalization.
[About having the GC just ignore calls to free during a GC cycle:]
Seems like a feasible solution for now.
In general the GC isn't reentrant safe, and that will be enforced even
stricter by using a non-recursive lock
https://trello.com/c/Xp44NwHG/87-ttas-spinlock-for-gc.
We do want to get rid of the InvalidMemoryOperation issue, and should
revisit it once the thread caches are implemented. During a collection
it should be possible to queue most operations and serve allocations
(maybe from a separate pool). There are still a lot of rather big
changes planned to the GC before it makes sense to look at this
particular issue.
==============
So it seems a good fix for this bug would be to just have the GC ignore calls
to free().
--
More information about the Digitalmars-d-bugs
mailing list