On Monday, 21 October 2013 at 07:31:30 UTC, Ali Çehreli wrote:
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

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:
Am 21.10.2013 04:17, schrieb Adam D. Ruppe:
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.

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 Thaut

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.

Reply via email to