|
|
| Line 228: |
Line 228: |
| * void naiGCMark(naRef r); | | * void naiGCMark(naRef r); |
| * void naiGCMarkHash(naRef h); | | * void naiGCMarkHash(naRef h); |
|
| |
| = naNew() =
| |
|
| |
| As can be seen, the key allocator function is [https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/misc.c#line66 naNew()]. naNew() is really just a fancy malloc() replacement, i.e. it's just getting passed the Nasal execution context, and the nasal type (which is mapped to the size of the requested memory region using naTypeSize()).
| |
|
| |
| The naNew() function is also implemented in misc.c, see [https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/misc.c#line122 line 66]:
| |
|
| |
| <syntaxhighlight lang="C">
| |
| naRef naNew(struct Context* c, int type)
| |
| {
| |
| naRef result;
| |
| if(c->nfree[type] == 0)
| |
| c->free[type] = naGC_get(&globals->pools[type],
| |
| OBJ_CACHE_SZ, &c->nfree[type]);
| |
| result = naObj(type, c->free[type][--c->nfree[type]]);
| |
| naTempSave(c, result);
| |
| return result;
| |
| }
| |
| </syntaxhighlight>
| |
|
| |
| First, the conditional checks if there's any free memory in the Nasal storage pools for the requested Nasal data type, if there isn't any free memory left, new memory is assigned to the contexts->free[type] pool via naGC_get().
| |
|
| |
| For the time being, OBJ_CACHE_SZ can be ignored, it's defined in code.h, line 12: https://gitorious.org/fg/simgear/blobs/next/simgear/nasal/code.h#line12
| |
| <syntaxhighlight lang="C">
| |
| // Number of objects (per pool per thread) asked for using naGC_get().
| |
| // The idea is that contexts can "cache" allocations to prevent thread
| |
| // contention on the global pools. But in practice this interacts
| |
| // very badly with small subcontext calls, which grab huge numbers of
| |
| // cached objects and don't use them, causing far more collections
| |
| // than necessary. Just leave it at 1 pending a rework of the
| |
| // collector synchronization.
| |
| #define OBJ_CACHE_SZ 1
| |
| </syntaxhighlight>
| |
|
| |
| The final argument to the naGC_get() function is a pointer to to the context's nfree[type] member which is updated by the function.
| |
|
| |
| Next, a new naRef structure is set up using the allocated naObj memory and the type info:
| |
|
| |
| <syntaxhighlight lang="C">
| |
| result = naObj(type, c->free[type][--c->nfree[type]]);
| |
| </syntaxhighlight>
| |
|
| |
|
| |
| <syntaxhighlight lang="C">
| |
| naRef naObj(int type, struct naObj* o)
| |
| {
| |
| naRef r;
| |
| SETPTR(r, o);
| |
| o->type = type;
| |
| return r;
| |
| }
| |
| </syntaxhighlight>
| |
|
| |
|
| = bottleneck() = | | = bottleneck() = |