NewtGC.c

説明を見る。
00001 /*------------------------------------------------------------------------*/
00013 /* ヘッダファイル */
00014 #ifdef HAVE_MEMORY_H
00015     #include <memory.h>
00016 #else
00017     #include <string.h>
00018 #endif
00019 
00020 
00021 #include "NewtGC.h"
00022 #include "NewtObj.h"
00023 #include "NewtMem.h"
00024 #include "NewtEnv.h"
00025 #include "NewtVM.h"
00026 #include "NewtIO.h"
00027 #include "NewtPrint.h"
00028 
00029 
00030 /* 関数プロトタイプ */
00031 static void     NewtPoolSnap(const char * title, newtPool pool, int32_t usesize);
00032 
00033 static void     NewtObjChain(newtObjRef * objp, newtObjRef obj);
00034 static void     NewtPoolChain(newtPool pool, newtObjRef obj, bool literal);
00035 static void     NewtObjFree(newtPool pool, newtObjRef obj);
00036 static void     NewtObjChainFree(newtPool pool, newtObjRef * objp);
00037 
00038 #if 0
00039 static void     NewtPoolMarkClean(newtPool pool);
00040 #endif
00041 
00042 static void     NewtPoolSweep(newtPool pool, bool mark);
00043 
00044 static void     NewtGCRefMark(newtRefArg r, bool mark);
00045 static void     NewtGCRegMark(vm_reg_t * reg, bool mark);
00046 static void     NewtGCStackMark(vm_env_t * env, bool mark);
00047 static void     NewtGCMark(vm_env_t * env, bool mark);
00048 
00049 
00050 #pragma mark -
00051 /*------------------------------------------------------------------------*/
00061 void NewtPoolSnap(const char * title, newtPool pool, int32_t usesize)
00062 {
00063     NewtDebugMsg(title, "mem = %d(%d)n", pool->usesize, pool->usesize - usesize);
00064 }
00065 
00066 
00067 #pragma mark -
00068 /*------------------------------------------------------------------------*/
00079 void NewtObjChain(newtObjRef * objp, newtObjRef obj)
00080 {
00081     if (*objp == NULL)
00082     {
00083         *objp = obj;
00084     }
00085     else
00086     {
00087         obj->header.nextp = *objp;
00088         *objp = obj;
00089     }
00090 }
00091 
00092 
00093 /*------------------------------------------------------------------------*/
00103 void NewtPoolChain(newtPool pool, newtObjRef obj, bool literal)
00104 {
00105     if (obj != NULL && pool != NULL)
00106     {
00107         if (literal)
00108             NewtObjChain(&pool->literal, obj);
00109         else
00110             NewtObjChain(&pool->obj, obj);
00111     }
00112 }
00113 
00114 
00115 /*------------------------------------------------------------------------*/
00124 void NewtCheckGC(newtPool pool, size_t size)
00125 {
00126     if (pool->maxspace < pool->usesize + size)
00127     {
00128         NEWT_NEEDGC = true;
00129     }
00130 }
00131 
00132 
00133 /*------------------------------------------------------------------------*/
00143 newtObjRef NewtObjChainAlloc(newtPool pool, size_t size, size_t dataSize)
00144 {
00145     newtObjRef  obj;
00146 
00147     NewtCheckGC(pool, size + dataSize);
00148 
00149     obj = (newtObjRef)NewtMemAlloc(pool, size);
00150     if (obj == NULL) return NULL;
00151 
00152     memset(&obj->header, 0, sizeof(obj->header));
00153 
00154     if (0 < dataSize)
00155     {
00156         uint8_t *   data;
00157     
00158         data = NewtMemAlloc(pool, dataSize);
00159     
00160         if (data == NULL)
00161         {
00162             NewtMemFree(obj);
00163             return NULL;
00164         }
00165 
00166         *((uint8_t **)(obj + 1)) = data;
00167     }
00168     else
00169     {
00170         obj->header.h = kNewtObjLiteral;
00171     }
00172 
00173     if (pool != NULL)
00174     {
00175         NewtPoolChain(pool, obj, dataSize == 0);
00176         pool->usesize += size + dataSize;
00177     }
00178 
00179     return obj;
00180 }
00181 
00182 
00183 #pragma mark -
00184 /*------------------------------------------------------------------------*/
00193 void NewtObjFree(newtPool pool, newtObjRef obj)
00194 {
00195     uint32_t    datasize;
00196 
00197     if (NewtObjIsLiteral(obj))
00198     {
00199         datasize = NewtAlign(sizeof(newtObj) + NewtObjSize(obj), 4);
00200     }
00201     else
00202     {
00203         datasize = sizeof(newtObj) + sizeof(uint8_t *);
00204         datasize += NewtObjCalcDataSize(NewtObjSize(obj));
00205 
00206         NewtMemFree(NewtObjData(obj));
00207     }
00208 
00209     NewtMemFree(obj);
00210 
00211     if (pool != NULL)
00212         pool->usesize -= datasize;
00213 }
00214 
00215 
00216 /*------------------------------------------------------------------------*/
00225 void NewtObjChainFree(newtPool pool, newtObjRef * objp)
00226 {
00227     newtObjRef  nextp;
00228     newtObjRef  obj;
00229 
00230     for (obj = *objp; obj != NULL; obj = nextp)
00231     {
00232         nextp = obj->header.nextp;
00233         NewtObjFree(pool, obj);
00234     }
00235 
00236     *objp = NULL;
00237 }
00238 
00239 
00240 /*------------------------------------------------------------------------*/
00248 void NewtPoolRelease(newtPool pool)
00249 {
00250     if (pool != NULL)
00251     {
00252         int32_t     usesize;
00253 
00254         usesize = pool->usesize;
00255 
00256         NewtObjChainFree(pool, &pool->obj);
00257         NewtObjChainFree(pool, &pool->literal);
00258 
00259         if (NEWT_DEBUG)
00260             NewtPoolSnap("RELEASE", pool, usesize);
00261     }
00262 }
00263 
00264 
00265 #pragma mark -
00266 #if 0
00267 /*------------------------------------------------------------------------*/
00275 void NewtPoolMarkClean(newtPool pool)
00276 {
00277     if (pool != NULL)
00278     {
00279         newtObjRef  nextp;
00280         newtObjRef  obj;
00281         newtObjRef *    prevp = &pool->obj;
00282         int32_t     usesize;
00283 
00284         usesize = pool->usesize;
00285 
00286         for (obj = pool->obj; obj != NULL; obj = nextp)
00287         {
00288             nextp = obj->header.nextp;
00289 
00290             if (NewtObjIsLiteral(obj))
00291             {
00292                 NewtObjChain(&pool->literal, obj);
00293                 *prevp = nextp;
00294 
00295                 continue;
00296             }
00297 
00298             obj->header.h &=  (uint32_t)kNewtObjSweep;
00299             prevp = &obj->header.nextp;
00300         }
00301     }
00302 }
00303 
00304 #endif
00305 
00306 /*------------------------------------------------------------------------*/
00315 void NewtPoolSweep(newtPool pool, bool mark)
00316 {
00317     if (pool != NULL)
00318     {
00319         newtObjRef  nextp;
00320         newtObjRef  obj;
00321         newtObjRef *    prevp = &pool->obj;
00322         int32_t     usesize;
00323 
00324         usesize = pool->usesize;
00325 
00326         for (obj = pool->obj; obj != NULL; obj = nextp)
00327         {
00328             nextp = obj->header.nextp;
00329 
00330             if (NewtObjIsLiteral(obj))
00331             {
00332                 NewtObjChain(&pool->literal, obj);
00333                 *prevp = nextp;
00334 
00335                 continue;
00336             }
00337 
00338             if (NewtObjIsSweep(obj, mark))
00339             {
00340                 *prevp = nextp;
00341                 NewtObjFree(pool, obj);
00342 
00343                 continue;
00344             }
00345 
00346             prevp = &obj->header.nextp;
00347         }
00348 
00349         if (NEWT_DEBUG)
00350             NewtPoolSnap("GC", pool, usesize);
00351     }
00352 
00353     if (pool->maxspace < pool->usesize)
00354     {
00355         pool->maxspace = ((pool->usesize + pool->expandspace - 1) / pool->expandspace)
00356                             * pool->expandspace;
00357     }
00358 }
00359 
00360 
00361 /*------------------------------------------------------------------------*/
00370 void NewtGCRefMark(newtRefArg r, bool mark)
00371 {
00372     if (NewtRefIsPointer(r))
00373     {
00374         newtObjRef  obj;
00375     
00376         obj = NewtRefToPointer(r);
00377     
00378         if (! NewtObjIsLiteral(obj) && NewtObjIsSweep(obj, mark))
00379         {
00380             if (mark)
00381                 obj->header.h &=  (uint32_t)kNewtObjSweep;
00382             else
00383                 obj->header.h |= kNewtObjSweep;
00384 
00385             if (NewtObjIsSlotted(obj))
00386             {
00387                 newtRef *   slots;
00388                 uint32_t    len;
00389                 uint32_t    i;
00390     
00391                 len = NewtObjSlotsLength(obj);
00392                 slots = NewtObjToSlots(obj);
00393     
00394                 for (i = 0; i < len; i++)
00395                 {
00396                     NewtGCRefMark(slots[i], mark);
00397                 }
00398             }
00399     
00400             if (NewtObjIsFrame(obj))
00401                 NewtGCRefMark(obj->as.map, mark);
00402         }
00403     }
00404 }
00405 
00406 
00407 /*------------------------------------------------------------------------*/
00416 void NewtGCRegMark(vm_reg_t * reg, bool mark)
00417 {
00418     NewtGCRefMark(reg->func, mark);
00419     NewtGCRefMark(reg->locals, mark);
00420     NewtGCRefMark(reg->rcvr, mark);
00421     NewtGCRefMark(reg->impl, mark);
00422 }
00423 
00424 
00425 /*------------------------------------------------------------------------*/
00434 void NewtGCStackMark(vm_env_t * env, bool mark)
00435 {
00436     newtRef *   stack;
00437     vm_reg_t *  callstack;
00438     uint32_t    i;
00439 
00440     // スタック
00441     stack = (newtRef *)env->stack.stackp;
00442 
00443     for (i = 0; i < env->reg.sp; i++)
00444     {
00445         NewtGCRefMark(stack[i], mark);
00446     }
00447 
00448     // 関数呼出しスタック
00449     callstack = (vm_reg_t *)env->callstack.stackp;
00450 
00451     for (i = 0; i < env->callstack.sp; i++)
00452     {
00453         NewtGCRegMark(&callstack[i], mark);
00454     }
00455 
00456     // 例外ハンドラ・スタック
00457     NewtGCRefMark(env->currexcp, mark);
00458 
00459 /*
00460     {
00461         vm_excp_t * excpstack;
00462         vm_excp_t * excp;
00463 
00464         excpstack = (vm_excp_t *)env->excpstack.stackp;
00465 
00466         for (i = 0; i < env->excpsp; i++)
00467         {
00468             excp = &excpstack[i];
00469             NewtGCRefMark(excp->sym, mark);
00470         }
00471     }
00472 */
00473 }
00474 
00475 
00476 /*------------------------------------------------------------------------*/
00485 void NewtGCMark(vm_env_t * env, bool mark)
00486 {
00487     NewtGCRefMark(NcGetRoot(), mark);
00488 //    NewtGCRefMark(NSGetGlobals(), mark);
00489 //    NewtGCRefMark(NSGetGlobalFns(), mark);
00490 //    NewtGCRefMark(NSGetMagicPointers(), mark);
00491 
00492     // レジスタ
00493     NewtGCRegMark(&env->reg, mark);
00494 
00495     // スタック
00496     NewtGCStackMark(env, mark);
00497 }
00498 
00499 
00500 /*------------------------------------------------------------------------*/
00506 void NewtGC(void)
00507 {
00508 //    NewtPoolMarkClean(NEWT_POOL);
00509     NewtGCMark(&vm_env, NEWT_SWEEP);
00510     NewtPoolSweep(NEWT_POOL, NEWT_SWEEP);
00511 
00512     NEWT_SWEEP = ! NEWT_SWEEP;
00513     NEWT_NEEDGC = false;
00514 }
00515 
00516 
00517 #pragma mark -
00518 /*------------------------------------------------------------------------*/
00528 newtRef NsGC(newtRefArg rcvr)
00529 {
00530     NEWT_NEEDGC = true;
00531     return kNewtRefNIL;
00532 }
00533 

NEWT/0に対してThu Nov 23 16:50:43 2006に生成されました。  doxygen 1.5.0