assert-non-interiorness
author benjamin@smedbergs.us
Wed, 12 Dec 2007 11:54:22 -0500
changeset 22 0ca31a2285356f7802d7a2ecda77ba7591f833cc
parent 20 458babdaa518471a7a2e4b09f514955c86b7c60f
permissions -rw-r--r--
Merge changes from jorendorff

diff --git a/MMgc/GC.cpp b/MMgc/GC.cpp
--- a/MMgc/GC.cpp
+++ b/MMgc/GC.cpp
@@ -2567,7 +2567,7 @@ bail:
 				}
 				else
 				{
-					item = FindBeginning((void *) val);
+					item = GetRealPointer(FindBeginning((void *) val));
 				}
 #else
 				// back up to real beginning
@@ -3184,5 +3184,16 @@ bail:
 	}
 #endif
 
-
+#ifdef _DEBUG
+	GCWorkItem::GCWorkItem(const void *p, uint32 s, bool isGCItem)
+		: ptr(p)
+		, _size(s | uint32(isGCItem))
+	{
+		// If a WI is a GC item, it should always point to the
+		// "real" item, not an interior pointer!
+		if (IsGCItem()) {
+			GCAssert(GC::GetGC(p)->FindBeginning(p) == p);
+		}
+	}
+#endif
 }
diff --git a/MMgc/GC.h b/MMgc/GC.h
--- a/MMgc/GC.h
+++ b/MMgc/GC.h
@@ -978,10 +978,17 @@ namespace MMgc
 		/** @access Requires(request) */
 		void *FindBeginning(const void *gcItem)
 		{
+			GCAcquireSpinlock lock(pageMapLock);
+			return FindBeginningAlreadyLocked(gcItem);
+		}
+
+		/** @access Requires(pageMapLock) */
+		void *FindBeginningAlreadyLocked(const void *gcItem)
+		{
 			GCAssert(gcItem != NULL);
-			GCAssert(GetPageMapValue((uintptr)gcItem) != 0);
+			GCAssert(GetPageMapValueAlreadyLocked((uintptr)gcItem) != 0);
 			void *realItem = NULL;
-			int bits = GetPageMapValue((uintptr)gcItem);
+			int bits = GetPageMapValueAlreadyLocked((uintptr)gcItem);
 			switch(bits)
 			{
 			case kGCAllocPage:
@@ -994,7 +1001,7 @@ namespace MMgc
 				while(bits == kGCLargeAllocPageRest)
 				{
 					gcItem = (void*) ((uintptr)gcItem - GCHeap::kBlockSize);
-					bits = GetPageMapValue((uintptr)gcItem);
+					bits = GetPageMapValueAlreadyLocked((uintptr)gcItem);
 				}
 				realItem = GCLargeAlloc::FindBeginning(gcItem);
 				break;
diff --git a/MMgc/GCTypes.h b/MMgc/GCTypes.h
--- a/MMgc/GCTypes.h
+++ b/MMgc/GCTypes.h
@@ -119,7 +119,12 @@ namespace MMgc
 	{
 	public:
 		GCWorkItem() : ptr(0), _size(0) {}
-		GCWorkItem(const void *p, uint32 s, bool isGCItem) : ptr(p), _size(s | uint32(isGCItem)) {}
+
+#ifdef _DEBUG
+		GCWorkItem(const void *p, uint32 s, bool isGCItem);
+#else
+		GCWorkItem(const void *p, uint32 s, bool isGCItem) : ptr(p), _size(s | uint32(isGCItem)) { }
+#endif
 		uint32 GetSize() const { return _size & ~1; }
 		int IsGCItem() const { return _size & 1; }
 		const void *ptr;