why allocators are not discussed here
H. S. Teoh
hsteoh at quickfur.ath.cx
Wed Jun 26 09:51:47 PDT 2013
On Wed, Jun 26, 2013 at 04:31:40PM +0200, cybervadim wrote:
> On Wednesday, 26 June 2013 at 14:26:03 UTC, H. S. Teoh wrote:
> >Yeah, I think the best approach would be one that doesn't require
> >changing a whole mass of code to support. Also, one that doesn't
> >require language changes would be far more likely to be accepted, as
> >the core D devs are leery of adding yet more complications to the
> >language.
> >
> >That's why I proposed that gc_alloc and gc_free be made into
> >thread-global function pointers, that can be swapped with a custom
> >allocator's version. This doesn't have to be visible to user code; it
> >can just be an implementation detail in std.allocator, for example.
> >It allows us to implement custom allocators across a block of code
> >that doesn't know (and doesn't need to know) what allocator will be
> >used.
> >
>
> Yes, being able to change gc_alloc, gc_free would do the work. If
> runtime remembers the stack of gc_alloc/gc_free functions like pushd,
> popd, that would simplify its usage. I think this is a very nice and
> simple solution to the problem.
Adam's idea does this: tie each replacement of gc_alloc/gc_free to some
stack-based object, that automatically cleans up in the dtor. So
something along these lines:
struct CustomAlloc(A) {
void* function(size_t size) old_alloc;
void function(void* ptr) old_free;
this(A alloc) {
old_alloc = gc_alloc;
old_free = gc_free;
gc_alloc = &A.alloc;
gc_free = &A.free;
}
~this() {
gc_alloc = old_alloc;
gc_free = old_free;
// Cleans up, e.g., region allocator deletes the
// region
A.cleanup();
}
}
class C {}
void main() {
auto c = new C(); // allocates using default allocator (GC)
{
CustomAlloc!MyAllocator _;
// Everything from here on until end of block
// uses MyAllocator
auto d = new C(); // allocates using MyAllocator
{
CustomAlloc!AnotherAllocator _;
auto e = new C(); // allocates using AnotherAllocator
// End of scope: auto cleanup, gc_alloc and
// gc_free reverts back to MyAllocator
}
auto f = new C(); // allocates using MyAllocator
// End of scope: auto cleanup, gc_alloc and
// gc_free reverts back to default values
}
auto g = new C(); // allocates using default allocator
}
So you effectively have an allocator stack, and user code never has to
directly manipulate gc_alloc/gc_free (which would be dangerous).
T
--
Almost all proofs have bugs, but almost all theorems are true. -- Paul Pedersen
More information about the Digitalmars-d
mailing list