Manually allocate delegate?
Tofu Ninja via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Nov 21 00:04:22 PST 2015
On Saturday, 21 November 2015 at 00:30:45 UTC, userABCabc123
wrote:
>
> Yes:
>
> ========================
> class Foo
> {
> void bar(){writeln(__PRETTY_FUNCTION__);}
> }
>
> auto uncollectedDelegate(T, string name)(ref T t)
> {
> import std.experimental.allocator.mallocator;
> struct Dg{void* ptr, funcptr;}
>
> void* funcptr = &__traits(getMember, T, name);
> void* ptr = cast(void*)t;
>
> Dg* dg = cast(Dg*) Mallocator.instance.allocate(Dg.sizeof);
> dg.ptr = ptr;
> dg.funcptr = funcptr;
> return dg;
> }
>
> void main(string[] args)
> {
> Foo foo = new Foo;
> auto dg = uncollectedDelegate!(Foo, "bar")(foo);
> auto tdg = cast(void delegate()*) dg;
> (*tdg)();
> }
> ========================
>
> with just a type __traits(getMember,...) on a delegate will
> only return the function address in the process image. so
> without the context ptr, just like a static or a global
> function. Later you set the context by hand, using a pointer to
> an instance.
I think you are misunderstanding a bit what my original question
was. The delegate it self is not gc allocated. The delegate it
self is just 2 pointers(a function pointer and a context
pointer), they are simply stack allocated. I am not woried about
allocating that bit. What I am worried about allocating is the
context, and primarily the context for nested functions(often
called a closure).
For delegates to member functions, the context pointer is always
just a pointer to the object that you pulled the delegate off of.
To avoid gc allocating the context there, all you need to do is
just don't gc allocate the object. Simple. In your example the
context is still gc allocated with new Foo;. You actually added
in another allocation on top of that with the mallocator. You now
allocate the delegate it self, which normally can just be stack
allocated.
The problem that I was concerned about was the case of nested
function delegates. For delegates to nested functions that need
to generate a closure, the allocation of the closure is
implicitly done and done with the gc. As far as I can tell, there
is no way to know anything about that closure, not its size,
layout, contents, no way to manually allocate it.
Example:
auto foo(int x)
{
int bar(){ return x; }
return &bar; // <-- implicitly allocates a closure with the gc
}
More information about the Digitalmars-d-learn
mailing list