Memory Usage - KidneyThief/TinScript1.0 GitHub Wiki

Memory usage in TinScript is designed to be both controlled externally, and as static as possible, in several ways:

Table of Contents

TinAlloc()

  • All allocations within TinScript use the above macro, defined in integration.h.
    • By default, this is simply a wrapper to new()
    • The first argument to TinAlloc() is one of the types, defined in the AllocTypeTuple, allowing you to choose the source of the allocation (heap, mempool, SBA, whatever...)
    • Examples are:
      • ALLOC_TreeNode used when parsing - perhaps a temporary heap is suitable.
      • ALLOC_VarTable a variable dictionary - fixed size, so either a heap or mempool.
      • ALLOC_CodeBlock' a variable size, and not temporary, so it's own heap might be preferred.
      • ALLOC_ObjEntry object entry - likely to be many, so a memory pool?

Function Registration

Every registered function or method instantiates a registration object.

  • These are templated, so the number and types of arguments mean there are varying sized objects.
  • They're declared statically, so they are created before execution, and live in static memory forever.

Hash Tables

Every CHashTable<> has two attributes to help control memory usage:

  • They are all implemented as a fixed size array of linked lists.
    • The trade off being, more collisions, but the tables themselves never grow, regardless of how many items are added.
    • Constants are declared at the top of TinScript.h (e.g. kLocalVarTableSize) so a balance between collisions and fixed size arrays can be tuned for your solution.
  • Second, All hash tables are tables of pointers only.
    • Every CHashTableEntry is a fixed size class containing a pointer, a hash value, and linked list members.
    • This means, you could if you choose, have one large pool of entries to be shared between all hash tables, regardless of type.

Memory Map

Below is a memory map of TinScript, beginning with the (self contained) CScriptContext.

  • The only variable sized elements of TinScript are the code blocks, as the byte code generated from compiling a script cannot be pre-determined.
  • Everything else is simply the number of a fixed size object... CVariableEntry, CFunctionEntry...
  • As mentioned above, the dictionaries are fixed size (with best guess initial but tunable sizes).
  • (Of course, this doesn't include the number of objects created or registered.)

Approximate Footprint

The current sizes of the most used classes are:

  • CScriptContext: ~65Kb (most of which is scratch buffers used for type conversions)
  • CStringTable: 32Kb (the single buffer storing all strings)
  • CObjectEntry: 36b
  • CNamespace: 40b
  • CVariableEntry: 300b (most of which is the char[256] name)
  • CFunctionEntry: 372b (most of which is the char[256] name), with 8x
Some napkin math:
  • If you used TinScript with, say, 200 namespaces, 10000 objects, and 2000 functions, 2000 dynamic variables, the approximate footprint would be somewhere in the neighborhood of 1.4Mb.
  • From the FLTK Demo, the compiled (in memory) size of the 500 line script file "asteroids.ts" is approximately 14Kb.
⚠️ **GitHub.com Fallback** ⚠️