20,741
edits
| Line 244: | Line 244: | ||
* void naiGCMark(naRef r); | * void naiGCMark(naRef r); | ||
* void naiGCMarkHash(naRef h); | * void naiGCMarkHash(naRef h); | ||
== The pool manager == | |||
All high level type allocators (naNewString, naNewVector, naNewHash etc) make use of the naNew() call introduced earlier. | |||
naNew() doesn't directly allocate new memory from the heap, but instead use the naGC_get() helper which manages memory from the global pools. | |||
The interesting part is the naGC_get() function which isn't directly mapped to naAlloc() or malloc(), but instead manages the Nasal memory pools. | |||
For each native Nasal data type (scalars, vectors, hashes, funcs etc) , there are separate memory pools in globals->pools[n]. The index (n) is one of T_VEC, T_HASH, T_FUNC etc. | |||
The naGC_get() pool "manager" is located in gc.nas line 194: https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/gc.c#line194 | |||
<syntaxhighlight lang="C"> | |||
struct naObj** naGC_get(struct naPool* p, int n, int* nout) | |||
{ | |||
struct naObj** result; | |||
naCheckBottleneck(); | |||
LOCK(); | |||
while(globals->allocCount < 0 || (p->nfree == 0 && p->freetop >= p->freesz)) { | |||
globals->needGC = 1; | |||
bottleneck(); | |||
} | |||
if(p->nfree == 0) | |||
newBlock(p, poolsize(p)/8); | |||
n = p->nfree < n ? p->nfree : n; | |||
*nout = n; | |||
p->nfree -= n; | |||
globals->allocCount -= n; | |||
result = (struct naObj**)(p->free + p->nfree); | |||
UNLOCK(); | |||
return result; | |||
} | |||
</syntaxhighlight> | |||
As can be seen, the garbage collector itself is triggered by setting the global "needGC" flag to 1 in the globals structure and then calling the bottleneck() function: [https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/gc.c#line199]. | |||
In line 209, the memory region from the global pool is cast back to a pointer (struct naObj**): https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/gc.c#line209 | |||
the "nout" paramter is just there to update c->nfree[type] with the amount of free memory. | |||
= bottleneck() = | = bottleneck() = | ||