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

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

GCにてヒープ領域判定処理を追加。更に高速化した。

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