Recent

Author Topic: Placing an instance of a class on the stack or in any memory area  (Read 649 times)

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 404
  • I use FPC [main] 💪🐯💪
I was interested in the task of making class instances be placed in any memory location, so far I have come to this code. Who is interested in this topic, I suggest to evaluate, criticize, give advice, improve the code, or maybe even say that it's all dabbling and unnecessary  :D
(in fact, it's a dabble for me so far, but who knows, maybe something interesting will be born from it, so I share with you + boast  :D )

Code: Pascal  [Select][+][-]
  1. program app;
  2. {$mode objfpc}
  3. {$modeswitch advancedrecords}
  4. {$h+}
  5.  
  6. uses Generics.Collections;
  7.  
  8. type
  9.   generic GetClass<T: class> = class sealed
  10.   strict private type
  11.     TWrapperClass = class sealed(T)
  12.       _InstanceSize_: Boolean;
  13.     end;
  14.   public const
  15.     Size = UIntPtr(@TWrapperClass(nil)._InstanceSize_);
  16.   end;
  17.  
  18.   generic TInplaceClass<T: class> = class(T)
  19.   private type
  20.     TSelf = specialize TInplaceClass<T>;
  21.     TSelfClass = class of TSelf;
  22.   strict private class threadvar
  23.     MemPointer: Pointer;
  24.   public
  25.     class function Inplace(mem: Pointer): TSelfClass; inline;
  26.     class function NewInstance: TObject; override;
  27.     procedure FreeInstance; override;
  28.   end;
  29.  
  30.   generic TInlineClass<T: class> = record
  31.   strict private type
  32.     TWrapperClass = specialize TInplaceClass<T>;
  33.   strict private
  34.     space: array [0..specialize GetClass<T>.Size-1] of Byte;
  35.   public
  36.     instance: TWrapperClass;
  37.     function get: TWrapperClass.TSelfClass; inline;
  38.   end;
  39.  
  40. class function TInplaceClass.NewInstance: TObject;
  41. begin
  42.   InitInstance(MemPointer);
  43.   NewInstance := TObject(MemPointer);
  44. end;
  45.  
  46. class function TInplaceClass.Inplace(mem: Pointer): TSelfClass;
  47. begin
  48.   MemPointer := mem;
  49.   Result := TSelf;
  50. end;
  51.  
  52. procedure TInplaceClass.FreeInstance;
  53. begin
  54. end;
  55.  
  56. function TInlineClass.get: TWrapperClass.TSelfClass;
  57. begin
  58.   instance := TWrapperClass(@space[0]);
  59.   Result := TWrapperClass.Inplace(@space[0]);
  60. end;
  61.  
  62. var
  63.   m: specialize TDictionary<byte, byte>;
  64.   inplace_class: specialize TInlineClass<(specialize TDictionary<byte, byte>)>;
  65.   arr1: array [0..specialize GetClass<specialize TDictionary<byte, byte>>.Size-1] of byte;
  66.   arr2: array [0..1000] of byte;
  67.  
  68. begin
  69. // ----
  70.   m := specialize TInplaceClass<(specialize TDictionary<byte, byte>)>.Inplace(@arr1[low(arr1)]).Create;
  71.  
  72.   m.Capacity:=1024;
  73.   m.Add(1,2);
  74.   m.Add(3,4);
  75.  
  76.   WriteLn(UIntPtr(@arr1[low(arr1)]));
  77.   WriteLn(UIntPtr(m));
  78.   WriteLn;
  79.  
  80.   m.Free;
  81.  
  82. // ----
  83.   m := specialize TInplaceClass<(specialize TDictionary<byte, byte>)>.Inplace(@arr2[low(arr2)]).Create;
  84.  
  85.   m.Capacity:=1024;
  86.   m.Add(1,2);
  87.   m.Add(3,4);
  88.  
  89.   WriteLn(UIntPtr(@arr2[low(arr2)]));
  90.   WriteLn(UIntPtr(m));
  91.   WriteLn;
  92.  
  93.   m.Free;
  94.  
  95. // ----
  96.   inplace_class.get.Create;
  97.  
  98.   inplace_class.instance.Capacity:=1024;
  99.   inplace_class.instance.Add(1,2);
  100.   inplace_class.instance.Add(3,4);
  101.  
  102.   WriteLn(UIntPtr(inplace_class.instance));
  103.   WriteLn(SizeOf(inplace_class));
  104.   WriteLn;
  105.  
  106.   inplace_class.instance.Free;
  107.  
  108.   ReadLn;
  109. end.
  110.  
I may seem rude - please don't take it personally

Fibonacci

  • Hero Member
  • *****
  • Posts: 790
  • Internal Error Hunter
Re: Placing an instance of a class on the stack or in any memory area
« Reply #1 on: May 08, 2025, 09:12:36 pm »
Nice, but what can it be used for?

ALLIGATOR

  • Sr. Member
  • ****
  • Posts: 404
  • I use FPC [main] 💪🐯💪
Re: Placing an instance of a class on the stack or in any memory area
« Reply #2 on: May 08, 2025, 09:17:11 pm »
I think this could be applied somewhere in high performance places - the point is that no memory manager is accessed

For example, if a large number of objects are created and destroyed many times, this could speed things up...

but then again, if it works at all, I'm not sure yet  :D
I may seem rude - please don't take it personally

egsuh

  • Hero Member
  • *****
  • Posts: 1752
Re: Placing an instance of a class on the stack or in any memory area
« Reply #3 on: May 09, 2025, 04:32:40 am »
AFAIK, Lazarus supports object, which is depricated in Delphi. It is managed within stack memory (again AFAIK).

Thaddy

  • Hero Member
  • *****
  • Posts: 18769
  • To Europe: simply sell USA bonds: dollar collapses
Re: Placing an instance of a class on the stack or in any memory area
« Reply #4 on: May 09, 2025, 11:06:43 am »
Yes, old school objects are stack oriented.. Normally classes are on the heap even if local to a procedure or function. After all classes are pointers.
Although it is possible to declare them on the stack provided you write a new root class that overrides newinstance. I gave a demo a couple of years ago somewhere on the forum. (I remember an erratic comment on it, you can ignore that)
It is based on this: http://www.atelierweb.com/index.php/64-bit-_alloca-how-to-use-from-delphi/ and combined with newinstance/initinstance.
Note you have to read the constraints I defined: it is not a fix all/do all solution and 64 bit only.
The alternative is using advanced records.
« Last Edit: May 09, 2025, 11:27:20 am by Thaddy »
If Europe sells their USA bonds the USD will collapse. Europe can affort that given average state debts. The USA can't affort that. Just an advice...

 

TinyPortal © 2005-2018