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

Last change on this file since 361 was 361, checked in by dai, 18 years ago

GCが管理するメモリバッファの先頭部分にメモリオブジェクトへのインデックスを格納するようにした。
オブジェクトからインターフェイスへのキャスト時に必要なだけメモリが確保できていないバグを修正。

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