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

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

api_commctrl.sbp、api_winsock2.sbpを標準ライブラリ内で取り込むようにした。
gc.sbp内のコードにコメントをつけた

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