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

Last change on this file since 373 was 373, checked in by dai, 16 years ago

Try-Catchを試験的に実装。
(まだ下記の動作しか実装していません)
・Try
・Catch(パラメータ無し)
・Throw(パラメータ無し)

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