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.