[Vm-dev] [commit][2850] CogVM source as per VMMaker.oscog-eem.590.

commits at squeakvm.org commits at squeakvm.org
Thu Jan 23 19:24:56 UTC 2014


Revision: 2850
Author:   eliot
Date:     2014-01-23 11:24:54 -0800 (Thu, 23 Jan 2014)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.590.

Fix bug in Cogit>>unlinkSendsOf:isMNUSelector:, used by
primitiveFlushCacheBySelector.  The method could leave sends
linked to freed MNU PICs.

Spur:
Fix valid instruction pointer asserts for instructionPointer pointing
at byte before first bytecode.

Fix GC of classes, piggy-backing on classTableBitmap.  So rename
expungeDuplicateClasses to expungeDuplicateAndUnmarkedClasses:.
Add some asserts to check that entries in the classTable are classes.

Revise class table become management.  Don't include methods in
"unforwarded zone".  Hence add followObjField:ofObject: & fix bug
in fixFollowedField:ofObject:withInitialValue:.
Add a read barrier to fetching newMethod from a method dictionary.
Add a read barrier to fetching a method dictionary from a class.

Don't inline any of the methods into fullGC.

Modified Paths:
--------------
    branches/Cog/nscogsrc/vm/cogit.c
    branches/Cog/nscogsrc/vm/cogit.h
    branches/Cog/nscogsrc/vm/cogmethod.h
    branches/Cog/nscogsrc/vm/cointerp.c
    branches/Cog/nscogsrc/vm/cointerp.h
    branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
    branches/Cog/nscogsrc/vm/interp.h
    branches/Cog/nscogsrc/vm/vmCallback.h
    branches/Cog/spursrc/vm/cogit.c
    branches/Cog/spursrc/vm/cogit.h
    branches/Cog/spursrc/vm/cogmethod.h
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/interp.h
    branches/Cog/spursrc/vm/vmCallback.h
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    branches/Cog/spurstacksrc/vm/interp.h
    branches/Cog/spurstacksrc/vm/vmCallback.h
    branches/Cog/src/plugins/FT2Plugin/FT2Plugin.c
    branches/Cog/src/vm/cogit.c
    branches/Cog/src/vm/cogit.h
    branches/Cog/src/vm/cogmethod.h
    branches/Cog/src/vm/cointerp.c
    branches/Cog/src/vm/cointerp.h
    branches/Cog/src/vm/cointerpmt.c
    branches/Cog/src/vm/cointerpmt.h
    branches/Cog/src/vm/gcc3x-cointerp.c
    branches/Cog/src/vm/gcc3x-cointerpmt.c
    branches/Cog/src/vm/interp.h
    branches/Cog/src/vm/vmCallback.h
    branches/Cog/stacksrc/vm/gcc3x-interp.c
    branches/Cog/stacksrc/vm/interp.c
    branches/Cog/stacksrc/vm/interp.h
    branches/Cog/stacksrc/vm/vmCallback.h

Property Changed:
----------------
    branches/Cog/platforms/Cross/vm/sqSCCSVersion.h

Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/cogit.c	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.585 uuid: ffc9c619-e2b4-4432-977e-aba381f975ff
+	CCodeGenerator VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.585 uuid: ffc9c619-e2b4-4432-977e-aba381f975ff
+	StackToRegisterMappingCogit VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.585 uuid: ffc9c619-e2b4-4432-977e-aba381f975ff " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -980,6 +980,7 @@
 void printCogMethodsWithPrimitive(sqInt primIdx);
 void printCogMethodsWithSelector(sqInt selectorOop);
 void printCogYoungReferrers(void);
+void printOpenPICList(void);
 void printTrampolineTable(void);
 static sqInt processorHasDivQuoRem(sqInt ignoredPrimIndex);
 static sqInt processorHasDoublePrecisionFloatingPointSupport(sqInt ignoredPrimIndex);
@@ -1070,9 +1071,9 @@
 static sqInt unimplementedPrimitive(void);
 static sqInt unknownBytecode(void);
 void unlinkAllSends(void);
+static sqInt unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector);
 static sqInt unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity);
 static sqInt unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity);
-static sqInt unlinkIfLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector);
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
@@ -2038,6 +2039,7 @@
 #define haltmsg(msg) warning("halt: " msg)
 #define limitZony() ((CogMethod *)mzFreeStart)
 #define maybeConstant(sse) ((sse)->constant)
+#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction
 #define minCallAddress() minValidCallAddress
 #define nextOpenPIC methodObject
 #define nextOpenPICHack hack hack hack i.e. the getter macro does all the work
@@ -18966,6 +18968,18 @@
 }
 
 void
+printOpenPICList(void)
+{
+    CogMethod *openPIC;
+
+	openPIC = openPICList;
+	while (!(openPIC == null)) {
+		printCogMethod(openPIC);
+		openPIC = ((CogMethod *) ((openPIC->nextOpenPIC)));
+	}
+}
+
+void
 printTrampolineTable(void)
 {
     sqInt i;
@@ -19251,6 +19265,11 @@
     sqInt delta;
 
 	delta = (cogMethod->objectHeader);
+	assert((((cogMethod->cmType)) == CMMethod)
+	 || (((cogMethod->cmType)) == CMOpenPIC));
+	assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod
+	? methodAbortTrampolineFor((cogMethod->cmNumArgs))
+	: picAbortTrampolineFor((cogMethod->cmNumArgs)))));
 	relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -delta);
 	mapForperformUntilarg(cogMethod, relocateIfCallOrMethodReferencemcpcdelta, delta);
 }
@@ -20686,7 +20705,7 @@
 }
 
 static sqInt
-unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity)
+unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector)
 {
     sqInt entryPoint;
     sqInt off;
@@ -20726,18 +20745,28 @@
 			}
 
 			targetMethod = ((CogMethod *) (entryPoint - offset));
-			if (((targetMethod->cmType)) == CMFree) {
+			if ((((targetMethod->cmType)) == CMFree)
+			 || (((targetMethod->selector)) == theSelector)) {
 				unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
 				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
 				codeModified = 1;
 			}
 		}
+		else {
+			if (entryPoint == ceImplicitReceiverTrampoline) {
+				if ((inlineCacheTagAt(backEnd, ((sqInt)mcpc))) == theSelector) {
+					unalignedLongAtput(backEnd, (((sqInt)mcpc)) + (jumpShortByteSize(backEnd)), 0);
+					unalignedLongAtput(backEnd, ((((sqInt)mcpc)) + (jumpShortByteSize(backEnd))) + BytesPerOop, 0);
+				}
+			}
+
+		}
 	}
 	return 0;
 }
 
 static sqInt
-unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity)
+unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity)
 {
     sqInt entryPoint;
     sqInt off;
@@ -20777,22 +20806,18 @@
 			}
 
 			targetMethod = ((CogMethod *) (entryPoint - offset));
-			unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
-			rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
-		}
-		else {
-			if (entryPoint == ceImplicitReceiverTrampoline) {
-				unalignedLongAtput(backEnd, (((sqInt)mcpc)) + (jumpShortByteSize(backEnd)), 0);
-				unalignedLongAtput(backEnd, ((((sqInt)mcpc)) + (jumpShortByteSize(backEnd))) + BytesPerOop, 0);
+			if (((targetMethod->cmType)) == CMFree) {
+				unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
+				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
+				codeModified = 1;
 			}
-
 		}
 	}
 	return 0;
 }
 
 static sqInt
-unlinkIfLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector)
+unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity)
 {
     sqInt entryPoint;
     sqInt off;
@@ -20832,18 +20857,13 @@
 			}
 
 			targetMethod = ((CogMethod *) (entryPoint - offset));
-			if (((targetMethod->selector)) == theSelector) {
-				unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
-				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
-				codeModified = 1;
-			}
+			unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
+			rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
 		}
 		else {
 			if (entryPoint == ceImplicitReceiverTrampoline) {
-				if ((inlineCacheTagAt(backEnd, ((sqInt)mcpc))) == theSelector) {
-					unalignedLongAtput(backEnd, (((sqInt)mcpc)) + (jumpShortByteSize(backEnd)), 0);
-					unalignedLongAtput(backEnd, ((((sqInt)mcpc)) + (jumpShortByteSize(backEnd))) + BytesPerOop, 0);
-				}
+				unalignedLongAtput(backEnd, (((sqInt)mcpc)) + (jumpShortByteSize(backEnd)), 0);
+				unalignedLongAtput(backEnd, ((((sqInt)mcpc)) + (jumpShortByteSize(backEnd))) + BytesPerOop, 0);
 			}
 
 		}
@@ -20919,36 +20939,37 @@
 unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector)
 {
     CogMethod *cogMethod;
+    sqInt freeSpace;
 
 	if (methodZoneBase == null) {
 		return;
 	}
+	cogMethod = ((CogMethod *) methodZoneBase);
 
 	/* First check if any method actually has the selector; if not there can't
 	   be any linked send to it. */
 
-	cogMethod = ((CogMethod *) methodZoneBase);
+	freeSpace = methodBytesFreedSinceLastCompaction();
 	while ((cogMethod < (limitZony()))
 	 && (((cogMethod->selector)) != selector)) {
+		if ((((cogMethod->cmType)) != CMFree)
+		 && ((isMNUSelector
+ && ((cogMethod->cpicHasMNUCase)))
+		 || (((cogMethod->selector)) == selector))) {
+			freeMethod(cogMethod);
+		}
 		cogMethod = methodAfter(cogMethod);
 	}
-	if (cogMethod >= (limitZony())) {
+	if ((cogMethod >= (limitZony()))
+	 && (freeSpace == (methodBytesFreedSinceLastCompaction()))) {
 		return;
 	}
 	codeModified = 0;
 	cogMethod = ((CogMethod *) methodZoneBase);
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
-			mapForperformUntilarg(cogMethod, unlinkIfLinkedSendpcof, selector);
+			mapForperformUntilarg(cogMethod, unlinkIfFreeOrLinkedSendpcof, selector);
 		}
-		else {
-			if ((((cogMethod->cmType)) != CMFree)
-			 && ((isMNUSelector
- && ((cogMethod->cpicHasMNUCase)))
-			 || (((cogMethod->selector)) == selector))) {
-				freeMethod(cogMethod);
-			}
-		}
 		cogMethod = methodAfter(cogMethod);
 	}
 	if (codeModified) {

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/cogit.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.585 uuid: ffc9c619-e2b4-4432-977e-aba381f975ff
+	CCodeGenerator VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 
@@ -61,6 +61,7 @@
 void printCogMethodsWithPrimitive(sqInt primIdx);
 void printCogMethodsWithSelector(sqInt selectorOop);
 void printCogYoungReferrers(void);
+void printOpenPICList(void);
 void printTrampolineTable(void);
 void recordCallOffsetInof(CogMethod *cogMethod, void *callLabelArg);
 sqInt recordPrimTraceFunc(void);

Modified: branches/Cog/nscogsrc/vm/cogmethod.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogmethod.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/cogmethod.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.585 uuid: ffc9c619-e2b4-4432-977e-aba381f975ff
+	CCodeGenerator VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 typedef struct {

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
    from
-	CoInterpreter VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CoInterpreter VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2029,7 +2029,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.581";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.590";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13394,6 +13394,8 @@
 	: primitiveTable[primitiveIndex])));
 	}
 	else {
+		assert(!((isNonImmediate(GIV(newMethod)))
+ && (isForwarded(GIV(newMethod)))));
 		primitiveFunctionPointer = primitiveInvokeObjectAsMethod;
 	}
 	for (p = 0; p < CacheProbeMax; p += 1) {
@@ -15254,7 +15256,8 @@
 	 || ((addressCouldBeObj(aMethodObj))
 	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
-	assert(((cPIC->cmType)) == CMClosedPIC);
+	assert((((cPIC->cmType)) == CMClosedPIC)
+	 || (((cPIC->cmType)) == CMOpenPIC));
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
 	if (aMethodObj != 0) {
@@ -23104,7 +23107,7 @@
 	markStackPageMostRecentlyUsed(newPage);
 	GIV(framePointer) = (GIV(stackPage)->headFP);
 	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	assert(validInstructionPointerinFrame(GIV(instructionPointer), GIV(framePointer)));
+	assert(validInstructionPointerinFrame(GIV(instructionPointer) + 1, GIV(framePointer)));
 	assert((!(frameHasContext(GIV(framePointer))))
 	 || (isContext(frameContext(GIV(framePointer)))));
 
@@ -53684,7 +53687,7 @@
 	GIV(stackPointer) += BytesPerWord;
 	GIV(instructionPointer) = ((sqInt) top);
 	/* begin assertValidExecutionPointe:r:s: */
-	assertValidExecutionPointersimbarline(GIV(instructionPointer), GIV(framePointer), GIV(stackPointer), !((((usqInt)(longAt(GIV(framePointer) + FoxMethod)))) < (startOfMemory())), __LINE__);
+	assertValidExecutionPointersimbarline(GIV(instructionPointer) + 1, GIV(framePointer), GIV(stackPointer), !((((usqInt)(longAt(GIV(framePointer) + FoxMethod)))) < (startOfMemory())), __LINE__);
 }
 
 sqInt
@@ -54205,7 +54208,7 @@
 		theInstrPointer = longAt(fp + FoxIFSavedIP);
 	}
 	else {
-		theInstrPointer = instrPointer;
+		theInstrPointer = instrPointer + 1;
 		if ((((usqInt)(longAt(fp + FoxMethod)))) < (startOfMemory())) {
 			/* begin mframeHomeMethod: */
 			methodField = longAt(fp + FoxMethod);
@@ -54226,7 +54229,7 @@
 			(methodHeader = (isCogMethodReference(methodHeader1)
 					? ((((CogMethod *) methodHeader1))->methodHeader)
 					: methodHeader1)),
-			(theInstrPointer >= (((aMethod + (lastPointerOf(aMethod))) + BaseHeaderSize) - 1))
+			(theInstrPointer >= ((aMethod + (lastPointerOf(aMethod))) + BytesPerOop))
 				 && ((theInstrPointer < (((aMethod + (byteLengthOf(aMethod))) + BaseHeaderSize) - 1))
 				 && (!(((((sqInt) methodHeader)) < 0)
 		 && ((methodHeader & (65536 << SmallIntegerShift))

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-01-23 19:24:54 UTC (rev 2850)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
    from
-	CoInterpreter VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CoInterpreter VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2032,7 +2032,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.581";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.590";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13403,6 +13403,8 @@
 	: primitiveTable[primitiveIndex])));
 	}
 	else {
+		assert(!((isNonImmediate(GIV(newMethod)))
+ && (isForwarded(GIV(newMethod)))));
 		primitiveFunctionPointer = primitiveInvokeObjectAsMethod;
 	}
 	for (p = 0; p < CacheProbeMax; p += 1) {
@@ -15263,7 +15265,8 @@
 	 || ((addressCouldBeObj(aMethodObj))
 	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
-	assert(((cPIC->cmType)) == CMClosedPIC);
+	assert((((cPIC->cmType)) == CMClosedPIC)
+	 || (((cPIC->cmType)) == CMOpenPIC));
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
 	if (aMethodObj != 0) {
@@ -23113,7 +23116,7 @@
 	markStackPageMostRecentlyUsed(newPage);
 	GIV(framePointer) = (GIV(stackPage)->headFP);
 	GIV(stackPointer) = (GIV(stackPage)->headSP);
-	assert(validInstructionPointerinFrame(GIV(instructionPointer), GIV(framePointer)));
+	assert(validInstructionPointerinFrame(GIV(instructionPointer) + 1, GIV(framePointer)));
 	assert((!(frameHasContext(GIV(framePointer))))
 	 || (isContext(frameContext(GIV(framePointer)))));
 
@@ -53693,7 +53696,7 @@
 	GIV(stackPointer) += BytesPerWord;
 	GIV(instructionPointer) = ((sqInt) top);
 	/* begin assertValidExecutionPointe:r:s: */
-	assertValidExecutionPointersimbarline(GIV(instructionPointer), GIV(framePointer), GIV(stackPointer), !((((usqInt)(longAt(GIV(framePointer) + FoxMethod)))) < (startOfMemory())), __LINE__);
+	assertValidExecutionPointersimbarline(GIV(instructionPointer) + 1, GIV(framePointer), GIV(stackPointer), !((((usqInt)(longAt(GIV(framePointer) + FoxMethod)))) < (startOfMemory())), __LINE__);
 }
 
 sqInt
@@ -54214,7 +54217,7 @@
 		theInstrPointer = longAt(fp + FoxIFSavedIP);
 	}
 	else {
-		theInstrPointer = instrPointer;
+		theInstrPointer = instrPointer + 1;
 		if ((((usqInt)(longAt(fp + FoxMethod)))) < (startOfMemory())) {
 			/* begin mframeHomeMethod: */
 			methodField = longAt(fp + FoxMethod);
@@ -54235,7 +54238,7 @@
 			(methodHeader = (isCogMethodReference(methodHeader1)
 					? ((((CogMethod *) methodHeader1))->methodHeader)
 					: methodHeader1)),
-			(theInstrPointer >= (((aMethod + (lastPointerOf(aMethod))) + BaseHeaderSize) - 1))
+			(theInstrPointer >= ((aMethod + (lastPointerOf(aMethod))) + BytesPerOop))
 				 && ((theInstrPointer < (((aMethod + (byteLengthOf(aMethod))) + BaseHeaderSize) - 1))
 				 && (!(((((sqInt) methodHeader)) < 0)
 		 && ((methodHeader & (65536 << SmallIntegerShift))

Modified: branches/Cog/nscogsrc/vm/interp.h
===================================================================
--- branches/Cog/nscogsrc/vm/interp.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/interp.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nscogsrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nscogsrc/vm/vmCallback.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/nscogsrc/vm/vmCallback.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.581 uuid: 926531fd-20be-42b4-9332-015b90e6734f
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 #define VM_CALLBACK_INC 1


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Thu Jan 16 10:48:19 PST 2014
   + Thu Jan 23 11:23:59 PST 2014

Modified: branches/Cog/spursrc/vm/cogit.c
===================================================================
--- branches/Cog/spursrc/vm/cogit.c	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/spursrc/vm/cogit.c	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa
+	CCodeGenerator VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
    from
-	StackToRegisterMappingCogit * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa
+	StackToRegisterMappingCogit VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -940,6 +940,7 @@
 void printCogMethodsWithPrimitive(sqInt primIdx);
 void printCogMethodsWithSelector(sqInt selectorOop);
 void printCogYoungReferrers(void);
+void printOpenPICList(void);
 void printTrampolineTable(void);
 static sqInt processorHasDivQuoRem(sqInt ignoredPrimIndex);
 static sqInt processorHasDoublePrecisionFloatingPointSupport(sqInt ignoredPrimIndex);
@@ -1026,9 +1027,9 @@
 static sqInt unimplementedPrimitive(void);
 static sqInt unknownBytecode(void);
 void unlinkAllSends(void);
+static sqInt unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector);
 static sqInt unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity);
 static sqInt unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity);
-static sqInt unlinkIfLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector);
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
@@ -1730,6 +1731,7 @@
 #define haltmsg(msg) warning("halt: " msg)
 #define limitZony() ((CogMethod *)mzFreeStart)
 #define maybeConstant(sse) ((sse)->constant)
+#define methodBytesFreedSinceLastCompaction() methodBytesFreedSinceLastCompaction
 #define minCallAddress() minValidCallAddress
 #define nextOpenPIC methodObject
 #define nextOpenPICHack hack hack hack i.e. the getter macro does all the work
@@ -18619,6 +18621,18 @@
 }
 
 void
+printOpenPICList(void)
+{
+    CogMethod *openPIC;
+
+	openPIC = openPICList;
+	while (!(openPIC == null)) {
+		printCogMethod(openPIC);
+		openPIC = ((CogMethod *) ((openPIC->nextOpenPIC)));
+	}
+}
+
+void
 printTrampolineTable(void)
 {
     sqInt i;
@@ -18904,6 +18918,11 @@
     sqLong delta;
 
 	delta = (cogMethod->objectHeader);
+	assert((((cogMethod->cmType)) == CMMethod)
+	 || (((cogMethod->cmType)) == CMOpenPIC));
+	assert((callTargetFromReturnAddress(backEnd, (((sqInt)cogMethod)) + missOffset)) == ((((cogMethod->cmType)) == CMMethod
+	? methodAbortTrampolineFor((cogMethod->cmNumArgs))
+	: picAbortTrampolineFor((cogMethod->cmNumArgs)))));
 	relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -delta);
 	mapForperformUntilarg(cogMethod, relocateIfCallOrMethodReferencemcpcdelta, delta);
 }
@@ -20205,7 +20224,7 @@
 }
 
 static sqInt
-unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity)
+unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector)
 {
     sqInt entryPoint;
     sqInt off;
@@ -20234,18 +20253,22 @@
 			}
 
 			targetMethod = ((CogMethod *) (entryPoint - offset));
-			if (((targetMethod->cmType)) == CMFree) {
+			if ((((targetMethod->cmType)) == CMFree)
+			 || (((targetMethod->selector)) == theSelector)) {
 				unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
 				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
 				codeModified = 1;
 			}
 		}
+		else {
+			
+		}
 	}
 	return 0;
 }
 
 static sqInt
-unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity)
+unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity)
 {
     sqInt entryPoint;
     sqInt off;
@@ -20274,18 +20297,18 @@
 			}
 
 			targetMethod = ((CogMethod *) (entryPoint - offset));
-			unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
-			rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
+			if (((targetMethod->cmType)) == CMFree) {
+				unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
+				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
+				codeModified = 1;
+			}
 		}
-		else {
-			
-		}
 	}
 	return 0;
 }
 
 static sqInt
-unlinkIfLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector)
+unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity)
 {
     sqInt entryPoint;
     sqInt off;
@@ -20314,11 +20337,8 @@
 			}
 
 			targetMethod = ((CogMethod *) (entryPoint - offset));
-			if (((targetMethod->selector)) == theSelector) {
-				unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
-				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
-				codeModified = 1;
-			}
+			unlinkedRoutine = sendTable[((((targetMethod->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod->cmNumArgs)) : (NumSendTrampolines - 1))];
+			rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod->selector), unlinkedRoutine);
 		}
 		else {
 			
@@ -20380,36 +20400,37 @@
 unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector)
 {
     CogMethod *cogMethod;
+    sqInt freeSpace;
 
 	if (methodZoneBase == null) {
 		return;
 	}
+	cogMethod = ((CogMethod *) methodZoneBase);
 
 	/* First check if any method actually has the selector; if not there can't
 	   be any linked send to it. */
 
-	cogMethod = ((CogMethod *) methodZoneBase);
+	freeSpace = methodBytesFreedSinceLastCompaction();
 	while ((cogMethod < (limitZony()))
 	 && (((cogMethod->selector)) != selector)) {
+		if ((((cogMethod->cmType)) != CMFree)
+		 && ((isMNUSelector
+ && ((cogMethod->cpicHasMNUCase)))
+		 || (((cogMethod->selector)) == selector))) {
+			freeMethod(cogMethod);
+		}
 		cogMethod = methodAfter(cogMethod);
 	}
-	if (cogMethod >= (limitZony())) {
+	if ((cogMethod >= (limitZony()))
+	 && (freeSpace == (methodBytesFreedSinceLastCompaction()))) {
 		return;
 	}
 	codeModified = 0;
 	cogMethod = ((CogMethod *) methodZoneBase);
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
-			mapForperformUntilarg(cogMethod, unlinkIfLinkedSendpcof, selector);
+			mapForperformUntilarg(cogMethod, unlinkIfFreeOrLinkedSendpcof, selector);
 		}
-		else {
-			if ((((cogMethod->cmType)) != CMFree)
-			 && ((isMNUSelector
- && ((cogMethod->cpicHasMNUCase)))
-			 || (((cogMethod->selector)) == selector))) {
-				freeMethod(cogMethod);
-			}
-		}
 		cogMethod = methodAfter(cogMethod);
 	}
 	if (codeModified) {

Modified: branches/Cog/spursrc/vm/cogit.h
===================================================================
--- branches/Cog/spursrc/vm/cogit.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/spursrc/vm/cogit.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa
+	CCodeGenerator VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 
@@ -62,6 +62,7 @@
 void printCogMethodsWithPrimitive(sqInt primIdx);
 void printCogMethodsWithSelector(sqInt selectorOop);
 void printCogYoungReferrers(void);
+void printOpenPICList(void);
 void printTrampolineTable(void);
 void recordCallOffsetInof(CogMethod *cogMethod, void *callLabelArg);
 sqInt recordPrimTraceFunc(void);

Modified: branches/Cog/spursrc/vm/cogmethod.h
===================================================================
--- branches/Cog/spursrc/vm/cogmethod.h	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/spursrc/vm/cogmethod.h	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.569 uuid: 84f8b41f-92bf-41d2-9927-6c7e3d3e4272
+	CCodeGenerator VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
 
 typedef struct {

Modified: branches/Cog/spursrc/vm/cointerp.c
===================================================================
--- branches/Cog/spursrc/vm/cointerp.c	2014-01-23 01:15:54 UTC (rev 2849)
+++ branches/Cog/spursrc/vm/cointerp.c	2014-01-23 19:24:54 UTC (rev 2850)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
    from
-	CoInterpreter * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa
+	CoInterpreter VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662
  */
-static char __buildInfo[] = "CoInterpreter * VMMaker.oscog-eem.584 uuid: f8e3994b-6462-4df0-bc8e-c71034adf6aa " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.590 uuid: 8f6d2060-b948-464c-89d9-341f775e8662 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -482,6 +482,7 @@
 sqInt classExternalStructure(void);
 sqInt classFloat(void);
 sqInt classFloatCompactIndex(void);
+static sqInt classForClassTag(sqInt classIndex);
 sqInt classIndexMask(void);
 sqInt classIndexOf(sqInt objOop);
 sqInt classLargeNegativeInteger(void);
@@ -506,6 +507,7 @@
 CogMethod * cogMethodOf(sqInt aMethodOop);
 static void collapseSegmentsPostSwizzle(void);
 static void commenceCogCompiledCodeCompaction(void);
+static void compact(void);
 sqInt compactClassIndexOf(sqInt objOop);
 static sqInt compare31or32Bitsequal(sqInt obj1, sqInt obj2);
 void compilationBreakpointFor(sqInt selectorOop);
@@ -558,7 +560,7 @@
 static void executeCogMethodfromUnlinkedSendWithReceiver(CogMethod *cogMethod, sqInt rcvr);
 static sqInt executeNewMethod(void);
 static sqInt existInstancesInNewSpaceOf(sqInt classObj);
-static void expungeDuplicateClasses(void);
+static void expungeDuplicateAndUnmarkedClasses(sqInt expungeUnmarked);
 static void externalDivorceFrameandContext(char *theFP, sqInt ctxt);
 static char * externalEnsureIsBaseFrame(char *aFramePtr);
 static sqInt externalInstVarofContext(sqInt offset, sqInt aContext);
@@ -647,6 +649,7 @@
 static void freeStackPageNoAssert(StackPage *aPage);
 static sqInt freeStackPage(StackPage *aPage);
 usqInt freeStartAddress(void);
+static void freeUnmarkedObjectsAndSortAndCoalesceFreeSpace(void);
 static void freeUntracedStackPages(void);
 sqInt fullDisplayUpdate(void);
 usqLong fullGC(void);
@@ -827,6 +830,7 @@
 void markAndTrace(sqInt objOop);
 static void markCogMethodsAndReferentsOnPage(StackPage *thePage);
 static sqInt markInactiveEphemerons(void);
+static void markObjects(void);
 static void markStackPageMostRecentlyUsed(StackPage *page);
 static void markStackPageNextMostRecentlyUsed(StackPage *page);
 static void markWeaklingsAndMarkAndFireEphemerons(void);
@@ -1451,6 +1455,7 @@
 _iss sqInt profileMethod;
 _iss usqLong nextWakeupUsecs;
 _iss sqInt preemptionYields;
+_iss sqInt classTableIndex;
 _iss sqInt cogCompiledCodeCompactionCalledFor;
 _iss sqInt growHeadroom;
 _iss sqInt highestRunnableProcessPriority;
@@ -1465,7 +1470,6 @@
 _iss sqInt lastUncoggableInterpretedBlockMethod;
 _iss usqInt lowSpaceThreshold;
 _iss usqLong statGCEndUsecs;
-_iss sqInt classTableIndex;
 _iss sqInt cogCodeSize;
 _iss sqInt externalPrimitiveTableFirstFreeIndex;
 _iss sqInt flagInterpretedMethods;
@@ -2164,7 +2168,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 usqInt heapBase;
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter * VMMaker.oscog-eem.584]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.590]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -5778,6 +5782,8 @@
 				sendBreakpointreceiver(firstFixedFieldOfMaybeImmediate(GIV(messageSelector)), lengthOfMaybeImmediate(GIV(messageSelector)), longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop)));
 				if (recordSendTrace()) {
 					/* begin recordTrace:thing:source: */
+					/* begin classForClassTag: */
+					assert(lkupClassTag != (isForwardedObjectClassIndexPun()));
 					/* begin classAtIndex: */
 					VM_LABEL(0classAtIndex);
 					assert((lkupClassTag <= (tagMask()))
@@ -5794,7 +5800,7 @@
 					GIV(traceLog)[GIV(traceLogIndex) + 2] = TraceIsFromInterpreter;
 					GIV(traceLogIndex) = (GIV(traceLogIndex) + 3) % TraceBufferSize;
 					if (printOnTrace()) {
-						printActivationNameForSelectorstartClass(GIV(messageSelector), classAtIndex(lkupClassTag));
+						printActivationNameForSelectorstartClass(GIV(messageSelector), classForClassTag(lkupClassTag));
 						/* begin cr */
 						printf("\n");
 					}
@@ -5937,6 +5943,8 @@
 							goto l152;
 						}
 					}
+					/* begin classForClassTag: */
+					assert(lkupClassTag != (isForwardedObjectClassIndexPun()));
 					/* begin classAtIndex: */
 					VM_LABEL(1classAtIndex);
 					assert((lkupClassTag <= (tagMask()))
@@ -10683,6 +10691,8 @@
 	: primitiveTable[primitiveIndex])));
 	}
 	else {
+		assert(!((isNonImmediate(GIV(newMethod)))
+ && (isForwarded(GIV(newMethod)))));
 		primitiveFunctionPointer = primitiveInvokeObjectAsMethod;
 	}
 	for (p = 0; p < CacheProbeMax; p += 1) {
@@ -12242,7 +12252,7 @@
 			if (!copyHashFlag) {
 
 				/* in-lined
-				   clasIndex := (self isInClassTable: obj) ifTrue: [self rawHashBitsOf: obj] ifFalse: [0]
+				   classIndex := (self isInClassTable: obj) ifTrue: [self rawHashBitsOf: obj] ifFalse: [0]
 				   for speed. */
 
 				/* begin rawHashBitsOf: */
@@ -13514,7 +13524,8 @@
 	 || ((addressCouldBeObj(aMethodObj))
 	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
-	assert(((cPIC->cmType)) == CMClosedPIC);
+	assert((((cPIC->cmType)) == CMClosedPIC)
+	 || (((cPIC->cmType)) == CMOpenPIC));
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
 	if (aMethodObj != 0) {
@@ -13992,8 +14003,8 @@
 	}
 	else {
 		GIV(messageSelector) = selector;
-		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classAtIndex(classTag)))) != 0) {
-			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classAtIndex(classTag));
+		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classForClassTag(classTag)))) != 0) {
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForClassTag(classTag));
 			assert(0);
 		}
 	}
@@ -14082,8 +14093,8 @@
 			return ceSendFromInLineCacheMiss(cogMethodOrPIC);
 		}
 		GIV(messageSelector) = (cogMethodOrPIC->selector);
-		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classAtIndex(classTag)))) != 0) {
-			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classAtIndex(classTag));
+		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classForClassTag(classTag)))) != 0) {
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForClassTag(classTag));
 			assert(0);
 		}
 	}
@@ -14236,7 +14247,7 @@
 			return ceSendsupertonumArgs(selector, superNormalBar, handleForwardedSendFaultForReceiverstackDelta(rcvr, 1), numArgs);
 		}
 		GIV(messageSelector) = selector;
-		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classAtIndex(classTag)))) != 0) {
+		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classForClassTag(classTag)))) != 0) {
 			if (canLinkCacheTag
 			 && ((errSelIdx == SelectorDoesNotUnderstand)
 			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
@@ -14244,7 +14255,7 @@
 					? entryOffset()
 					: noCheckEntryOffset()), rcvr);
 			}
-			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classAtIndex(classTag));
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForClassTag(classTag));
 			assert(0);
 		}
 	}
@@ -16387,7 +16398,8 @@
 	assert((classIndex <= (tagMask()))
 	 || (classIndex >= (arrayClassIndexPun())));
 	assert((objOop == GIV(nilObj))
-	 || ((rawHashBitsOf(objOop)) == classIndex));
+	 || (((rawHashBitsOf(objOop)) == classIndex)
+	 && (objCouldBeClassObj(objOop))));
 	classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) classIndex) >> 10) << 2));
 	if (classTablePage == GIV(nilObj)) {
 		error("attempt to add class to empty page");
@@ -16477,7 +16489,23 @@
 	return ClassFloatCompactIndex;
 }
 
+static sqInt
+classForClassTag(sqInt classIndex)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt classTablePage;
 
+	assert(classIndex != (isForwardedObjectClassIndexPun()));
+	/* begin classAtIndex: */
+	assert((classIndex <= (tagMask()))
+	 || (classIndex >= (arrayClassIndexPun())));
+	classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) classIndex) >> 10) << 2));
+	if (classTablePage == GIV(nilObj)) {
+		return null;
+	}
+	return longAt((classTablePage + (BaseHeaderSize)) + ((classIndex & ((1 << 10) - 1)) << 2));
+}
+
+
 /*	22-bit class mask => ~ 4M classes */
 
 sqInt
@@ -17035,6 +17063,22 @@
 	}
 }
 
+
+/*	We'd like to use exact fit followed by best fit, but best-fit is complex
+	to implement
+	and potentially expensive. So just use exactFit followed, if necessary, by
+	first-fit. 
+ */
+
+static void
+compact(void)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+	exactFitCompact();
+	if ((usedSize(&GIV(highestObjects))) > 0) {
+		firstFitCompact();
+	}
+}
+
 sqInt
 compactClassIndexOf(sqInt objOop)
 {
@@ -20411,10 +20455,13 @@
 	a) won't have a bit set on load (because there are no forwarders on load),
 	b) wont match their identityHash.
 	So expunge duplicates by eliminating unmarked entries that don't occur at
-	their identityHash. */
+	their identityHash.
+	Further, any class in the table that is unmarked will also not have a bit
+	set so
+	eliminate unmarked classes using the bitmap too. */
 
 static void
-expungeDuplicateClasses(void)
+expungeDuplicateAndUnmarkedClasses(sqInt expungeUnmarked)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt byte;
     sqInt byteIndex;
@@ -20428,6 +20475,7 @@
 
 	for (i = 1; i < GIV(numClassTablePages); i += 1) {
 
+		/* Avoid expunging the puns by not scanning the 0th page. */
 		/* optimize scan by only scanning bitmap in regions that have pages. */
 
 		classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i << 2));
@@ -20444,12 +20492,21 @@
 							classIndex = majorBitIndex + minorBitIndex;
 							classOrNil = longAt((classTablePage + (BaseHeaderSize)) + ((classIndex & ((1 << 10) - 1)) << 2));
 							assert((classAtIndex(classIndex)) == classOrNil);
+							assert((classOrNil == GIV(nilObj))
+							 || (addressCouldBeClassObj(classOrNil)));
 							if ((classOrNil != GIV(nilObj))
-							 && ((rawHashBitsOf(classOrNil)) != classIndex)) {
+							 && ((expungeUnmarked
+ && (!(isMarked(classOrNil))))
+							 || ((rawHashBitsOf(classOrNil)) != classIndex))) {
 								/* begin storePointerUnchecked:ofObject:withValue: */
 								assert(!(isForwarded(classTablePage)));
 								longAtput((classTablePage + (BaseHeaderSize)) + ((classIndex & ((1 << 10) - 1)) << 2), GIV(nilObj));
-								assert((classAtIndex(rawHashBitsOf(classOrNil))) == classOrNil);
+								assert((expungeUnmarked
+ && (!(isMarked(classOrNil))))
+								 || ((classAtIndex(rawHashBitsOf(classOrNil))) == classOrNil));
+								if (classIndex < GIV(classTableIndex)) {
+									GIV(classTableIndex) = classIndex;
+								}
 							}
 						}
 					}
@@ -21660,6 +21717,8 @@
 				return;
 			}
 		}
+		/* begin classForClassTag: */
+		assert(classTag != (isForwardedObjectClassIndexPun()));
 		/* begin classAtIndex: */
 		assert((classTag <= (tagMask()))
 		 || (classTag >= (arrayClassIndexPun())));
@@ -22634,8 +22693,8 @@
 
 	assert(isOopForwarded(initialValue));
 	/* begin followForwarded: */
-	assert(isForwarded(objOop));
-	referent = longAt((objOop + (BaseHeaderSize)) + (0 << 2));
+	assert(isForwarded(initialValue));
+	referent = longAt((initialValue + (BaseHeaderSize)) + (0 << 2));
 	while (((referent & 3) == 0)
 	 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
 		referent = longAt((referent + (BaseHeaderSize)) + (0 << 2));
@@ -23741,63 +23800,27 @@
 }
 
 
-/*	Free any untraced stack pages. */
+/*	Sweep all of old space, freeing unmarked objects, coalescing free chunks,
+	and sorting free space.
+	
+	Small free chunks are sorted in address order on each small list head.
+	Large free chunks
+	are sorted on the sortedFreeChunks list. Record as many of the highest
+	objects as there
+	is room for in highestObjects, a circular buffer, for the use of
+	exactFitCompact. Use
+	unused eden space for highestObjects. If highestObjects does not wrap,
+	store 0
+	at highestObjects last. Record the lowest free object in firstFreeChunk.
+	Let the
+	segmentManager mark which segments contain pinned objects via notePinned:. */
 
 static void
-freeUntracedStackPages(void)
+freeUnmarkedObjectsAndSortAndCoalesceFreeSpace(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt i;
-    StackPage *thePage;
-
-	for (i = 0; i < GIV(numStackPages); i += 1) {
-		/* begin stackPageAt: */
-		thePage = stackPageAtpages(i, GIV(pages));
-		if ((!(isFree(thePage)))
-		 && (((thePage->trace)) == StackPageUnreached)) {
-			assert(noMarkedContextsOnPage(thePage));
-			freeStackPage(thePage);
-		}
-		assert(((thePage->trace = StackPageTraceInvalid)) != 0);
-	}
-}
-
-
-/*	Repaint the entire smalltalk screen, ignoring the affected rectangle. Used
-	in some platform's code when the Smalltalk window is brought to the front
-	or uncovered.
- */
-
-sqInt
-fullDisplayUpdate(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    sqInt displayObj;
-    sqInt h;
-    sqInt w;
-
-	displayObj = longAt((GIV(specialObjectsOop) + (BaseHeaderSize)) + (TheDisplay << 2));
-	if ((((displayObj & 3) == 0)
- && (((((usqInt) (longAt(displayObj))) >> 24) & 0x1F) <= 5))
-	 && ((lengthOfformat(displayObj, (((usqInt) (longAt(displayObj))) >> 24) & 0x1F)) >= 4)) {
-		w = fetchIntegerofObject(1, displayObj);
-		h = fetchIntegerofObject(2, displayObj);
-		displayBitsOfLeftTopRightBottom(displayObj, 0, 0, w, h);
-		ioForceDisplayUpdate();
-	}
-	return null;
-}
-
-
-/*	Perform a full lazy compacting GC. Answer the size of the largest free
-	chunk. 
- */
-
-usqLong
-fullGC(void)
-{   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt aLimit;
     usqLong bytes;
     sqInt bytes1;
-    sqInt childNode;
     usqInt header1NumSlots;
     usqInt header2NumSlots;
     usqInt headerNumSlots;
@@ -23805,19 +23828,11 @@
     sqInt highestObjectsWraps;
     sqInt i;
     sqInt i1;
-    sqInt i11;
-    sqInt i12;
     sqInt i2;
-    sqInt i21;
-    sqInt i3;
-    sqInt i4;
-    sqInt i5;
     sqInt iLimiT;
     sqInt iLimiT1;
-    sqInt iLimiT2;
     sqInt index;
     sqInt index1;
-    sqInt largestFree;
     usqInt lastHighest;
     sqInt lastLargeFree;
     sqInt limit;
@@ -23829,214 +23844,16 @@
     sqInt obj;
     sqInt obj2slots;
     sqInt objOop;
-    sqInt oop;
-    sqInt oop1;
     sqInt prev;
     sqInt prevObj;
     sqInt prevPrevObj;
     usqInt rawNumSlots;
     usqInt rawNumSlotsAfter;
-    sqInt sizeOfUnusedEden;
     sqInt sortedFreeChunks;
     sqInt statCoalesces = 0;
     sqInt sweepIndex;
-    StackPage *thePage;
     sqInt total;
-    sqInt traceType;
-    sqInt treeNode;
 
-	GIV(needGCFlag) = 0;
-	GIV(gcStartUsecs) = ioUTCMicrosecondsNow();
-	GIV(statMarkCount) = 0;
-	/* begin preGCAction: */
-	if (GIV(stackPage) != 0) {
-		/* begin externalWriteBackHeadFramePointers */
-		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
-		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
-		/* begin setHeadFP:andSP:inPage: */
-		assert(GIV(stackPointer) < GIV(framePointer));
-		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
-		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
-		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
-		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
-		(GIV(stackPage)->headFP = GIV(framePointer));
-		(GIV(stackPage)->headSP = GIV(stackPointer));
-		assert(pageListIsWellFormed());
-	}
-	/* begin flushMethodCache */
-	for (i = 1; i <= MethodCacheSize; i += 1) {
-		GIV(methodCache)[i] = 0;
-	}
-
-	/* this for primitiveExternalMethod */
-
-	GIV(lastMethodCacheProbeWrite) = 0;
-	/* begin flushAtCache */
-	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
-		GIV(atCache)[i1] = 0;
-	}
-	unlinkAllSends();
-
-	GIV(gcMode) = GCModeFull;
-	if (recordEventTrace()) {
-		traceType = (GCModeFull == GCModeFull
-			? TraceFullGC
-			: TraceIncrementalGC);
-		/* begin recordTrace:thing:source: */
-		GIV(traceLog)[GIV(traceLogIndex)] = traceType;
-		GIV(traceLog)[GIV(traceLogIndex) + 1] = traceType;
-		GIV(traceLog)[GIV(traceLogIndex) + 2] = 0;
-		GIV(traceLogIndex) = (GIV(traceLogIndex) + 3) % TraceBufferSize;
-	}
-	if (recordPrimTrace()) {
-		traceType = (GCModeFull == GCModeFull
-			? TraceFullGC
-			: TraceIncrementalGC);
-		/* begin fastLogPrim: */
-		GIV(primTraceLog)[GIV(primTraceLogIndex)] = traceType;
-		primTraceLogIndex(GIV(primTraceLogIndex) + 1);
-	}
-	/* begin globalGarbageCollect */
-	/* begin runLeakCheckerForFullGC: */
-	runLeakCheckerForFullGCexcludeUnmarkedNewSpaceObjs(1, 0);
-	/* return self */
-	assert(validObjStacks());
-	/* begin markObjects */
-	/* begin ensureAllMarkBitsAreZero */
-	flag("need to implement the inc GC first...");
-	assert(allObjectsUnmarked());
-	ensureAdequateClassTableBitmap();
-	/* begin initializeUnscannedEphemerons */
-	/* begin findLargestFreeChunk */
-	treeNode = GIV(freeLists)[0];
-	if (treeNode == 0) {
-		largestFree = null;
-		goto l2;
-	}
-	while (1) {
-		assert(isValidFreeObject(treeNode));
-		childNode = longAt((treeNode + (BaseHeaderSize)) + (4 << 2));
-		if (!(childNode != 0)) break;
-		treeNode = childNode;
-	}
-	largestFree = treeNode;
-l2:	/* end findLargestFreeChunk */;
-	sizeOfUnusedEden = (((eden()).limit)) - GIV(freeStart);
-	if ((largestFree != null)
-	 && ((numSlotsOfAny(largestFree)) > (sizeOfUnusedEden / (wordSize())))) {
-		(GIV(unscannedEphemerons).start = largestFree + (BaseHeaderSize));
-		(GIV(unscannedEphemerons).limit = addressAfter(largestFree));
-	}
-	else {
-		(GIV(unscannedEphemerons).start = GIV(freeStart));
-		(GIV(unscannedEphemerons).limit = ((eden()).limit));
-	}
-	(GIV(unscannedEphemerons).top = (GIV(unscannedEphemerons).start));
-	/* begin initializeMarkStack */
-	ensureRoomOnObjStackAt(MarkStackRootIndex);
-	/* begin initializeWeaklingStack */
-	ensureRoomOnObjStackAt(WeaklingStackRootIndex);
-	/* begin markAccessibleObjects */
-	assert(validClassTableRootPages());
-	assert(allBridgesMarked());
-	null;
-
-	/* This must come first to enable stack page reclamation.  It clears
-	   the trace flags on stack pages and so must preceed any marking.
-	   Otherwise it will clear the trace flags of reached pages. */
-
-	GIV(marking) = 1;
-	/* begin initStackPageGC */
-	if (GIV(stackPage) != 0) {
-		/* begin externalWriteBackHeadFramePointers */
-		assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize);
-		assert(GIV(stackPage) == (mostRecentlyUsedPage()));
-		/* begin setHeadFP:andSP:inPage: */
-		assert(GIV(stackPointer) < GIV(framePointer));
-		assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress)))
-		 && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize)));
-		assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress)))
-		 && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1)))));
-		(GIV(stackPage)->headFP = GIV(framePointer));
-		(GIV(stackPage)->headSP = GIV(stackPointer));
-		assert(pageListIsWellFormed());
-	}
-	for (i2 = 0; i2 < GIV(numStackPages); i2 += 1) {
-		/* begin stackPageAt: */
-		thePage = stackPageAtpages(i2, GIV(pages));
-		(thePage->trace = StackPageUnreached);
-	}
-	/* begin markAndTraceHiddenRoots */
-	markAndTraceObjStackandContents(GIV(markStack), 0);
-	markAndTraceObjStackandContents(GIV(weaklingStack), 0);
-	markAndTraceObjStackandContents(GIV(ephemeronQueue), 1);
-	setIsMarkedOfto(freeListsObj(), 1);
-	if (((((usqInt) (longAt(GIV(classTableFirstPage)))) >> 24) & 0x1F) == 4) {
-		markAndTrace(GIV(hiddenRootsObj));
-		goto l1;
-	}
-	setIsMarkedOfto(GIV(hiddenRootsObj), 1);
-	markAndTrace(GIV(classTableFirstPage));
-	for (i4 = 1; i4 < GIV(numClassTablePages); i4 += 1) {
-		setIsMarkedOfto(longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i4 << 2)), 1);
-	}
-l1:	/* end markAndTraceHiddenRoots */;
-	/* begin markAndTraceExtraRoots */
-	assert(GIV(remapBufferCount) == 0);
-	for (i11 = 1; i11 <= GIV(extraRootCount); i11 += 1) {
-		oop = (GIV(extraRoots)[i11])[0];
-		if (!(((oop & 3) != 0)
-			 || (((longAt(oop)) & 0x3FFFFF) == 0))) {
-			markAndTrace(oop);
-		}
-	}
-	assert(validClassTableRootPages());
-	/* begin markAndTraceInterpreterOops: */
-	markAndTraceStackPages(1);
-	markAndTraceTraceLog();
-	markAndTracePrimTraceLog();
-	markAndTrace(GIV(specialObjectsOop));
-	if (!((GIV(newMethod) & 3) != 0)) {
-		markAndTrace(GIV(newMethod));
-	}
-	/* begin traceProfileState */
-	markAndTrace(GIV(profileProcess));
-	markAndTrace(GIV(profileMethod));
-	markAndTrace(GIV(profileSemaphore));
-	sqLowLevelMFence();
-	if ((GIV(longRunningPrimitiveCheckMethod) != null)
-	 && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) {
-		markAndTrace(GIV(longRunningPrimitiveCheckMethod));
-	}
-	if (GIV(longRunningPrimitiveCheckSemaphore) != null) {
-		markAndTrace(GIV(longRunningPrimitiveCheckSemaphore));
-	}
-	if (!(GIV(tempOop) == 0)) {
-		markAndTrace(GIV(tempOop));
-	}
-	for (i3 = 1, iLimiT = GIV(remapBufferCount); i3 <= iLimiT; i3 += 1) {
-		oop1 = GIV(remapBuffer)[i3];
-		if (!((oop1 & 1))) {
-			markAndTrace(oop1);
-		}
-	}
-	for (i3 = 1; i3 <= GIV(jmpDepth); i3 += 1) {
-		oop1 = GIV(suspendedCallbacks)[i3];
-		if (!((oop1 & 1))) {
-			markAndTrace(oop1);
-		}
-		oop1 = GIV(suspendedMethods)[i3];
-		if (!((oop1 & 1))) {
-			markAndTrace(oop1);
-		}
-	}
-	assert(validObjStacks());
-	markWeaklingsAndMarkAndFireEphemerons();
-	assert(validObjStacks());
-	GIV(marking) = 0;
-	expungeDuplicateClasses();
-	nilUnmarkedWeaklingSlots();
-	/* begin freeUnmarkedObjectsAndSortAndCoalesceFreeSpace */
 	/* begin checkFreeSpace */
 	assert(bitsSetInFreeSpaceMaskForAllFreeLists());
 	assert(GIV(totalFreeOldSpace) == (totalFreeListBytes()));
@@ -24061,12 +23878,12 @@
 	assert(GIV(rememberedSetSize) >= 0);
 	/* begin prepareForGlobalSweep */
 	sweepIndex = 0;
-	for (i5 = 0; i5 < GIV(numSegments); i5 += 1) {
-		((GIV(segments)[i5]).containsPinned = 0);
+	for (i = 0; i < GIV(numSegments); i += 1) {
+		((GIV(segments)[i]).containsPinned = 0);
 	}
 	/* begin resetFreeListHeads */
-	for (i12 = 0, iLimiT2 = (32 - 1); i12 <= iLimiT2; i12 += 1) {
-		GIV(freeLists)[i12] = 0;
+	for (i1 = 0, iLimiT = (32 - 1); i1 <= iLimiT; i1 += 1) {
+		GIV(freeLists)[i1] = 0;
 	}
 	/* begin initializeStart:limit: */
 	aLimit = ((eden()).limit);
@@ -24163,7 +23980,7 @@
 				if (header1NumSlots == 0xFF) {
 					longAtput(here - (BaseHeaderSize), obj2slots + (longAt(here - (BaseHeaderSize))));
 					here = here;
-					goto l4;
+					goto l2;
 				}
 				header1NumSlots = (header1NumSlots == 0
 					? 2
@@ -24176,7 +23993,7 @@
 				if (newNumSlots < 0xFF) {
 					byteAtput(here + (((sqInt) 56 >> 3)), newNumSlots);

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list