source: trunk/Include/system/gc.sbp@ 362

Last change on this file since 362 was 362, checked in by dai, 17 years ago

GCの初期値をメソッド経由で指定するように変更。

File size: 19.3 KB
RevLine 
[360]1/*!
2 @brief このファイルでは、ABのガベージコレクションの実装を行います。
[109]3*/
[1]4
[109]5
[1]6/*
7※これらの変数はコンパイラが自動的に定義します。
8Dim _System_gc_StackRoot_StartPtr As VoidPtr
9*/
10
11Function _System_GetSp() As LONG_PTR 'dummy
12End Function
13
14
15Const _System_GC_FLAG_ATOMIC = 1
16Const _System_GC_FLAG_NEEDFREE = 2
17Const _System_GC_FLAG_INITZERO = 4
[144]18Const _System_GC_FLAG_OBJECT = 8
[1]19
[214]20Type _System_GlobalRoot
21 ptr As *LONG_PTR
22 count As Long
23End Type
24
[361]25Type _System_MemoryObject
26 ptr As VoidPtr
27 size As Long
28 flags As DWord
29 generationCount As Long
30End Type
31
[1]32Class _System_CGarbageCollection
[266]33
[361]34 pMemoryObjects As *_System_MemoryObject ' メモリオブジェクト
35 countOfMemoryObjects As Long ' 管理するメモリオブジェクトの個数
[1]36
37 iAllSize As SIZE_T
38
[360]39 isSweeping As Boolean ' スウィープ中かどうか
[144]40
[360]41 ' クリティカルセクション
[1]42 CriticalSection As CRITICAL_SECTION
43
[214]44 ' メモリの上限値(この値を超えるとGCが発動します)
45 limitMemorySize As LONG_PTR ' バイト単位
46 limitMemoryObjectNum As Long ' メモリオブジェクトの個数単位
[109]47
[360]48 isFinish As Boolean ' GC管理が終了したかどうか
[144]49
50
[214]51 ' Global Root
52 pGlobalRoots As *_System_GlobalRoot
53 globalRootNum As Long
54 Sub AddGlobalRootPtr( ptr As *LONG_PTR, count As Long )
55 pGlobalRoots = _System_realloc( pGlobalRoots, (globalRootNum + 1) * SizeOf(_System_GlobalRoot) )
56 pGlobalRoots[globalRootNum].ptr = ptr
57 pGlobalRoots[globalRootNum].count = count
58 globalRootNum++
59 End Sub
60
61 Sub RegisterGlobalRoots()
62 ' このメソッドの実装はコンパイラが自動生成する
63
64 ' AddGlobalRootPtr(...)
65 ' ...
66 End Sub
67
[144]68 ' 特殊クラスのため、コンストラクタ・デストラクタは呼ばれません
[1]69 Sub _System_CGarbageCollection()
[144]70 End Sub
71 Sub ~_System_CGarbageCollection()
72 End Sub
73
[214]74Public
75
[360]76 /*!
77 @brief 環境変数にGCを登録する
78 @author Daisuke Yamamoto
79 @date 2007/10/21
80 */
[266]81 Static Sub Initialize()
82 Dim temporary[255] As Char
83 If GetEnvironmentVariable( "ActiveBasicGarbageCollection", temporary, 255 ) Then
84 ' 既にGCがプロセスに存在するとき
85 sscanf( temporary, "%08x", VarPtr( _System_pGC ) )
86 MessageBox(0,temporary,"GetEnvironmentVariable",0)
87 Else
88 _System_pGC = _System_calloc( SizeOf( _System_CGarbageCollection ) )
89 _System_pGC->Begin()
90
91 ' GCをプロセスに登録する
92 sprintf( temporary, "%08x", _System_pGC )
93 SetEnvironmentVariable( "ActiveBasicGarbageCollection", temporary )
94 End If
95 End Sub
96
[360]97 /*!
98 @brief メモリサイズの上限を指定する
99 @param limitMemorySize メモリサイズの上限(単位はバイト)
100 limitMemoryObjectNum メモリ個数の上限
101 @author Daisuke Yamamoto
102 @date 2007/10/21
103 */
104 Sub SetLimit( limitMemorySize As LONG_PTR, limitMemoryObjectNum As Long )
105 This.limitMemorySize = limitMemorySize
106 This.limitMemoryObjectNum = limitMemoryObjectNum
107 End Sub
108
109 /*!
110 @brief 初期化
111 @author Daisuke Yamamoto
112 @date 2007/10/21
113 */
[144]114 Sub Begin()
[361]115 If pMemoryObjects Then Exit Sub
[1]116
[144]117 isFinish = False
118
119 'メモリの上限値(この値を超えるとGCが発動します)
[362]120 SetLimit(
121 1024*1024, ' バイト単位
122 2000 ' メモリオブジェクトの個数単位
123 )
[144]124
[361]125 pMemoryObjects = _System_calloc( 1 )
126 countOfMemoryObjects=0
[1]127
[214]128 ' Global Root
129 pGlobalRoots = _System_calloc( 1 )
130 globalRootNum = 0
131 RegisterGlobalRoots()
132
[1]133 iAllSize=0
134
[144]135 ' スウィープ中かどうか
136 isSweeping = False
[1]137
138 'クリティカルセッションを生成
139 InitializeCriticalSection(CriticalSection)
140
[18]141
142 '---------------------------
143 ' 開始時のスレッドを通知
144 '---------------------------
[1]145 Dim hTargetThread As HANDLE
146 DuplicateHandle(GetCurrentProcess(),
147 GetCurrentThread(),
148 GetCurrentProcess(),
149 hTargetThread, 0, FALSE, DUPLICATE_SAME_ACCESS) 'カレントスレッドのハンドルを複製
[18]150
[144]151 ' スレッド管理用オブジェクトを生成
152 _System_pobj_AllThreads = New _System_CThreadCollection()
[18]153
[144]154 ' 自身のThreadオブジェクトを生成
155 Dim thread As Thread(hTargetThread,GetCurrentThreadId(),0)
[330]156 thread.Name = "main"
[18]157
[232]158 _System_pobj_AllThreads->BeginThread(ObjPtr( thread ),_System_gc_StackRoot_StartPtr As *LONG_PTR)
[144]159
[1]160 End Sub
[360]161
162 /*!
163 @brief 終了処理
164 @author Daisuke Yamamoto
165 @date 2007/10/21
166 */
[144]167 Sub Finish()
[361]168 If pMemoryObjects = NULL Then Exit Sub
[1]169
[144]170 isFinish = True
[79]171
[144]172 ' スレッド管理用オブジェクトを破棄
173 Delete _System_pobj_AllThreads
[1]174
[144]175 ' 自分以外のスレッドを一時停止
176 '_System_pobj_AllThreads->SuspendAnotherThread()
177
[259]178 _System_DebugOnly_OutputDebugString( Ex"garbage colletion sweeping all memory objects!\r\n" )
[144]179 DeleteAllGarbageMemories()
180
181 ' 未解放のメモリオブジェクトをトレース
182 DumpMemoryLeaks()
183
184 ' 自分以外のスレッドを再開
185 '_System_pobj_AllThreads->ResumeAnotherThread()
186
[361]187 _System_free( pMemoryObjects )
188 pMemoryObjects = NULL
[1]189
[214]190 _System_free( pGlobalRoots )
191 pGlobalRoots = NULL
192
[1]193 'クリティカルセッションを破棄
194 DeleteCriticalSection(CriticalSection)
[144]195
[79]196 End Sub
[1]197
[360]198 /*!
[361]199 @brief メモリオブジェクトからインデックスを取得する
200 @param new_ptr メモリオブジェクトへのポインタ
201 @author Daisuke Yamamoto
202 @date 2007/10/21
203 */
204 Function GetMemoryObjectPtr( ptr As VoidPtr ) As *_System_MemoryObject
205 ' メモリオブジェクトの先頭部分からインデックスを取得する
206 Dim index = Get_LONG_PTR( ptr - SizeOf(LONG_PTR) ) As Long
207
208 If pMemoryObjects[index].ptr <> ptr Then
209 ' メモリイメージが壊れている(先頭に存在するインデックスの整合性が取れない)
210 Dim temporary[1024] As Char
211 wsprintf( temporary, Ex"indexOfMemoryObjects: %d\r\npMemoryObjects[index].ptr: &H%08x\r\nptr: &H%08x\r\n",
212 index,
213 pMemoryObjects[index].ptr,
214 ptr )
215 _System_DebugOnly_OutputDebugString( temporary )
216 debug
217 End If
218
219 Return VarPtr( pMemoryObjects[index] )
220 End Function
221
222 /*!
[360]223 @brief メモリオブジェクトを追加する
224 @param new_ptr メモリオブジェクトへのポインタ
225 size メモリオブジェクトのサイズ
226 flags メモリオブジェクトの属性
227 @author Daisuke Yamamoto
228 @date 2007/10/21
229 */
[170]230 Sub add(new_ptr As VoidPtr, size As SIZE_T, flags As DWord)
[144]231 EnterCriticalSection(CriticalSection)
[361]232 iAllSize+=size
[1]233
[361]234 ' メモリオブジェクトインスタンスの先頭にインデックスをセットする
235 Set_LONG_PTR( new_ptr - SizeOf( LONG_PTR ), countOfMemoryObjects )
[1]236
[361]237 pMemoryObjects = _System_realloc( pMemoryObjects, (countOfMemoryObjects+1)*SizeOf(_System_MemoryObject) )
238 pMemoryObjects[countOfMemoryObjects].ptr = new_ptr
239 pMemoryObjects[countOfMemoryObjects].size = size
240 pMemoryObjects[countOfMemoryObjects].flags = flags
241 pMemoryObjects[countOfMemoryObjects].generationCount = 0
[360]242
[361]243 countOfMemoryObjects++
[144]244 LeaveCriticalSection(CriticalSection)
[1]245
[330]246 /*
247 ' デバッグ用
[361]248 If countOfMemoryObjects = 1996 Then
[330]249 debug
250 End If
251 */
[1]252 End Sub
253
254
[360]255 /*!
256 @brief メモリオブジェクトを確保する
257 @param size メモリオブジェクトのサイズ
258 flags メモリオブジェクトの属性
259 @author Daisuke Yamamoto
260 @date 2007/10/21
261 */
[1]262 Function __malloc(size As SIZE_T,flags As Byte) As VoidPtr
[361]263 Dim dwFlags As DWord
264 If flags and _System_GC_FLAG_INITZERO Then
265 dwFlags=HEAP_ZERO_MEMORY
266 Else
267 dwFlags=0
268 End If
[1]269
[361]270 ' 実際のメモリバッファはインデックスの分だけ多めに確保する
271 Dim ptr = HeapAlloc( _System_hProcessHeap, dwFlags, size + SizeOf( LONG_PTR ) ) + SizeOf( LONG_PTR )
[1]272
[361]273 ' 管理対象のメモリオブジェクトとして追加
274 add( ptr, size, flags )
275
[144]276 Return ptr
[1]277 End Function
278
[360]279 /*!
280 @brief メモリオブジェクトを再確保する
281 @param lpMem メモリオブジェクトへのポインタ
282 size メモリオブジェクトのサイズ
283 flags メモリオブジェクトの属性
284 @author Daisuke Yamamoto
285 @date 2007/10/21
286 */
[1]287 Function __realloc(lpMem As VoidPtr, size As SIZE_T) As VoidPtr
[18]288 EnterCriticalSection(CriticalSection)
[1]289
[361]290 ' メモリオブジェクトを取得
291 Dim pTempMemoryObject = GetMemoryObjectPtr( lpMem )
[18]292
[361]293 iAllSize += size - pTempMemoryObject->size
294
295 pTempMemoryObject->size = size
296 pTempMemoryObject->ptr = HeapReAlloc( _System_hProcessHeap, HEAP_ZERO_MEMORY, pTempMemoryObject->ptr - SizeOf(LONG_PTR), size + SizeOf(LONG_PTR) ) + SizeOf(LONG_PTR)
297
[18]298 LeaveCriticalSection(CriticalSection)
[361]299 Return pTempMemoryObject->ptr
[1]300 End Function
301
[360]302 /*!
303 @brief メモリオブジェクトを解放する
304 @param lpMem メモリオブジェクトへのポインタ
305 isSweeping スウィープ中にこのメソッドが呼ばれるときはTrue、それ以外はFalse
306 @author Daisuke Yamamoto
307 @date 2007/10/21
308 */
[144]309 Sub __free_ex(lpMem As VoidPtr, isSweeping As Boolean)
[18]310 EnterCriticalSection(CriticalSection)
[1]311
[361]312 ' メモリオブジェクトを取得
313 Dim pTempMemoryObject = GetMemoryObjectPtr( lpMem )
314
315 If (pTempMemoryObject->flags and _System_GC_FLAG_NEEDFREE)<>0 or isSweeping Then
316 iAllSize -= pTempMemoryObject->size
317
318 HeapFree( _System_hProcessHeap, 0, pTempMemoryObject->ptr - SizeOf(LONG_PTR) )
319 pTempMemoryObject->ptr = NULL
320 pTempMemoryObject->size = 0
321 Else
322 If isFinish = False Then
323 _System_DebugOnly_OutputDebugString( Ex"heap free missing!\r\n" )
[1]324 End If
[361]325 End If
[18]326 LeaveCriticalSection(CriticalSection)
[1]327 End Sub
328
[360]329 /*!
330 @brief メモリオブジェクトを解放する
331 @param lpMem メモリオブジェクトへのポインタ
332 @author Daisuke Yamamoto
333 @date 2007/10/21
334 */
[144]335 Sub __free(lpMem As VoidPtr)
336 __free_ex( lpMem, False )
337 End Sub
338
[360]339 /*!
340 @brief スウィープする
341 @author Daisuke Yamamoto
342 @date 2007/10/21
343 */
[1]344 Sub sweep()
[361]345 If isSweeping <> False or (iAllSize<limitMemorySize and countOfMemoryObjects<limitMemoryObjectNum) Then
[171]346 'メモリ使用量が上限値を超えていないとき
347 Exit Sub
348 End If
[144]349
[171]350 Dim hThread As HANDLE
351 Dim ThreadId As DWord
352 hThread=_beginthreadex(NULL,0,AddressOf(SweepOnOtherThread),VarPtr(This),0,ThreadId)
353 WaitForSingleObject(hThread,INFINITE)
354 CloseHandle(hThread)
[202]355 isSweeping = False
[1]356 End Sub
357
[144]358Private
[1]359
[214]360 Static Function IsNull( object As Object ) As Boolean
[237]361 Return Object.ReferenceEquals(object, Nothing)
[214]362 End Function
363
[360]364 /*!
365 @brief メモリオブジェクトの生存検地
366 @param pSample メモリオブジェクトへのポインタ
367 @author Daisuke Yamamoto
368 @date 2007/10/21
369 */
[144]370 Function HitTest(pSample As VoidPtr) As Long
371 Dim i As Long
[361]372 For i=0 To ELM(countOfMemoryObjects)
373 If (pMemoryObjects[i].ptr As LONG_PTR)<=(pSample As LONG_PTR) and (pSample As LONG_PTR)<((pMemoryObjects[i].ptr As LONG_PTR)+pMemoryObjects[i].size) Then
[144]374 Return i
375 End If
376 Next
377 Return -1
378 End Function
[1]379
[360]380 /*!
381 @brief オブジェクトのスキャン
382 @param pObject オブジェクトへのポインタ
383 pbMark マークリスト
384 @author Daisuke Yamamoto
385 @date 2007/10/21
386 */
[214]387 Function ScanObject(pObject As *Object, pbMark As *Byte) As Boolean
[275]388 Dim classTypeInfo = Nothing As ActiveBasic.Core._System_TypeForClass
389 classTypeInfo = pObject->GetType() As ActiveBasic.Core._System_TypeForClass
[214]390
391 If IsNull( classTypeInfo ) Then
392 Return False
393 End If
394
[330]395 /*
396 _System_DebugOnly_OutputDebugString( " (scanning object)" )
397 _System_DebugOnly_OutputDebugString( classTypeInfo.Name )
398 _System_DebugOnly_OutputDebugString( Ex"\r\n" )
399 */
400
[214]401 Dim i As Long
402 For i = 0 To ELM(classTypeInfo.numOfReference)
403 Scan( (pObject + classTypeInfo.referenceOffsets[i]) As *LONG_PTR, 1, pbMark )
404 Next
405
406 Return True
407 End Function
408
[360]409 /*!
410 @brief メモリオブジェクトのスキャン
411 @param pStartPtr メモリオブジェクトへのポインタ
412 maxNum スキャンするメモリオブジェクトの個数
413 pbMark マークリスト
414 @author Daisuke Yamamoto
415 @date 2007/10/21
416 */
[214]417 Sub Scan(pStartPtr As *LONG_PTR, maxNum As Long, pbMark As *Byte)
418 Dim i As Long, index As Long
419
420 For i=0 To ELM(maxNum)
[144]421 index=HitTest(pStartPtr[i] As VoidPtr)
422 If index<>-1 Then
423 If pbMark[index]=0 Then
424 pbMark[index]=1
[170]425
[361]426 ' ジェネレーションカウントを増やす
427 pMemoryObjects[index].generationCount ++
428
429 If pMemoryObjects[index].flags and _System_GC_FLAG_OBJECT Then
[214]430 ' オブジェクトの場合
[361]431 If ScanObject( (pMemoryObjects[index].ptr + 4*SizeOf(LONG_PTR)) As *Object, pbMark) = False Then
432 Dim maxNum = (pMemoryObjects[index].size\SizeOf(LONG_PTR)) As Long
433 Scan(pMemoryObjects[index].ptr As *LONG_PTR, maxNum, pbMark)
[214]434 End If
435
[361]436 ElseIf (pMemoryObjects[index].flags and _System_GC_FLAG_ATOMIC)=0 Then
[214]437 ' ヒープ領域がポインタ値を含む可能性があるとき
[361]438 If pMemoryObjects[index].ptr = NULL Then
[144]439 'エラー
[170]440
[144]441 End If
[214]442
[361]443 Dim maxNum = (pMemoryObjects[index].size\SizeOf(LONG_PTR)) As Long
444 Scan(pMemoryObjects[index].ptr As *LONG_PTR, maxNum, pbMark)
[144]445 End If
446 End If
447 End If
448 Next
449 End Sub
[1]450
[360]451 /*!
452 @brief グローバル領域をルートに指定してスキャン
453 @param pbMark マークリスト
454 @author Daisuke Yamamoto
455 @date 2007/10/21
456 */
457 Sub GlobalScan( pbMark As *Byte )
458 Dim i As Long
459 For i = 0 To ELM( globalRootNum )
460 Scan( pGlobalRoots[i].ptr, pGlobalRoots[i].count, pbMark )
461 Next
462 End Sub
463
464 /*!
465 @brief ローカル領域をルートに指定してスキャン
466 @param pbMark マークリスト
467 @author Daisuke Yamamoto
468 @date 2007/10/21
469 */
[144]470 Sub LocalScan( pbMark As *Byte )
[18]471 Dim Context As CONTEXT
[1]472 Dim NowSp As *LONG_PTR
473 Dim size As LONG_PTR
[18]474 Dim i As Long
475 For i=0 To ELM(_System_pobj_AllThreads->ThreadNum)
[330]476 Dim thread = _System_pobj_AllThreads->ppobj_Thread[i]
477 If thread Then
[1]478 FillMemory(VarPtr(Context),SizeOf(CONTEXT),0)
479 Context.ContextFlags=CONTEXT_CONTROL
[330]480 If thread->__GetContext(Context)=0 Then
[259]481 _System_DebugOnly_OutputDebugString(Ex"レジスタ情報の取得に失敗しました。\r\n")
[1]482 End If
483
484#ifdef _WIN64
485 NowSp=Context.Rsp As *LONG_PTR
486#else
487 NowSp=Context.Esp As *LONG_PTR
488#endif
489
[214]490 Dim size=(_System_pobj_AllThreads->pStackBase[i] As LONG_PTR)-(NowSp As LONG_PTR)
491 Dim maxNum = (size\SizeOf(LONG_PTR)) As Long
[1]492
[144]493 If NowSp = 0 Then
494 debug
495 Exit Sub
496 End If
497
[330]498 /*
499 _System_DebugOnly_OutputDebugString( "(scanning thread local)" )
500 _System_DebugOnly_OutputDebugString( thread.Name )
501 _System_DebugOnly_OutputDebugString( Ex"\r\n" )
502 */
503
[214]504 Scan( NowSp, maxNum, pbMark )
[1]505 End If
506 Next
[144]507 End Sub
[1]508
[360]509 /*!
510 @brief 生存していないメモリオブジェクトを解放する
511 @param pbMark マークリスト
512 @author Daisuke Yamamoto
513 @date 2007/10/21
514 */
[144]515 Sub DeleteGarbageMemories( pbMark As *Byte )
[1]516
[144]517 Dim isAllDelete = False
518 If pbMark = NULL Then
519 ' すべてを破棄するとき
520 isAllDelete = True
[361]521 pbMark = _System_calloc( countOfMemoryObjects )
[144]522 End If
[1]523
[144]524 Dim i As Long
[361]525 For i=0 To ELM(countOfMemoryObjects)
526 If pbMark[i]=0 and pMemoryObjects[i].ptr<>0 and (pMemoryObjects[i].flags and _System_GC_FLAG_NEEDFREE)=0 Then
527 If pMemoryObjects[i].ptr = NULL Then
[144]528 If isAllDelete Then
529 Continue
530 Else
531 debug
532 End If
533 End If
[1]534
[361]535 Dim ptr = pMemoryObjects[i].ptr
536 Dim size = pMemoryObjects[i].size
[144]537
[361]538 If (pMemoryObjects[i].flags and _System_GC_FLAG_OBJECT) <> 0 Then
[144]539 /* ・オブジェクトの個数
540 ・オブジェクトのサイズ
541 ・デストラクタの関数ポインタ
[249]542 ・リザーブ領域
[144]543 を考慮 */
[249]544 _System_SweepingDelete (ptr + SizeOf( LONG_PTR ) * 4 )
[144]545 Else
[361]546 __free_ex( ptr, True )
[144]547 End If
[1]548 End If
549 Next
550
[144]551 If isAllDelete Then
552 _System_free( pbMark )
553 End If
554
555 End Sub
556
[360]557 /*!
558 @brief GCが管理するすべてのメモリオブジェクトを解放する
559 @author Daisuke Yamamoto
560 @date 2007/10/21
561 */
[144]562 Sub DeleteAllGarbageMemories()
563 DeleteGarbageMemories( NULL )
564 End Sub
565
[360]566 /*!
567 @brief コンパクション
568 @author Daisuke Yamamoto
569 @date 2007/10/21
570 */
[144]571 Sub Compaction()
572 Dim i As Long, i2 = 0 As Long
[361]573 For i=0 To ELM(countOfMemoryObjects)
574 pMemoryObjects[i2] = pMemoryObjects[i]
[144]575
[361]576 If pMemoryObjects[i2].ptr Then
577 ' メモリオブジェクトの先頭部分にあるインデックスを書き換える
578 Set_LONG_PTR( pMemoryObjects[i2].ptr - SizeOf(LONG_PTR), i2 )
579
[144]580 i2++
581 End If
582 Next
[361]583 countOfMemoryObjects = i2
[144]584 End Sub
585
[360]586 /*!
587 @brief スウィープ(新規スレッドで呼び出す必要あり)
588 @author Daisuke Yamamoto
589 @date 2007/10/21
590 */
[284]591 Function SweepOnOtherThread() As Long
[171]592 EnterCriticalSection(CriticalSection)
[144]593
[214]594
595 Dim startTime = GetTickCount()
596
[259]597 _System_DebugOnly_OutputDebugString( Ex"garbage colletion sweep start!\r\n" )
[214]598
599
[361]600 If isSweeping <> False or (iAllSize<limitMemorySize and countOfMemoryObjects<limitMemoryObjectNum) Then
[202]601 ExitThread(0)
602 End If
[203]603 isSweeping = True
[202]604
[144]605 ' すべてのスレッドを一時停止
606 _System_pobj_AllThreads->SuspendAllThread()
607
608 ' マークリストを生成
[361]609 Dim pbMark = HeapAlloc(_System_hProcessHeap,HEAP_ZERO_MEMORY,countOfMemoryObjects*SizeOf(Byte)) As *Byte
[144]610
611 ' グローバル領域をルートに指定してスキャン
[360]612 GlobalScan( pbMark )
[144]613
614 ' ローカル領域をルートに指定してスキャン
615 LocalScan( pbMark )
616
617 ' スウィープ前のメモリサイズを退避
618 Dim iBackAllSize = iAllSize
619
620 ' スウィープ前のメモリオブジェクトの数
[361]621 Dim iBeforeN = countOfMemoryObjects
[144]622
623 '使われていないメモリを解放する
624 DeleteGarbageMemories(pbMark)
625
626 'コンパクション
627 Compaction()
628
[1]629 'マークリストを解放
630 HeapFree(_System_hProcessHeap,0,pbMark)
631
[299]632 If iBackAllSize <= iAllSize * 2 Then
[144]633 If iAllSize > limitMemorySize Then
634 limitMemorySize = iAllSize
635 End If
636
[1]637 '許容量を拡張する
[144]638 limitMemorySize *= 2
[214]639 limitMemoryObjectNum *= 2
[144]640
[259]641 _System_DebugOnly_OutputDebugString( Ex"memory size is extended for gc!\r\n" )
[1]642 End If
643
[144]644 Dim temp[100] As Char
[361]645 wsprintf(temp,Ex"object items ... %d -> %d ( %d MB -> %d MB )\r\n",iBeforeN,countOfMemoryObjects, iBackAllSize\1024\1024, iAllSize\1024\1024)
[259]646 _System_DebugOnly_OutputDebugString( temp )
[144]647 wsprintf(temp,Ex"limit size of memory ... %d\r\n",limitMemorySize)
[259]648 _System_DebugOnly_OutputDebugString( temp )
[214]649 wsprintf(temp,Ex"garbage colletion sweep finish! (%d ms)\r\n\r\n", GetTickCount()-startTime)
[259]650 _System_DebugOnly_OutputDebugString( temp )
[1]651
[144]652
[1]653 '-------------------------------------
654 ' すべてのスレッドを再開
655 '-------------------------------------
[18]656 _System_pobj_AllThreads->ResumeAllThread()
[171]657
658 LeaveCriticalSection(CriticalSection)
[1]659 End Function
660
[360]661 /*!
662 @brief 未解放のメモリオブジェクトをデバッグ出力する
663 @author Daisuke Yamamoto
664 @date 2007/10/21
665 */
[144]666 Sub DumpMemoryLeaks()
667 Dim isLeak = False
[1]668 Dim i As Long
[361]669 For i=0 To ELM(countOfMemoryObjects)
670 If pMemoryObjects[i].ptr Then
671 If (pMemoryObjects[i].flags and _System_GC_FLAG_NEEDFREE)<>0 Then
[144]672 If isLeak = False Then
[259]673 _System_DebugOnly_OutputDebugString( Ex"Detected memory leaks!\r\n" )
[144]674 isLeak = True
675 End If
[1]676
[144]677 Dim temp[100] As Char
[259]678 _System_DebugOnly_OutputDebugString( Ex"heap free missing!\r\n" )
[361]679 wsprintf(temp,Ex"{%d} normal block at &H%08X, %d bytes long.\r\n", i, pMemoryObjects[i].ptr, pMemoryObjects[i].size)
[259]680 _System_DebugOnly_OutputDebugString( temp )
[1]681 End If
682 End If
683 Next
[144]684
685 If isLeak Then
[259]686 _System_DebugOnly_OutputDebugString( Ex"Object dump complete.\r\n" )
[144]687 End If
[170]688
[1]689 End Sub
[144]690
[1]691End Class
692
693'GC管理用の特殊なシステムオブジェクト(デストラクタは最終のタイミングで呼び出されます)
[144]694Dim _System_pGC As *_System_CGarbageCollection
[1]695
696
697
698Function GC_malloc(size As Long) As VoidPtr
699 ' sweep
[144]700 _System_pGC->sweep()
[1]701
702 'allocate
[144]703 Return _System_pGC->__malloc(size,0)
[1]704End Function
705
706Function GC_malloc_atomic(size As Long) As VoidPtr
707 ' sweep
[144]708 _System_pGC->sweep()
[1]709
710 'allocate
[144]711 Return _System_pGC->__malloc(size,_System_GC_FLAG_ATOMIC)
[1]712End Function
[144]713
714Function _System_GC_malloc_ForObject(size As Long) As VoidPtr
715 ' sweep
716 _System_pGC->sweep()
717
718 'allocate
719 Return _System_pGC->__malloc(size,_System_GC_FLAG_OBJECT or _System_GC_FLAG_INITZERO)
720End Function
721
722Function _System_GC_malloc_ForObjectPtr(size As Long) As VoidPtr
723 ' sweep
724 _System_pGC->sweep()
725
726 'allocate
727 Return _System_pGC->__malloc(size,_System_GC_FLAG_OBJECT or _System_GC_FLAG_INITZERO or _System_GC_FLAG_NEEDFREE)
728End Function
729
730Function _System_GC_free_for_SweepingDelete( ptr As *Object )
731 ' free
732 _System_pGC->__free_ex( ptr, True )
733End Function
Note: See TracBrowser for help on using the repository browser.