digitalmars.D.learn - Call destructor directly.
- Agustin (9/9) Oct 20 2013 I'm implementing some custom memory allocator, is possible to
- Adam D. Ruppe (8/10) Oct 20 2013 destroy(object);
- Agustin (2/12) Oct 20 2013 Thank you :)
- Agustin (10/26) Oct 20 2013 What about constructor?. My current code is:
- Jonathan M Davis (3/15) Oct 20 2013 IIRC, the constructor should be name __ctor.
- Agustin (3/18) Oct 20 2013 no property 'opCall' for type 'Main.MyClass' :(
- Agustin (4/24) Oct 20 2013 Trait allMember return "__ctor", but seems like i cannot call it
- Jonathan M Davis (14/44) Oct 20 2013 If you want to see how to use emplace, I'd advise looking at
- Agustin (11/61) Oct 20 2013 I'm silly the issue was at this line
- Agustin (17/85) Oct 20 2013 That didn't work, but after reading how emplace works, i had to
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (40/45) Oct 21 2013 Does rawAllocate still return void*? For classes, emplace requires (or
- Agustin (25/117) Oct 21 2013 Thanks!, i didn't knew i could do that, void[] sounds like an
- Benjamin Thaut (23/32) Oct 21 2013 Using destroy will zero the entire memory block after destroying the
- Dicebot (4/10) Oct 21 2013 It is probably a good idea to use malloc/free for deterministic
I'm implementing some custom memory allocator, is possible to call an object destructor directly? For example void deallocate(T)(T object) { assert(object !is null); object.~this(); rawDeallocate(cast(void *)object); }
Oct 20 2013
On Monday, 21 October 2013 at 02:06:02 UTC, Agustin wrote:I'm implementing some custom memory allocator, is possible to call an object destructor directly?destroy(object); destroy is in the automatically imported object.dm so you don't have to import anything, The source code is in dmd2/src/druntime/src/object_.d, there's a few overloads if you are curious how it is implemented. Short answer is there's a pointer to the destructor in the TypeInfo and destroy calls it.
Oct 20 2013
On Monday, 21 October 2013 at 02:17:54 UTC, Adam D. Ruppe wrote:On Monday, 21 October 2013 at 02:06:02 UTC, Agustin wrote:Thank you :)I'm implementing some custom memory allocator, is possible to call an object destructor directly?destroy(object); destroy is in the automatically imported object.dm so you don't have to import anything, The source code is in dmd2/src/druntime/src/object_.d, there's a few overloads if you are curious how it is implemented. Short answer is there's a pointer to the destructor in the TypeInfo and destroy calls it.
Oct 20 2013
On Monday, 21 October 2013 at 02:26:03 UTC, Agustin wrote:On Monday, 21 October 2013 at 02:17:54 UTC, Adam D. Ruppe wrote:What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.On Monday, 21 October 2013 at 02:06:02 UTC, Agustin wrote:Thank you :)I'm implementing some custom memory allocator, is possible to call an object destructor directly?destroy(object); destroy is in the automatically imported object.dm so you don't have to import anything, The source code is in dmd2/src/druntime/src/object_.d, there's a few overloads if you are curious how it is implemented. Short answer is there's a pointer to the destructor in the TypeInfo and destroy calls it.
Oct 20 2013
On Monday, October 21, 2013 05:07:02 Agustin wrote:What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.IIRC, the constructor should be name __ctor. - Jonathan M Davis
Oct 20 2013
On Monday, 21 October 2013 at 03:46:33 UTC, Jonathan M Davis wrote:On Monday, October 21, 2013 05:07:02 Agustin wrote:no property 'opCall' for type 'Main.MyClass' :(What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.IIRC, the constructor should be name __ctor. - Jonathan M Davis
Oct 20 2013
On Monday, 21 October 2013 at 03:50:24 UTC, Agustin wrote:On Monday, 21 October 2013 at 03:46:33 UTC, Jonathan M Davis wrote:Trait allMember return "__ctor", but seems like i cannot call it directly: (cast(T)pMemory).__ctor(arguments); // Being pMemory void*On Monday, October 21, 2013 05:07:02 Agustin wrote:no property 'opCall' for type 'Main.MyClass' :(What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.IIRC, the constructor should be name __ctor. - Jonathan M Davis
Oct 20 2013
On Monday, October 21, 2013 05:53:46 Agustin wrote:On Monday, 21 October 2013 at 03:50:24 UTC, Agustin wrote:If you want to see how to use emplace, I'd advise looking at std.typecons.RefCounted's implementation: https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L3505 emplace calls the constructor for you, so I don't know why you'd be trying to call it. But you can look at emplace's implementation if you want to see how to call __ctor. For structs: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L3976 For classes: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L4716 I don't think that it'll work if the constructor is private though, so maybe that's your problem. - Jonathan M DavisOn Monday, 21 October 2013 at 03:46:33 UTC, Jonathan M Davis wrote:Trait allMember return "__ctor", but seems like i cannot call it directly: (cast(T)pMemory).__ctor(arguments); // Being pMemory void*On Monday, October 21, 2013 05:07:02 Agustin wrote:no property 'opCall' for type 'Main.MyClass' :(What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.IIRC, the constructor should be name __ctor. - Jonathan M Davis
Oct 20 2013
On Monday, 21 October 2013 at 05:17:01 UTC, Jonathan M Davis wrote:On Monday, October 21, 2013 05:53:46 Agustin wrote:I'm silly the issue was at this line auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); emplace(pMemory, arguments); Correct was auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); emplace(&pMemory, arguments); Thanks guysOn Monday, 21 October 2013 at 03:50:24 UTC, Agustin wrote:If you want to see how to use emplace, I'd advise looking at std.typecons.RefCounted's implementation: https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L3505 emplace calls the constructor for you, so I don't know why you'd be trying to call it. But you can look at emplace's implementation if you want to see how to call __ctor. For structs: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L3976 For classes: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L4716 I don't think that it'll work if the constructor is private though, so maybe that's your problem. - Jonathan M DavisOn Monday, 21 October 2013 at 03:46:33 UTC, Jonathan M Davis wrote:Trait allMember return "__ctor", but seems like i cannot call it directly: (cast(T)pMemory).__ctor(arguments); // Being pMemory void*On Monday, October 21, 2013 05:07:02 Agustin wrote:no property 'opCall' for type 'Main.MyClass' :(What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.IIRC, the constructor should be name __ctor. - Jonathan M Davis
Oct 20 2013
On Monday, 21 October 2013 at 05:40:13 UTC, Agustin wrote:On Monday, 21 October 2013 at 05:17:01 UTC, Jonathan M Davis wrote:That didn't work, but after reading how emplace works, i had to make some changes. public T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); assert(pMemory !is null, "Not enought memory on the allocator"); byte[] * pByteMemory = cast(byte[] *) pMemory; *pByteMemory = typeid(T).init[]; auto pObject = cast(T) pMemory; static if (is(typeof(pObject.__ctor(arguments)))) { pObject.__ctor(arguments); } return pObject; } That would work.On Monday, October 21, 2013 05:53:46 Agustin wrote:I'm silly the issue was at this line auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); emplace(pMemory, arguments); Correct was auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); emplace(&pMemory, arguments); Thanks guysOn Monday, 21 October 2013 at 03:50:24 UTC, Agustin wrote:If you want to see how to use emplace, I'd advise looking at std.typecons.RefCounted's implementation: https://github.com/D-Programming-Language/phobos/blob/master/std/typecons.d#L3505 emplace calls the constructor for you, so I don't know why you'd be trying to call it. But you can look at emplace's implementation if you want to see how to call __ctor. For structs: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L3976 For classes: https://github.com/D-Programming-Language/phobos/blob/master/std/conv.d#L4716 I don't think that it'll work if the constructor is private though, so maybe that's your problem. - Jonathan M DavisOn Monday, 21 October 2013 at 03:46:33 UTC, Jonathan M Davis wrote:Trait allMember return "__ctor", but seems like i cannot call it directly: (cast(T)pMemory).__ctor(arguments); // Being pMemory void*On Monday, October 21, 2013 05:07:02 Agustin wrote:no property 'opCall' for type 'Main.MyClass' :(What about constructor?. My current code is: T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); // Return void* emplace!T(cast(T *)pMemory, arguments); return cast(T) pMemory; } Doesn't seems to work, and i can't find any good documentation about it.IIRC, the constructor should be name __ctor. - Jonathan M Davis
Oct 20 2013
On 10/20/2013 10:59 PM, Agustin wrote:That didn't work, but after reading how emplace works, i had to make some changes. public T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof);Does rawAllocate still return void*? For classes, emplace requires (or at least "also accepts" a slice). Your code will be simpler if rawAllocate returned a slice: import std.conv; void[] rawAllocate(size_t, size_t) { static ubyte[1000] buffer; return buffer; } T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); return emplace!T(pMemory, arguments); } class C { this(int i, double d) {} } void main() { auto c = allocate!C(42, 1.5); } If it has to return void*, you can make a slice from a plain pointer with the following syntax: void * rawAllocate(size_t, size_t) { static ubyte[1000] buffer; return buffer.ptr; } import std.stdio; void main() { enum requiredLength = 42; auto rawPtr = rawAllocate(requiredLength, 16); auto slice = rawPtr[0..requiredLength]; // <-- slice from plain pointer writeln(slice); } Ali
Oct 21 2013
On Monday, 21 October 2013 at 07:31:30 UTC, Ali Çehreli wrote:On 10/20/2013 10:59 PM, Agustin wrote:Thanks!, i didn't knew i could do that, void[] sounds like an array of nothing :P. On Monday, 21 October 2013 at 11:48:11 UTC, Benjamin Thaut wrote:That didn't work, but after reading how emplace works, i hadto makesome changes. public T allocate(T : Object, A...)(auto ref Aarguments) {auto pMemory =rawAllocate(__traits(classInstanceSize, T),T.alignof);Does rawAllocate still return void*? For classes, emplace requires (or at least "also accepts" a slice). Your code will be simpler if rawAllocate returned a slice: import std.conv; void[] rawAllocate(size_t, size_t) { static ubyte[1000] buffer; return buffer; } T allocate(T : Object, A...)(auto ref A arguments) { auto pMemory = rawAllocate(__traits(classInstanceSize, T), T.alignof); return emplace!T(pMemory, arguments); } class C { this(int i, double d) {} } void main() { auto c = allocate!C(42, 1.5); } If it has to return void*, you can make a slice from a plain pointer with the following syntax: void * rawAllocate(size_t, size_t) { static ubyte[1000] buffer; return buffer.ptr; } import std.stdio; void main() { enum requiredLength = 42; auto rawPtr = rawAllocate(requiredLength, 16); auto slice = rawPtr[0..requiredLength]; // <-- slice from plain pointer writeln(slice); } AliAm 21.10.2013 04:17, schrieb Adam D. Ruppe:I just need to call the destructor of the class since the memory of the allocators is released at the end of the application. // Pre allocate 1GB. auto pMemory = GC.malloc(1_048_576 * 1000, GC.BlkAttr.NONE); // Allocate a linear allocator of 10MB. auto pLinearAllocator = new LinearAllocator(1_048_576 * 10, pMemory); // Allocates a pool allocator of 50MB. auto pMemoryBlock = pMemory + 1_048_576 * 10; auto pPoolAllocator = new PoolAllocator!MyComponent(1_048_576 * 50, pMemory + 1_048_576 * 10); // Game loop, etc. // ..... (When a object is called to release, it won't release its memory rather than cache the entry and call the object destructor. Releasing the object from GC // end of game exit() // Allocators are released here, because GC will not find any reference to it, and will call any object destructor left.On Monday, 21 October 2013 at 02:06:02 UTC, Agustin wrote:Using destroy will zero the entire memory block after destroying the object. If you are freeing the memory right after destroying this is going to cost you performance. To avoid this declare: extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true); and then call rt_finalize(cast(void*)object, false, false); Also if you want to give a nice error message in case you are calling a construcor that does not exist you should take a look at my AllocatorNew function: https://github.com/Ingrater/druntime/blob/merge64/src/core/allocator.d#L616 Doing it the way emplace does will just result in a error message "Dont know how to initialize a object of type YourObject" With some meta programming you can get error messages like: "Dont know how to initialize a object of type YourObject Available constructors: this(int, int) this(float) this(void*)" Kind Regards Benjamin ThautI'm implementing some custom memory allocator, is possible to call an object destructor directly?destroy(object); destroy is in the automatically imported object.dm so you don't have to import anything, The source code is in dmd2/src/druntime/src/object_.d, there's a few overloads if you are curious how it is implemented. Short answer is there's a pointer to the destructor in the TypeInfo and destroy calls it.
Oct 21 2013
Am 21.10.2013 04:17, schrieb Adam D. Ruppe:On Monday, 21 October 2013 at 02:06:02 UTC, Agustin wrote:Using destroy will zero the entire memory block after destroying the object. If you are freeing the memory right after destroying this is going to cost you performance. To avoid this declare: extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true); and then call rt_finalize(cast(void*)object, false, false); Also if you want to give a nice error message in case you are calling a construcor that does not exist you should take a look at my AllocatorNew function: https://github.com/Ingrater/druntime/blob/merge64/src/core/allocator.d#L616 Doing it the way emplace does will just result in a error message "Dont know how to initialize a object of type YourObject" With some meta programming you can get error messages like: "Dont know how to initialize a object of type YourObject Available constructors: this(int, int) this(float) this(void*)" Kind Regards Benjamin ThautI'm implementing some custom memory allocator, is possible to call an object destructor directly?destroy(object); destroy is in the automatically imported object.dm so you don't have to import anything, The source code is in dmd2/src/druntime/src/object_.d, there's a few overloads if you are curious how it is implemented. Short answer is there's a pointer to the destructor in the TypeInfo and destroy calls it.
Oct 21 2013
On Monday, 21 October 2013 at 11:48:11 UTC, Benjamin Thaut wrote:Using destroy will zero the entire memory block after destroying the object. If you are freeing the memory right after destroying this is going to cost you performance. To avoid this declare: extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true);It is probably a good idea to use malloc/free for deterministic allocators anyway as GC is not really supposed to be used that way by design.
Oct 21 2013