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

Last change on this file since 364 was 364, checked in by イグトランス (egtra), 17 years ago

FormatFloatFを実装

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