[fpc-pascal] Stack alias for ARC like memory management?

Ryan Joseph ryan at thealchemistguild.com
Wed Apr 25 03:15:50 CEST 2018


I had another idea and I was just curious what anyone thought about it. Between C++ where classes can either be on the stack or heap and full ARC like in Swift/Java FPC is kind of in the middle with a unified heap-only class system which is easier to use than C++ (classes are always pointers so need to worry about pointer indirection all the time) but creates lots of garbage memory you need to manage yourself (no ARC/garbage collector unless you count ref counted interfaces).

My idea is to keep the FPC class as is but introduce a keyword that allocates the classes memory on the stack upon declaration. Then we you call Create like you normally would, instead of getting a new chunk of memory from GetMem the class internally references the pointer on the stack. Finally when the scope terminates it calls the destructor in a recursive process on all local variables (or class members) that are stack alias.

The benefits are:

1) Easy to implement since it just overrides GetMem with another pointer
2) Transparent to switch between heap vs stack since the class is always a pointer so no copying on pas and, pointer indirection, like c++ classes on the stack or Objects in Pascal (objects are missing features anyways and allocating on the stack still uses new() ). FPC is even worse than C++ in this regard because switching between class vs object is a real mess and just not practical.
3) More performant since we don’t need to allocate memory on the heap which we already know will be needed at compile time anyways. Doesn't require a runtime for garbage collecting and doesn’t allocate memory on the heap behind the scenes like Swift and full ARC systems probably do.

What do you think? Is there any merit to this idea? It’s not real reference counting but it’s a simple solution to improve performance and clean up code in many common scenarios.

type
	TMyClass = class
		child: TObject; stackalias;
		constructor Create; override;
		destructor Destroy; override;
	end;

constructor TMyClass.Create;
begin
	child := TObject.Create;
end;

destructor TMyClass.Destroy;
begin
	// all stack alias members call destructor here
end;

var
	parent: TMyClass; stackalias; // memory is reserved on the stack for sizeof(TMyClass)
begin
	parent := TMyClass.Create; // constructor still works like normal but internal pointer points to @parent

	// all stack alias local variables call destructor at end of scope
end;



Regards,
	Ryan Joseph




More information about the fpc-pascal mailing list