Index: Include/system/gc.sbp
===================================================================
--- Include/system/gc.sbp	(revision 203)
+++ Include/system/gc.sbp	(revision 214)
@@ -20,4 +20,9 @@
 Const _System_GC_FLAG_OBJECT = 8
 
+Type _System_GlobalRoot
+	ptr As *LONG_PTR
+	count As Long
+End Type
+
 Class _System_CGarbageCollection
 	ppPtr As *VoidPtr
@@ -32,11 +37,27 @@
 	CriticalSection As CRITICAL_SECTION
 
-	'メモリの上限値（この値を超えるとGCが発動します）
-	'※バイト単位
-	limitMemorySize As LONG_PTR
+	' メモリの上限値（この値を超えるとGCが発動します）
+	limitMemorySize As LONG_PTR		' バイト単位
+	limitMemoryObjectNum As Long	' メモリオブジェクトの個数単位
 
 	isFinish As Boolean
 
-Public
+
+	' Global Root
+	pGlobalRoots As *_System_GlobalRoot
+	globalRootNum As Long
+	Sub AddGlobalRootPtr( ptr As *LONG_PTR, count As Long )
+		pGlobalRoots = _System_realloc( pGlobalRoots, (globalRootNum + 1) * SizeOf(_System_GlobalRoot) )
+		pGlobalRoots[globalRootNum].ptr = ptr
+		pGlobalRoots[globalRootNum].count = count
+		globalRootNum++
+	End Sub
+
+	Sub RegisterGlobalRoots()
+		' このメソッドの実装はコンパイラが自動生成する
+
+		' AddGlobalRootPtr(...)
+		' ...
+	End Sub
 
 	' 特殊クラスのため、コンストラクタ・デストラクタは呼ばれません
@@ -46,4 +67,6 @@
 	End Sub
 
+Public
+
 	Sub Begin()
 		If ppPtr Then Exit Sub
@@ -52,6 +75,6 @@
 
 		'メモリの上限値（この値を超えるとGCが発動します）
-		'※バイト単位
-		limitMemorySize = 1024*1024 As LONG_PTR
+		limitMemorySize = 1024*1024 As LONG_PTR		' バイト単位
+		limitMemoryObjectNum = 2000					' メモリオブジェクトの個数単位
 
 		ppPtr=_System_calloc( 1 )
@@ -59,4 +82,9 @@
 		pdwFlags=_System_calloc( 1 )
 		n=0
+
+		' Global Root
+		pGlobalRoots = _System_calloc( 1 )
+		globalRootNum = 0
+		RegisterGlobalRoots()
 
 		iAllSize=0
@@ -107,11 +135,14 @@
 		'_System_pobj_AllThreads->ResumeAnotherThread()
 
-		HeapFree(_System_hProcessHeap,0,ppPtr)
-		ppPtr=0
-
-		HeapFree(_System_hProcessHeap,0,pSize)
-		pSize=0
-		HeapFree(_System_hProcessHeap,0,pdwFlags)
-		pdwFlags=0
+		_System_free( ppPtr )
+		ppPtr = NULL
+
+		_System_free( pSize )
+		pSize = NULL
+		_System_free( pdwFlags )
+		pdwFlags = NULL
+
+		_System_free( pGlobalRoots )
+		pGlobalRoots = NULL
 
 		'クリティカルセッションを破棄
@@ -198,9 +229,8 @@
 
 	Sub sweep()
-		If isSweeping <> False Or iAllSize<limitMemorySize Then
+		If isSweeping <> False or (iAllSize<limitMemorySize and n<limitMemoryObjectNum) Then
 			'メモリ使用量が上限値を超えていないとき
 			Exit Sub
 		End If
-		OutputDebugString( Ex"garbage colletion sweep start!\r\n" )
 
 		Dim hThread As HANDLE
@@ -214,4 +244,11 @@
 Private
 
+	Static Function IsNull( object As Object ) As Boolean
+		If VarPtr( object ) = NULL Then
+			Return True
+		End If
+		Return False
+	End Function
+
 	' 生存検知
 	Function HitTest(pSample As VoidPtr) As Long
@@ -225,9 +262,26 @@
 	End Function
 
+	' オブジェクトのスキャン
+	Function ScanObject(pObject As *Object, pbMark As *Byte) As Boolean
+		Dim classTypeInfo = Nothing As _System_TypeForClass
+		classTypeInfo = pObject->GetType() As _System_TypeForClass
+
+		If IsNull( classTypeInfo ) Then
+			Return False
+		End If
+
+		Dim i As Long
+		For i = 0 To ELM(classTypeInfo.numOfReference)
+			Scan( (pObject + classTypeInfo.referenceOffsets[i]) As *LONG_PTR, 1, pbMark )
+		Next
+
+		Return True
+	End Function
+
 	' 指定領域のスキャン
-	Sub Scan(pStartPtr As *LONG_PTR, size As LONG_PTR, pbMark As *Byte)
-		Dim i As Long, count As Long, index As Long
-		count=(size\SizeOf(LONG_PTR)) As Long
-		For i=0 To ELM(count)
+	Sub Scan(pStartPtr As *LONG_PTR, maxNum As Long, pbMark As *Byte)
+		Dim i As Long, index As Long
+
+		For i=0 To ELM(maxNum)
 			index=HitTest(pStartPtr[i] As VoidPtr)
 			If index<>-1 Then
@@ -235,11 +289,20 @@
 					pbMark[index]=1
 
-					If (pdwFlags[index] and _System_GC_FLAG_ATOMIC)=0 Then
-						'ヒープ領域がポインタ値を含む可能性があるとき
+					If pdwFlags[index] and _System_GC_FLAG_OBJECT Then
+						' オブジェクトの場合
+						If ScanObject( (ppPtr[index] + 3*SizeOf(LONG_PTR)) As *Object, pbMark) = False Then
+							Dim maxNum = (pSize[index]\SizeOf(LONG_PTR)) As Long
+							Scan(ppPtr[index] As *LONG_PTR, maxNum, pbMark)
+						End If
+
+					ElseIf (pdwFlags[index] and _System_GC_FLAG_ATOMIC)=0 Then
+						' ヒープ領域がポインタ値を含む可能性があるとき
 						If ppPtr[index] = 0 Then
 							'エラー
 
 						End If
-						Scan(ppPtr[index] As *LONG_PTR,pSize[index],pbMark)
+
+						Dim maxNum = (pSize[index]\SizeOf(LONG_PTR)) As Long
+						Scan(ppPtr[index] As *LONG_PTR, maxNum, pbMark)
 					End If
 				End If
@@ -268,5 +331,6 @@
 #endif
 
-				size=(_System_pobj_AllThreads->pStackBase[i] As LONG_PTR)-(NowSp As LONG_PTR)
+				Dim size=(_System_pobj_AllThreads->pStackBase[i] As LONG_PTR)-(NowSp As LONG_PTR)
+				Dim maxNum = (size\SizeOf(LONG_PTR)) As Long
 
 				If NowSp = 0 Then
@@ -275,5 +339,5 @@
 				End If
 
-				Scan( NowSp, size, pbMark )
+				Scan( NowSp, maxNum, pbMark )
 			End If
 		Next
@@ -313,7 +377,8 @@
 					_System_SweepingDelete (ptr + SizeOf( LONG_PTR ) * 3 )
 				Else
-					iAllSize-=size
 					HeapFree(_System_hProcessHeap,0,ptr)
 				End If
+
+				iAllSize-=size
 			End If
 		Next
@@ -347,5 +412,11 @@
 		EnterCriticalSection(CriticalSection)
 
-		If isSweeping <> False Or iAllSize<limitMemorySize Then
+
+		Dim startTime = GetTickCount()
+
+		OutputDebugString( Ex"garbage colletion sweep start!\r\n" )
+
+
+		If isSweeping <> False or (iAllSize<limitMemorySize and n<limitMemoryObjectNum) Then
 			ExitThread(0)
 		End If
@@ -359,5 +430,8 @@
 
 		' グローバル領域をルートに指定してスキャン
-		Scan( _System_gc_GlobalRoot_StartPtr, _System_gc_GlobalRoot_Size, pbMark )
+		Dim i As Long
+		For i = 0 To ELM( globalRootNum )
+			Scan( pGlobalRoots[i].ptr, pGlobalRoots[i].count, pbMark )
+		Next
 
 		' ローカル領域をルートに指定してスキャン
@@ -386,4 +460,5 @@
 			'許容量を拡張する
 			limitMemorySize *= 2
+			limitMemoryObjectNum *= 2
 
 			OutputDebugString( Ex"memory size is extended for gc!\r\n" )
@@ -391,9 +466,10 @@
 
 		Dim temp[100] As Char
-		wsprintf(temp,Ex"object items         ... %d -> %d  ( %dMB -> %dMB )\r\n",iBeforeN,n, iBackAllSize\1024\1024, iAllSize\1024\1024)
+		wsprintf(temp,Ex"object items         ... %d -> %d  ( %d MB -> %d MB )\r\n",iBeforeN,n, iBackAllSize\1024\1024, iAllSize\1024\1024)
 		OutputDebugString( temp )
 		wsprintf(temp,Ex"limit size of memory ... %d\r\n",limitMemorySize)
 		OutputDebugString( temp )
-		OutputDebugString( Ex"garbage colletion sweep finish!\r\n" )
+		wsprintf(temp,Ex"garbage colletion sweep finish! (%d ms)\r\n\r\n", GetTickCount()-startTime)
+		OutputDebugString( temp )
 
 
