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