Пример #1
0
bool PyrGC::BlackToWhiteCheck(PyrObject *objA)
{
	if (objA->obj_format > obj_slot) return true;
	// scan it
	int size = objA->size;
	if (size > 0) {
		PyrSlot *slot = objA->slots;
		for (int j=size; j--; ++slot) {
			PyrObject * objB = NULL;
			if (IsObj(slot) && slotRawObject(slot)) {
				objB = slotRawObject(slot);
			}
			if (objB && (unsigned long)objB < 100) {
				fprintf(stderr, "weird obj ptr\n");
				return false;
			}
			if (objB) {
				if (objA == mStack)
					continue;

				if (objA->gc_color == mBlackColor && objA != mPartialScanObj) {
					if (objB->gc_color == mWhiteColor) {
						if (objA->classptr == class_frame) {
							// jmc: black stack frames pointing to white nodes can be ignore
							PyrFrame * frameA = (PyrFrame*)objA;
							PyrMethod * meth = slotRawMethod(&frameA->method);
							PyrMethodRaw * methraw = METHRAW(meth);
							if (methraw->needsHeapContext)
								continue;
						}
#if DUMPINSANITY
						fprintf(stderr, "black frame to white ref %p %p\n", objA, objB);
						dumpBadObject(objA);
						dumpBadObject(objB);
						fprintf(stderr, "\n");
#endif
						return false;
					}
				}
			}
		}
	}
	return true;
}
Пример #2
0
bool PyrGC::BlackToWhiteCheck(PyrObject *objA)
{
	int j, size, tag;
	PyrSlot *slot;
	PyrObject *objB;

	if (objA->obj_format > obj_slot) return true;
	// scan it
	size = objA->size;
	if (size > 0) {
		slot = objA->slots;
		for (j=size; j--; ++slot) {
			objB = NULL;
			tag = slot->utag;
			if (tag == tagObj && slot->uo) {
				objB = slot->uo;
			}
			if (objB && (long)objB < 100) {
				fprintf(stderr, "weird obj ptr\n");
				return false;
			}
			if (objB) {
				if (objA == mStack) {
				} else if (objA->gc_color == mBlackColor && objA != mPartialScanObj) {
					if (objB->gc_color == mWhiteColor) {
						fprintf(stderr, "black to white ref %p %p\n", objA, objB);
#if DUMPINSANITY
						dumpBadObject(objA);
						dumpBadObject(objB);
						fprintf(stderr, "\n");
#endif
						return false;
					}
				}
			}
		}
	}
	return true;
}
Пример #3
0
bool PyrGC::ListSanity()
{
	bool found;

	if (StackDepth() < 0) {
		fprintf(stderr, "stack underflow %d\n", (int)StackDepth());
		return false;
	}

	//postfl("PyrGC::ListSanity\n");
	for (int i=0; i<kNumGCSets; ++i) {
		PyrObjectHdr *obj;
		GCSet* set = mSets + i;

		// check black marker
		obj = &set->mBlack;
		if (!IsMarker(obj)) {
			//debugf("set %d black marker color wrong %d %p\n", i, obj->gc_color, obj);
			fprintf(stderr, "set %d black marker color wrong %d %p\n", i, obj->gc_color, obj);
			setPostFile(stderr);
			DumpBackTrace(mVMGlobals);
			dumpBadObject((PyrObject*)obj);
			return false;
		}

		// check white marker
		obj = &set->mWhite;
		if (!IsMarker(obj)) {
			//debugf("set %d white marker color wrong %d %p\n", i, obj->gc_color, obj);
			fprintf(stderr, "set %d white marker color wrong %d %p\n", i, obj->gc_color, obj);
			setPostFile(stderr);
			DumpBackTrace(mVMGlobals);
			dumpBadObject((PyrObject*)obj);
			return false;
		}

		// check free pointer between white and black marker
		if (set->mFree != &set->mBlack) {
			obj = set->mWhite.next;
			found = false;
			while (!IsMarker(obj)) {
				if (obj == set->mFree) { found = true; break; }
				obj = obj->next;
			}
			if (!found) {
				//debugf("set %d free pointer not between white and black\n", i);
				fprintf(stderr, "set %d free pointer not between white and black\n", i);
				fprintf(stderr, "set->mFree %p\n", set->mFree);
				fprintf(stderr, "set->mWhite %p\n", &set->mWhite);
				fprintf(stderr, "set->mBlack %p\n", &set->mBlack);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)set->mFree);

				fprintf(stderr, "black %d white %d grey %d\n", mBlackColor, mWhiteColor, mGreyColor);

				obj = &set->mWhite;
				int count = 0;
				do {
					if (obj == set->mFree) fprintf(stderr, "%4d %p %3d %d FREE\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					else if (obj == &set->mWhite) fprintf(stderr, "%4d %p %3d %d WHITE\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					else if (obj == &set->mBlack) fprintf(stderr, "%4d %p %3d %d BLACK\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					else fprintf(stderr, "%4d %p %3d %d\n", count, obj, obj->gc_color, obj->obj_sizeclass);
					obj = obj->next;
					count++;
				} while (obj != &set->mWhite);

				return false;
			}
		}

		// scan black list
		obj = set->mBlack.next;
		while (!IsMarker(obj)) {
			if (obj->gc_color != mBlackColor) {
				//debugf("set %d black list obj color wrong %d (%d, %d, %d) %p\n",
				//	i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				fprintf(stderr, "set %d black list obj color wrong %d (%d, %d, %d) %p\n",
					i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (GetGCSet(obj) != set) {
				//debugf("set %d black obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				fprintf(stderr, "set %d black obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				setPostFile(stderr);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (obj->next->prev != obj) {
				fprintf(stderr, "set %d black obj->next->prev != obj\n", i);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
			}

			// scan for refs to white.
			if (!BlackToWhiteCheck((PyrObject*)obj)) return false;

			obj = obj->next;
		}

		// scan white list
		obj = set->mWhite.next;
		while (obj != set->mFree) {
			if (obj->gc_color != mWhiteColor) {
				//debugf("set %d white list obj color wrong %d (%d, %d, %d) %p\n",
				//	i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				//debugf("hmmm free %p  black %p\n", set->mFree, set->black);
				fprintf(stderr, "set %d white list obj color wrong %d (%d, %d, %d) %p\n",
					i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj);
				fprintf(stderr, "hmmm free %p  black %p\n", set->mFree, &set->mBlack);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (GetGCSet(obj) != set) {
				//debugf("set %d white obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				fprintf(stderr, "set %d white obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
				return false;
			}
			if (obj->next->prev != obj) {
				fprintf(stderr, "set %d white obj->next->prev != obj\n", i);
				setPostFile(stderr);
				DumpBackTrace(mVMGlobals);
				dumpBadObject((PyrObject*)obj);
			}
			obj = obj->next;
		}

		// mark all free list items free
		obj = set->mFree;
		while (!IsMarker(obj)) {
			/*if (obj->gc_color == mGreyColor) {
				//debugf("grey obj on free list\n");
				fprintf(stderr, "grey obj on free list\n");
				return false;
			}*/
			//post("FREE\n");
			//dumpObject((PyrObject*)(PyrObject*)obj);
			obj->gc_color = mFreeColor;
			if (GetGCSet(obj) != set) {
				//debugf("set %d free obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				fprintf(stderr, "set %d free obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj);
				//dumpObject((PyrObject*)obj);
				return false;
			}
			if (obj->next->prev != obj) {
				fprintf(stderr, "set %d free obj->next->prev != obj\n", i);
				//dumpObject((PyrObject*)obj);
			}
			obj = obj->next;
		}
	}

	int numgrey = 0;
	PyrObjectHdr *grey = mGrey.next;
	while (!IsMarker(grey)) {
		numgrey++;
		if (!IsGrey(grey)) {
			fprintf(stderr, "sc Object on grey list not grey  %d %d   %d\n", grey->gc_color, mGreyColor, numgrey);
			fprintf(stderr, "%p <- %p -> %p grey %p process %p\n", mGrey.prev, &mGrey, mGrey.next, grey, mProcess);
			return false;
		}
		grey = grey->next;
	}

	if (numgrey != mNumGrey) {
		fprintf(stderr, "grey count off %d %d\n", numgrey, mNumGrey);
		DumpInfo();
		fprintf(stderr, ".");
		return false;
	}
	return true;
}
Пример #4
0
bool PyrGC::SanityMarkObj(PyrObject *objA, PyrObject *fromObj, int level)
{
	int j, size, tag;
	PyrSlot *slot;
	PyrObject *objB;

	if (objA->IsPermanent()) return true;
	if (objA->IsMarked()) return true;
	if (objA->size > MAXINDEXSIZE(objA)) {
		fprintf(stderr, "obj indexed size larger than max: %d > %d\n", objA->size, MAXINDEXSIZE(objA));
		//dumpObject((PyrObject*)objA);
		return false;
	}
	objA->SetMark(); // mark it
	if (objA->obj_format <= obj_slot) {
		// scan it
		size = objA->size;
		if (size > 0) {
			slot = objA->slots;
			for (j=size; j--; ++slot) {
				objB = NULL;
				tag = slot->utag;
				if (tag == tagObj && slot->uo) {
					objB = slot->uo;
				}
				if (objB && (long)objB < 100) {
					fprintf(stderr, "weird obj ptr\n");
					return false;
				}
				if (objB) {
					if (objA == mStack) {
					} else if (objA->gc_color == mBlackColor && objA != mPartialScanObj) {
						if (objB->gc_color == mWhiteColor) {

							//debugf("black to white ref %p %p\n", objA, objB);
							//debugf("sizeclass %d %d\n",  objA->obj_sizeclass, objB->obj_sizeclass);
							//debugf("class %s %s\n",  objA->classptr->name.us->name, objB->classptr->name.us->name);

							fprintf(stderr, "black to white ref %p %p\n", objA, objB);
	#if DUMPINSANITY
							dumpBadObject(objA);
							dumpBadObject(objB);
							fprintf(stderr, "\n");
	#endif
							return false;
						}
					}
					/*if (level > 40) {
						fprintf(stderr, "40 levels deep!\n");
						dumpBadObject(objA);
						dumpBadObject(objB);
						return false;
					}*/
					bool err = SanityMarkObj(objB, objA, level + 1);
					if (!err) return false;
				}
			}
		}
	}
	return true;
}