www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Allocators stack

reply "Allocator stack" <iackhtak gmail.com> writes:
How about allocators stack? Allocator e.g. one of these
https://github.com/andralex/phobos/blob/allocator/std/allocator.d
-------------
allocatorStack.push(new GCAllocator);
//Some code that use memory allocation
auto a = ['x', 'y'];
a ~= ['a', 'b']; // use allocatorStack.top.realloc(...);
allocatorStack.pop();
-------------
Allocators must be equipped with dynamic polymorphism. For those
cases when it is too expensive attribute
 allocator(yourAllocator) applied to declaration set allocator
statically.

-------------
 allocator(Mallocator.instance)
void f()
{
// Implicitly use global(tls?) allocator Mallocator when allocate 
an
object or resize an array or etc.
}

 allocator("StackAllocator")
void f()
{
// Implicitly use allocatorStack.top() allocator when allocate an
object or resize an array or etc.
}
-------------

There is some issues to solve. E.g. how to eliminate mix memory 
from different allocators.
Dec 22 2014
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Monday, 22 December 2014 at 16:51:30 UTC, Allocator stack 
wrote:
 How about allocators stack? Allocator e.g. one of these
 https://github.com/andralex/phobos/blob/allocator/std/allocator.d
 -------------
 allocatorStack.push(new GCAllocator);
 //Some code that use memory allocation
 auto a = ['x', 'y'];
 a ~= ['a', 'b']; // use allocatorStack.top.realloc(...);
 allocatorStack.pop();
 -------------
 Allocators must be equipped with dynamic polymorphism. For those
 cases when it is too expensive attribute
  allocator(yourAllocator) applied to declaration set allocator
 statically.

 -------------
  allocator(Mallocator.instance)
 void f()
 {
 // Implicitly use global(tls?) allocator Mallocator when 
 allocate an
 object or resize an array or etc.
 }

  allocator("StackAllocator")
 void f()
 {
 // Implicitly use allocatorStack.top() allocator when allocate 
 an
 object or resize an array or etc.
 }
 -------------

 There is some issues to solve. E.g. how to eliminate mix memory 
 from different allocators.
There are only a couple of constructs in D that allocate, so it may be worthwhile to let the allocator control the primitives, i.e.: auto gc = new GCAllocator(...); gc.Array!char a = ['x', 'y']; a ~= ['a', 'b']; //use allocatorStack.top.realloc(...); //I don't remember the proposed API for //allocators, but you get the idea gcAlloc.DestroyAll(); This looks a bit uglier, but it also doesn't require any new language constructs. The downside is, how do you manage things like closures doing it this way?
Dec 22 2014
parent reply "Allocator stack" <iackhtak gmail.com> writes:
On Monday, 22 December 2014 at 21:09:21 UTC, Meta wrote:
 There are only a couple of constructs in D that allocate, so it 
 may be worthwhile to let the allocator control the primitives, 
 i.e.:

 auto gc = new GCAllocator(...);
 gc.Array!char a = ['x', 'y'];
 a ~= ['a', 'b']; //use allocatorStack.top.realloc(...);
 //I don't remember the proposed API for
 //allocators, but you get the idea
 gcAlloc.DestroyAll();

 This looks a bit uglier, but it also doesn't require any new 
 language constructs. The downside is, how do you manage things 
 like closures doing it this way?
In this case you have to make all things template on allocator or even more on Allocator!T making Cartesian product of allocators and types. The point is to provide method to handle different memory management strategies by user in run time. It is ease to give up GC using annotation and run time stack. Set an allocator for a class by annotation(apply for all methods) and it force std library to use the allocator whenever you use it in the class.
Dec 23 2014
parent "Allocator stack" <iackhtak gmail.com> writes:
Walter's DIP: Region Based Memory Allocation
http://wiki.dlang.org/DIP46
"Sandboxes" for stateless programing
Dec 23 2014
prev sibling next sibling parent "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Monday, 22 December 2014 at 16:51:30 UTC, Allocator stack 
wrote:
 How about allocators stack? Allocator e.g. one of these
 https://github.com/andralex/phobos/blob/allocator/std/allocator.d
 -------------
 allocatorStack.push(new GCAllocator);
 //Some code that use memory allocation
 auto a = ['x', 'y'];
 a ~= ['a', 'b']; // use allocatorStack.top.realloc(...);
 allocatorStack.pop();
 -------------
 Allocators must be equipped with dynamic polymorphism. For those
 cases when it is too expensive attribute
  allocator(yourAllocator) applied to declaration set allocator
 statically.

 -------------
  allocator(Mallocator.instance)
 void f()
 {
 // Implicitly use global(tls?) allocator Mallocator when 
 allocate an
 object or resize an array or etc.
 }

  allocator("StackAllocator")
 void f()
 {
 // Implicitly use allocatorStack.top() allocator when allocate 
 an
 object or resize an array or etc.
 }
 -------------

 There is some issues to solve. E.g. how to eliminate mix memory 
 from different allocators.
I've put together some semi-realistic code that touches on this (ignore the `scope` thingies in there): http://wiki.dlang.org/User:Schuetzm/RC,_Owned_and_allocators The goal was to allow returning owned objects from functions that don't know what kind of memory management strategy the end user wants to use. The caller can then decide to convert them into ref counted objects, or release them and let the GC take care of them, or just use them in a UFCS chain and let them get destroyed at the end of the current statement automatically. This is achieved by storing a pointer to the allocator (which is an interface) next to the object. (As a side note, these interfaces can be auto-implemented by templates when needed, similar to `std.range.InputRange` et al.) This design makes it possible to switch allocators at runtime in any order, either through a global variable, or by passing a parameter to a function. It also avoids template bloat, because the functions involved just need to return Owned!MyType, which does not depend on the allocator type. The downside is, of course, the overhead of the indirect calls. (The call to `reallocate` can be left out in this example if `Owned` already preallocates some space for the refcount, therefore it's just two indirect calls for the lifetime of a typical object: one each for creation and destruction.) As for static allocators, I think it's not possible without sacrificing the ability to switch allocators at runtime and without templating on the allocator.
Dec 22 2014
prev sibling parent Rikki Cattermole <alphaglosined gmail.com> writes:
On 23/12/2014 5:51 a.m., Allocator stack wrote:
 How about allocators stack? Allocator e.g. one of these
 https://github.com/andralex/phobos/blob/allocator/std/allocator.d
 -------------
 allocatorStack.push(new GCAllocator);
 //Some code that use memory allocation
 auto a = ['x', 'y'];
 a ~= ['a', 'b']; // use allocatorStack.top.realloc(...);
 allocatorStack.pop();
 -------------
 Allocators must be equipped with dynamic polymorphism. For those
 cases when it is too expensive attribute
  allocator(yourAllocator) applied to declaration set allocator
 statically.

 -------------
  allocator(Mallocator.instance)
 void f()
 {
 // Implicitly use global(tls?) allocator Mallocator when allocate an
 object or resize an array or etc.
 }

  allocator("StackAllocator")
 void f()
 {
 // Implicitly use allocatorStack.top() allocator when allocate an
 object or resize an array or etc.
 }
 -------------

 There is some issues to solve. E.g. how to eliminate mix memory from
 different allocators.
I've also come up with a way to do this. Using the with statement and a couple extra functionality. with(new MyAllocator()) { // myAllocator.opWithIn(); Foo foo = new Foo(1); // myAllocator.alloc!Foo(1); } // myAllocator.opWithOut(); class MyAllocator : Allocator { private { Allocator old; } void opWithIn() { old = RuntimeThread.allocator; RuntimeThread.allocator = this; } void opWithout() { RuntimeThread.allocator = old; } } I'm sure you get the gist.
Dec 22 2014