mmgc-bit-checks
author jorendorff@mozilla.com
Wed, 23 Jan 2008 14:57:45 -0600
changeset 36 90c061d30873dfc7ea592b3f616be00ba73bf0db
parent 34 ec1155ba48ec7f8f8b0c2e5f35f619d0ea4e95e3
permissions -rw-r--r--
Push some patches.

diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
--- a/MMgc/GC.cpp
+++ b/MMgc/GC.cpp
@@ -2881,27 +2881,6 @@ bail:
 		collecting = false;
 		marking = false;
 	}
-
-	int GC::IsWhite(const void *item)
-	{
-		// back up to real beginning
-		item = GetRealPointer((const void*) item);
-
-		// normalize and divide by 4K to get index
-		if(!IsPointerToGCPage(item))
-			return false;
-		int bits = GetPageMapValue((uintptr)item);	
-		switch(bits) {
-		case 1:
-			return GCAlloc::IsWhite(item);
-		case 3:
-			// FIXME: we only want pointers to the first page for large items, fix
-			// this by marking the first page and subsequent pages of large items differently
-			// in the page map (ie use 2).
-			return GCLargeAlloc::IsWhite(item);
-		}
-		return false;
-	}
 	
 	// TODO: fix headers so this can be declared there and inlined
 	void GC::WriteBarrierWrite(const void *address, const void *value)
@@ -3003,11 +2982,6 @@ bail:
 	{
 		int bits = GetPageMapValue((uintptr)item);
 		return (bits != 0);
-	}
-
-	bool GC::IsQueued(const void *item)
-	{
-		return !GetMark(item) && !IsWhite(item);
 	}
 
 	uint32 *GC::GetBits(int numBytes, int sizeClass)
diff --git a/MMgc/GC.h b/MMgc/GC.h
--- a/MMgc/GC.h
+++ b/MMgc/GC.h
@@ -785,6 +785,17 @@ namespace MMgc
 
 		}
 
+	private:
+		__forceinline static void CheckItem(const void *&item)
+		{
+#if defined(DEBUG) || defined(MEMORY_INFO)
+			GCAssert(item != NULL);
+			item = GetRealPointer(item);
+			GCAssert(GetGC(item)->IsPointerToGCPage(item));
+#endif
+		}
+
+	public:
 		/**
 		 * Tracers should employ GetMark and SetMark to
 		 * set the mark bits during the mark pass.
@@ -803,25 +814,28 @@ namespace MMgc
 
 		static int SetMark(const void *item)
 		{
-			GCAssert(item != NULL);
-#ifdef MEMORY_INFO
-			GC *gc = GetGC(item);	
-			item = GetRealPointer(item);
-			GCAssert(gc->IsPointerToGCPage(item));
-#endif 			
+			CheckItem(item);
 			if (GCLargeAlloc::IsLargeBlock(item)) {
 				return GCLargeAlloc::SetMark(item);
 			} else {
 				return GCAlloc::SetMark(item);
 			}
 		}
-		
-		void SetQueued(const void *item)
-		{
-#ifdef MEMORY_INFO
-			item = GetRealPointer(item);
-			GCAssert(IsPointerToGCPage(item));
-#endif 			
+
+		/** @access Requires(request || exclusiveGC) */
+		static bool IsQueued(const void *item)
+		{
+			CheckItem(item);
+			if (GCLargeAlloc::IsLargeBlock(item)) {
+				return GCLargeAlloc::IsQueued(item);
+			} else {
+				return GCAlloc::IsQueued(item);
+			}
+		}
+
+		static void SetQueued(const void *item)
+		{
+			CheckItem(item);
 			if (GCLargeAlloc::IsLargeBlock(item)) {
 				GCLargeAlloc::SetQueued(item);
 			} else {
@@ -829,13 +843,24 @@ namespace MMgc
 			}
 		}
 
+		/**
+		 * True if the item is neither marked nor queued.
+		 *
+		 * @access Requires(request || exclusiveGC)
+		 */
+		static int IsWhite(const void *item)
+		{
+			CheckItem(item);
+			if (GCLargeAlloc::IsLargeBlock(item)) {
+				return GCLargeAlloc::IsWhite(item);
+			} else {
+				return GCAlloc::IsWhite(item);
+			}
+		}
+
 		static void ClearFinalized(const void *item)
 		{
-#ifdef MEMORY_INFO
-			GC *gc = GetGC(item);	
-			item = GetRealPointer(item);
-			GCAssert(gc->IsPointerToGCPage(item));
-#endif 			
+			CheckItem(item);
 			if (GCLargeAlloc::IsLargeBlock(item)) {
 				GCLargeAlloc::ClearFinalized(item);
 			} else {
@@ -845,11 +870,7 @@ namespace MMgc
 
 		static void SetFinalize(const void *item)
 		{
-#ifdef MEMORY_INFO
-			GC *gc = GetGC(item);	
-			item = GetRealPointer(item);
-			GCAssert(gc->IsPointerToGCPage(item));
-#endif 			
+			CheckItem(item);
 			if (GCLargeAlloc::IsLargeBlock(item)) {
 				GCLargeAlloc::SetFinalize(item);
 			} else {
@@ -859,11 +880,7 @@ namespace MMgc
 
 		static int IsFinalized(const void *item)
 		{
-#ifdef MEMORY_INFO
-			GC *gc = GetGC(item);	
-			item = GetRealPointer(item);
-			GCAssert(gc->IsPointerToGCPage(item));
-#endif 			
+			CheckItem(item);
 			if (GCLargeAlloc::IsLargeBlock(item)) {
 				return GCLargeAlloc::IsFinalized(item);
 			} else {
@@ -873,11 +890,7 @@ namespace MMgc
 
 		static int HasWeakRef(const void *item)
 		{
-#ifdef MEMORY_INFO
-			GC *gc = GetGC(item);	
-			item = GetRealPointer(item);
-			GCAssert(gc->IsPointerToGCPage(item));
-#endif 			
+			CheckItem(item);
 			if (GCLargeAlloc::IsLargeBlock(item)) {
 				return GCLargeAlloc::HasWeakRef(item);
 			} else {
@@ -1057,9 +1070,6 @@ namespace MMgc
 		/** @access Requires(request || exclusiveGC) */
 		bool IsGCMemory (const void *);
 
-		/** @access Requires(request || exclusiveGC) */
-		bool IsQueued(const void *item);
-
 		static uint64 GetPerformanceCounter();
 		static uint64 GetPerformanceFrequency();
 		
@@ -1244,9 +1254,6 @@ namespace MMgc
 		void StartIncrementalMark();
 		void FinishIncrementalMark();
 
-		/** @access Requires(request || exclusiveGC) */
-		int IsWhite(const void *item);
-		
 		/** @access ReadWrite(request, exclusiveGC) */
 		uint64 lastMarkTicks;
 		/** @access ReadWrite(request, exclusiveGC) */
diff --git a/MMgc/GCAlloc.h b/MMgc/GCAlloc.h
--- a/MMgc/GCAlloc.h
+++ b/MMgc/GCAlloc.h
@@ -110,6 +110,13 @@ namespace MMgc
 			return SetBit(block, GetIndex(block, item), kQueued);
 		}
 		
+		static bool IsQueued(const void *item)
+		{
+			// Zero low 12 bits of address to get to the Block header
+			GCBlock *block = (GCBlock*) ((uintptr)item & ~0xFFF);
+			return GetBit(block, GetIndex(block, item), kQueued) != 0;
+		}
+
 		static int SetFinalize(const void *item)
 		{
 			// Zero low 12 bits of address to get to the Block header
@@ -123,11 +130,8 @@ namespace MMgc
 			GCBlock *block = (GCBlock*) ((uintptr)item & ~0xFFF);
 
 			// not a real item
-			if(item < block->items)
-				return false;
-
-			if(FindBeginning(item) != item)
-				return false;
+			GCAssert(item >= block->items);
+			GCAssert(FindBeginning(item) == item);
 
 			return IsWhite(block, GetIndex(block, item));
 		}
diff --git a/MMgc/GCLargeAlloc.h b/MMgc/GCLargeAlloc.h
--- a/MMgc/GCLargeAlloc.h
+++ b/MMgc/GCLargeAlloc.h
@@ -101,6 +101,12 @@ namespace MMgc
 			block->flags |= kQueuedFlag;
 		}
 
+		static bool IsQueued(const void *item)
+		{
+			LargeBlock *block = GetBlockHeader(item);
+			return (block->flags & kQueuedFlag) != 0;
+		}
+
 		static void SetFinalize(const void *item)
 		{
 			LargeBlock *block = GetBlockHeader(item);