[Vm-dev] [commit][3084] CogVM source as per VMMaker.oscog-eem.885

commits at squeakvm.org commits at squeakvm.org
Thu Sep 25 23:12:19 UTC 2014


Revision: 3084
Author:   eliot
Date:     2014-09-25 16:12:18 -0700 (Thu, 25 Sep 2014)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.885

Fix regression in V# become youngReferrers management in VMMaker.oscog-eem.882.
We /must/ prune young referrers if mapObjectReferencesInMachineCodeForBecome
removes a cog method from youngReferrers because it may get added back and
youngReferrers cannot contain duplicates.

Fix potential bug in Spur become argument validation.  Check for immediates
needs to come /after/ following forwarders since an object can become-forward
to an immediate.

Fix cPICHasForwardedClass:; this did /not/
enumerate the classIndices in a Spur Closed PIC.

Modified Paths:
--------------
    branches/Cog/nscogsrc/vm/cogit.c
    branches/Cog/nscogsrc/vm/cogit.h
    branches/Cog/nscogsrc/vm/cointerp.c
    branches/Cog/nscogsrc/vm/cointerp.h
    branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspursrc/vm/cogit.c
    branches/Cog/nsspursrc/vm/cogit.h
    branches/Cog/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
    branches/Cog/nsspurstacksrc/vm/interp.c
    branches/Cog/scripts/revertIfEssentiallyUnchanged
    branches/Cog/sistasrc/vm/cogit.c
    branches/Cog/sistasrc/vm/cogit.h
    branches/Cog/sistasrc/vm/cointerp.c
    branches/Cog/sistasrc/vm/cointerp.h
    branches/Cog/sistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursistasrc/vm/cogit.c
    branches/Cog/spursistasrc/vm/cogit.h
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cogit.c
    branches/Cog/spursrc/vm/cogit.h
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    branches/Cog/src/vm/cogit.c
    branches/Cog/src/vm/cogit.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/stacksrc/vm/gcc3x-interp.c
    branches/Cog/stacksrc/vm/interp.c

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

Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nscogsrc/vm/cogit.c	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -12553,7 +12553,7 @@
 {
     sqInt *address;
     sqInt *address1;
-    usqInt cacheAddress;
+    sqInt cacheAddress;
     sqInt cacheTag;
     sqInt cacheTag1;
     sqInt cacheTagMarked;
@@ -12723,7 +12723,7 @@
 static sqInt
 markYoungObjectspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod)
 {
-    usqInt cacheAddress;
+    sqInt cacheAddress;
     sqInt cacheTag;
     sqInt cacheTag1;
     sqInt class;
@@ -13814,7 +13814,7 @@
 static sqInt
 remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, sqInt hasYoungPtr)
 {
-    usqInt cacheAddress;
+    sqInt cacheAddress;
     sqInt cacheTag;
     sqInt cacheTag1;
     sqInt entryPoint;
@@ -14583,7 +14583,7 @@
 static void
 voidImplicitReceiverCacheAt(sqInt mcpc)
 {
-    usqInt cacheAddress;
+    sqInt cacheAddress;
 
 	assert(NumOopsPerIRC == 2);
 	cacheAddress = (((usqInt)mcpc)) + (jumpShortByteSize(backEnd));

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nscogsrc/vm/cogit.h	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
 
 

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
    from
-	CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -108,6 +108,7 @@
 #define AtCacheSize 2
 #define AtCacheTotalSize 64
 #define AtPutBase 32
+#define BecameActiveClassFlag 8
 #define BecameCompiledMethodFlag 2
 #define Byte0Mask 0xFF
 #define Byte1Mask 0xFF00
@@ -852,7 +853,7 @@
 void printWronglySizedContexts(sqInt printContexts);
 static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut) NoDbgRegParms;
 static void runLeakCheckerForFullGC(sqInt fullGCFlag) NoDbgRegParms;
-static usqInt safeObjectAfter(sqInt oop) NoDbgRegParms;
+static sqInt safeObjectAfter(sqInt oop) NoDbgRegParms;
 static sqInt safePrintStringOf(sqInt oop) NoDbgRegParms;
 static sqInt shortentoIndexableSize(sqInt obj, sqInt nSlots) NoDbgRegParms;
 static sqInt sizeBitsOfSafe(sqInt oop) NoDbgRegParms;
@@ -2085,7 +2086,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -34936,6 +34937,7 @@
     sqInt anArray2;
     sqInt anArray3;
     sqInt c;
+    sqInt c1;
     sqInt contextSize;
     sqInt fieldOffset;
     sqInt first;
@@ -34956,6 +34958,8 @@
     sqInt i;
     sqInt i1;
     sqInt i2;
+    sqInt i3;
+    sqInt i4;
     sqInt iLimiT;
     sqInt iLimiT1;
     sqInt last;
@@ -34981,6 +34985,7 @@
     sqInt oop21;
     sqInt procLists;
     sqInt s;
+    sqInt s1;
     sqInt sched;
     sqInt schedAssoc;
     sqInt sp;
@@ -36766,15 +36771,17 @@
     sqInt header1;
     sqInt header2;
     sqInt header3;
+    sqInt header4;
     usqInt lastWord;
     sqInt newFreeChunk;
     sqInt newOop;
-    usqInt next;
+    sqInt next;
     sqInt oop;
     sqInt realHeader;
     sqInt sz;
     sqInt sz1;
     sqInt sz2;
+    sqInt sz3;
     sqInt target;
     usqInt w;
 
@@ -36785,7 +36792,21 @@
 		/* begin objectAfterWhileForwarding: */
 		header2 = longAt(oop);
 		if ((header2 & MarkBit) == 0) {
-			next = ((sqInt) (objectAfter(oop)));
+			/* begin objectAfter: */
+			if (!(asserta(oopisLessThan(oop, GIV(freeStart))))) {
+				error("no objects after the end of memory");
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz2 = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header3 = longAt(oop);
+				sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header3 & SizeMask);
+			}
+			next = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]);
 			goto l1;
 		}
 		fwdBlock1 = (header2 & AllButMarkBitAndTypeMask) << 1;
@@ -36800,7 +36821,7 @@
 		else {
 			sz1 = realHeader & SizeMask;
 		}
-		next = ((sqInt) ((oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask])));
+		next = (oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]);
 	l1:	/* end objectAfterWhileForwarding: */;
 		if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
 
@@ -36854,18 +36875,18 @@
 	}
 	/* begin safeObjectAfter: */
 	if (((longAt(newFreeChunk)) & TypeMask) == HeaderTypeFree) {
-		sz2 = (longAt(newFreeChunk)) & AllButTypeMask;
+		sz3 = (longAt(newFreeChunk)) & AllButTypeMask;
 	}
 	else {
 		/* begin sizeBitsOf: */
-		header3 = longAt(newFreeChunk);
-		sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+		header4 = longAt(newFreeChunk);
+		sz3 = ((header4 & TypeMask) == HeaderTypeSizeAndClass
 			? (longAt(newFreeChunk - (BytesPerWord * 2))) & LongSizeMask
-			: header3 & SizeMask);
+			: header4 & SizeMask);
 	}
-	next = ((newFreeChunk + sz2) >= GIV(freeStart)
+	next = ((newFreeChunk + sz3) >= GIV(freeStart)
 		? GIV(freeStart)
-		: (newFreeChunk + sz2) + (headerTypeBytes[(longAt(newFreeChunk + sz2)) & TypeMask]));
+		: (newFreeChunk + sz3) + (headerTypeBytes[(longAt(newFreeChunk + sz3)) & TypeMask]));
 	assert((next == GIV(freeStart))
 	 || (next == (oopFromChunk(GIV(compEnd)))));
 	if (next == GIV(freeStart)) {
@@ -38737,7 +38758,7 @@
 	given object or free chunk in memory. Return freeStart when
 	enumeration is complete. This is for assertion checking only. */
 
-static usqInt
+static sqInt
 safeObjectAfter(sqInt oop)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt header;

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-09-25 23:12:18 UTC (rev 3084)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
    from
-	CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -111,6 +111,7 @@
 #define AtCacheSize 2
 #define AtCacheTotalSize 64
 #define AtPutBase 32
+#define BecameActiveClassFlag 8
 #define BecameCompiledMethodFlag 2
 #define Byte0Mask 0xFF
 #define Byte1Mask 0xFF00
@@ -855,7 +856,7 @@
 void printWronglySizedContexts(sqInt printContexts);
 static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut) NoDbgRegParms;
 static void runLeakCheckerForFullGC(sqInt fullGCFlag) NoDbgRegParms;
-static usqInt safeObjectAfter(sqInt oop) NoDbgRegParms;
+static sqInt safeObjectAfter(sqInt oop) NoDbgRegParms;
 static sqInt safePrintStringOf(sqInt oop) NoDbgRegParms;
 static sqInt shortentoIndexableSize(sqInt obj, sqInt nSlots) NoDbgRegParms;
 static sqInt sizeBitsOfSafe(sqInt oop) NoDbgRegParms;
@@ -2088,7 +2089,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -34945,6 +34946,7 @@
     sqInt anArray2;
     sqInt anArray3;
     sqInt c;
+    sqInt c1;
     sqInt contextSize;
     sqInt fieldOffset;
     sqInt first;
@@ -34965,6 +34967,8 @@
     sqInt i;
     sqInt i1;
     sqInt i2;
+    sqInt i3;
+    sqInt i4;
     sqInt iLimiT;
     sqInt iLimiT1;
     sqInt last;
@@ -34990,6 +34994,7 @@
     sqInt oop21;
     sqInt procLists;
     sqInt s;
+    sqInt s1;
     sqInt sched;
     sqInt schedAssoc;
     sqInt sp;
@@ -36775,15 +36780,17 @@
     sqInt header1;
     sqInt header2;
     sqInt header3;
+    sqInt header4;
     usqInt lastWord;
     sqInt newFreeChunk;
     sqInt newOop;
-    usqInt next;
+    sqInt next;
     sqInt oop;
     sqInt realHeader;
     sqInt sz;
     sqInt sz1;
     sqInt sz2;
+    sqInt sz3;
     sqInt target;
     usqInt w;
 
@@ -36794,7 +36801,21 @@
 		/* begin objectAfterWhileForwarding: */
 		header2 = longAt(oop);
 		if ((header2 & MarkBit) == 0) {
-			next = ((sqInt) (objectAfter(oop)));
+			/* begin objectAfter: */
+			if (!(asserta(oopisLessThan(oop, GIV(freeStart))))) {
+				error("no objects after the end of memory");
+			}
+			if (((longAt(oop)) & TypeMask) == HeaderTypeFree) {
+				sz2 = (longAt(oop)) & AllButTypeMask;
+			}
+			else {
+				/* begin sizeBitsOf: */
+				header3 = longAt(oop);
+				sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+					? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask
+					: header3 & SizeMask);
+			}
+			next = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]);
 			goto l1;
 		}
 		fwdBlock1 = (header2 & AllButMarkBitAndTypeMask) << 1;
@@ -36809,7 +36830,7 @@
 		else {
 			sz1 = realHeader & SizeMask;
 		}
-		next = ((sqInt) ((oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask])));
+		next = (oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]);
 	l1:	/* end objectAfterWhileForwarding: */;
 		if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
 
@@ -36863,18 +36884,18 @@
 	}
 	/* begin safeObjectAfter: */
 	if (((longAt(newFreeChunk)) & TypeMask) == HeaderTypeFree) {
-		sz2 = (longAt(newFreeChunk)) & AllButTypeMask;
+		sz3 = (longAt(newFreeChunk)) & AllButTypeMask;
 	}
 	else {
 		/* begin sizeBitsOf: */
-		header3 = longAt(newFreeChunk);
-		sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass
+		header4 = longAt(newFreeChunk);
+		sz3 = ((header4 & TypeMask) == HeaderTypeSizeAndClass
 			? (longAt(newFreeChunk - (BytesPerWord * 2))) & LongSizeMask
-			: header3 & SizeMask);
+			: header4 & SizeMask);
 	}
-	next = ((newFreeChunk + sz2) >= GIV(freeStart)
+	next = ((newFreeChunk + sz3) >= GIV(freeStart)
 		? GIV(freeStart)
-		: (newFreeChunk + sz2) + (headerTypeBytes[(longAt(newFreeChunk + sz2)) & TypeMask]));
+		: (newFreeChunk + sz3) + (headerTypeBytes[(longAt(newFreeChunk + sz3)) & TypeMask]));
 	assert((next == GIV(freeStart))
 	 || (next == (oopFromChunk(GIV(compEnd)))));
 	if (next == GIV(freeStart)) {
@@ -38746,7 +38767,7 @@
 	given object or free chunk in memory. Return freeStart when
 	enumeration is complete. This is for assertion checking only. */
 
-static usqInt
+static sqInt
 safeObjectAfter(sqInt oop)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt header;

Modified: branches/Cog/nsspursrc/vm/cogit.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.c	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nsspursrc/vm/cogit.c	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -625,6 +625,7 @@
 static void compileTrampolineFornumArgsargargargargsaveRegspushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt saveRegs, sqInt pushLinkReg, sqInt resultRegOrNil) NoDbgRegParms;
 static void computeEntryOffsets(void);
 static void computeMaximumSizes(void);
+static sqInt cPICHasForwardedClass(CogMethod *cPIC) NoDbgRegParms;
 static sqInt cPICHasFreedTargets(CogMethod *cPIC) NoDbgRegParms;
 static sqInt cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) NoDbgRegParms;
 static AbstractInstruction * gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) NoDbgRegParms;
@@ -777,11 +778,13 @@
 static sqInt unimplementedPrimitive(void);
 static sqInt unknownBytecode(void);
 void unlinkAllSends(void);
+static sqInt unlinkIfForwardedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) NoDbgRegParms;
 static sqInt unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector) NoDbgRegParms;
 static sqInt unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) NoDbgRegParms;
 static sqInt unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) NoDbgRegParms;
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) NoDbgRegParms;
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
+void unlinkSendsToForwardedClasses(void);
 void unlinkSendsToFree(void);
 void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue);
 static sqInt updateMaybeObjRefAt(sqInt mcpc) NoDbgRegParms;
@@ -10141,6 +10144,24 @@
 }
 
 static sqInt
+cPICHasForwardedClass(CogMethod *cPIC)
+{
+    sqInt classIndex;
+    sqInt i;
+    sqInt pc;
+
+	pc = (((((usqInt)cPIC)) + firstCPICCaseOffset) + cPICCaseSize) - (jumpLongConditionalByteSize(backEnd));
+	for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) {
+		classIndex = inlineCacheTagAt(backEnd, pc);
+		if (isForwardedClassIndex(classIndex)) {
+			return 1;
+		}
+		pc += cPICCaseSize;
+	}
+	return 0;
+}
+
+static sqInt
 cPICHasFreedTargets(CogMethod *cPIC)
 {
     sqInt entryPoint;
@@ -14001,6 +14022,63 @@
 }
 
 static sqInt
+unlinkIfForwardedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity)
+{
+    usqInt cacheAddress;
+    sqInt entryPoint;
+    sqInt sendTable;
+    sqInt *sendTable1;
+    sqInt targetMethod;
+    CogMethod *targetMethod1;
+    sqInt unlinkedRoutine;
+
+	if ((annotation == IsSendCall)
+			 || (annotation == IsNSSendCall)) {
+		entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc));
+		if (entryPoint > methodZoneBase) {
+
+			/* It's a linked send, but maybe a super send or linked to an OpenPIC, in which case the cache tag will be a selector.... */
+
+			if (isForwardedClassIndex(inlineCacheTagAt(backEnd, mcpc))) {
+				/* begin targetMethodAndSendTableFor:into: */
+				if ((entryPoint & entryPointMask) == checkedEntryAlignment) {
+					targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
+					sendTable1 = sendTrampolines;
+				}
+				else {
+					if ((entryPoint & entryPointMask) == dynSuperEntryAlignment) {
+						targetMethod1 = ((CogMethod *) (entryPoint - cmDynSuperEntryOffset));
+						sendTable1 = dynamicSuperSendTrampolines;
+					}
+					else {
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
+					}
+				}
+
+				/* begin unlinkSendAt:targetMethod:sendTable: */
+				unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))];
+				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod1->selector), unlinkedRoutine);
+				codeModified = 1;
+
+			}
+		}
+		else {
+			if (entryPoint == ceImplicitReceiverTrampoline) {
+				assert(NumOopsPerIRC == 2);
+				cacheAddress = implicitReceiveCacheAt(backEnd, mcpc);
+				if ((isForwardedClassIndex(unalignedLongAt(backEnd, cacheAddress)))
+				 || (isForwardedClassIndex(unalignedLongAt(backEnd, cacheAddress + BytesPerOop)))) {
+					voidImplicitReceiverCacheAt(mcpc);
+				}
+			}
+
+		}
+	}
+	return 0;
+}
+
+static sqInt
 unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector)
 {
     sqInt entryPoint;
@@ -14295,6 +14373,72 @@
 }
 
 
+/*	Unlink all sends in cog methods whose class tag is that of a forwarded
+	class. 
+ */
+
+void
+unlinkSendsToForwardedClasses(void)
+{
+    CogMethod *cogMethod;
+    sqInt freedPIC;
+    sqInt map;
+    sqInt mapByte;
+    sqInt mcpc;
+    sqInt result;
+
+	if (!(methodZoneBase)) {
+		return;
+	}
+	cogMethod = ((CogMethod *) methodZoneBase);
+	codeModified = (freedPIC = 0);
+	while (cogMethod < (limitZony())) {
+		if (((cogMethod->cmType)) == CMMethod) {
+			/* begin mapFor:performUntil:arg: */
+			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
+			while (((mapByte = byteAt(map))) != MapEnd) {
+				if (mapByte >= FirstAnnotation) {
+					mcpc += mapByte & DisplacementMask;
+					result = unlinkIfForwardedSendpcignored((((usqInt) mapByte) >> AnnotationShift), (((char *) mcpc)), 0);
+					if (result != 0) {
+						result;
+						goto l1;
+					}
+				}
+				else {
+					mcpc += (mapByte >= DisplacementX2N
+						? (mapByte - DisplacementX2N) << AnnotationShift
+						: mapByte);
+				}
+				map -= 1;
+			}
+			0;
+		l1:	/* end mapFor:performUntil:arg: */;
+		}
+		else {
+			if ((((cogMethod->cmType)) == CMClosedPIC)
+			 && (cPICHasForwardedClass(cogMethod))) {
+				freeMethod(cogMethod);
+				freedPIC = 1;
+			}
+		}
+		cogMethod = ((CogMethod *) (roundUpLength((((sqInt)cogMethod)) + ((cogMethod->blockSize)))));
+	}
+	if (freedPIC) {
+		unlinkSendsToFree();
+	}
+	else {
+		if (codeModified) {
+
+			/* After possibly updating inline caches we need to flush the icache. */
+
+			flushICacheFromto(processor, methodZoneBase, ((sqInt)(limitZony())));
+		}
+	}
+}
+
+
 /*	Unlink all sends in cog methods to free methods and/or pics. */
 
 void

Modified: branches/Cog/nsspursrc/vm/cogit.h
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.h	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nsspursrc/vm/cogit.h	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
 
 
@@ -69,6 +69,7 @@
 sqInt traceLinkedSendOffset(void);
 void unlinkAllSends(void);
 void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
+void unlinkSendsToForwardedClasses(void);
 void unlinkSendsToFree(void);
 void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue);
 void addAllToYoungReferrers(void);

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
    from
-	CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -134,6 +134,7 @@
 #define AtCacheSize 2
 #define AtCacheTotalSize 64
 #define AtPutBase 32
+#define BecameActiveClassFlag 8
 #define BecameCompiledMethodFlag 2
 #define BecamePointerObjectFlag 1
 #define BitsPerByte 8
@@ -803,6 +804,7 @@
 usqInt freeStartAddress(void);
 usqInt getScavengeThreshold(void);
 static sqLong headerWhileForwardingOf(sqInt aCompiledMethodObjOop) NoDbgRegParms;
+sqInt isForwardedClassIndex(sqInt maybeClassIndex);
 sqInt isImmediateClass(sqInt classObj);
 sqInt isReallyYoungObject(sqInt objOop);
 sqInt methodHeaderOf(sqInt methodObj);
@@ -1559,11 +1561,11 @@
 _iss sqInt tempOop;
 _iss sqInt classTableIndex;
 _iss usqInt lastFreeChunk;
+_iss sqInt becomeEffectsFlags;
 _iss SpurNewSpaceSpace eden;
 _iss sqInt ephemeronList;
 _iss usqInt freeOldSpaceStart;
 _iss sqInt tenureThreshold;
-_iss sqInt becomeEffectsFlags;
 _iss sqInt extraRootCount;
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
@@ -2326,7 +2328,7 @@
 /*540*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -5618,6 +5620,7 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
+							null;
 							goto l293;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
@@ -5635,7 +5638,7 @@
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-					/* return self */
+					null;
 				l293:	/* end baseFrameReturn */;
 					goto l292;
 				}
@@ -38723,7 +38726,29 @@
 	return long64At(aCompiledMethodObjOop);
 }
 
+
+/*	A lenient tester of forwarded class indices for inline cache management in
+	the Cogit.
+ */
+
 sqInt
+isForwardedClassIndex(sqInt maybeClassIndex)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt classTablePage;
+    sqInt entry;
+
+	if ((((usqInt)maybeClassIndex)) >= (1 << (22 - 10))) {
+		return 0;
+	}
+	classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) maybeClassIndex) >> 10) << 2));
+	if (classTablePage == GIV(nilObj)) {
+		return 0;
+	}
+	entry = longAt((classTablePage + (BaseHeaderSize)) + ((maybeClassIndex & ((1 << 10) - 1)) << 2));
+	return ((longAt(entry)) & (0x3FFFFF - 8)) == 0;
+}
+
+sqInt
 isImmediateClass(sqInt classObj)
 {
 	return ((((usqInt) (((longAt((classObj + (BaseHeaderSize)) + (InstanceSpecificationIndex << 2))) >> 1))) >> 16) & 0x1F) == 7;
@@ -42136,14 +42161,19 @@
 
 
 /*	Answer the appropriate become effect flags for objOop, or 0 if none.
-	The effect flags affect how much work is done after the become in
-	following forwarding pointers. */
+	The effect flags determine how much work is done after the become
+	in following forwarding pointers, voiding method caches, etc. */
 
 static sqInt
 becomeEffectFlagsFor(sqInt objOop)
 {
+    sqInt hash;
+
 	return (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) <= 5
-		? BecamePointerObjectFlag
+		? ((((hash = (longAt(objOop + 4)) & 0x3FFFFF)) != 0)
+			 && ((classAtIndex(hash)) == objOop)
+				? BecamePointerObjectFlag + BecameActiveClassFlag
+				: BecamePointerObjectFlag)
 		: (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) >= 24
 				? BecameCompiledMethodFlag
 				: 0));
@@ -42172,8 +42202,8 @@
 becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt c;
+    sqInt c1;
     sqInt classOrNil;
-    sqInt classTablePage;
     sqInt clone1;
     sqInt clone2;
     sqInt contextSize;
@@ -42199,6 +42229,8 @@
     sqInt i3;
     sqInt i4;
     sqInt i5;
+    sqInt i6;
+    sqInt i7;
     sqInt iLimiT;
     sqInt iLimiT1;
     sqInt iLimiT2;
@@ -42262,13 +42294,13 @@
     sqInt referent8;
     sqInt referent9;
     sqInt s;
+    sqInt s1;
     sqInt sched;
     sqInt schedAssoc;
     sqInt sp;
     sqInt sp1;
     sqInt temp1;
     sqInt temp2;
-    sqInt tmp;
     sqInt xArray;
 
 	assert(GIV(becomeEffectsFlags) == 0);
@@ -42333,11 +42365,8 @@
 		effectsFlags = 0;
 		while (fieldOffset >= (BaseHeaderSize)) {
 			oop = longAt(array1 + fieldOffset);
-			if ((oop & 3) != 0) {
-				ec = PrimErrInappropriate;
-				goto l3;
-			}
-			if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) {
+			if (((oop & 3) == 0)
+			 && (((longAt(oop)) & 0x3FFFFF) == 8)) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(oop));
 				referent5 = longAt((oop + (BaseHeaderSize)) + (0 << 2));
@@ -42348,17 +42377,18 @@
 				oop = referent5;
 				longAtput(array1 + fieldOffset, oop);
 			}
+			if ((oop & 3) != 0) {
+				ec = PrimErrInappropriate;
+				goto l3;
+			}
 			if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) {
 				ec = PrimErrObjectIsPinned;
 				goto l3;
 			}
 			effectsFlags = effectsFlags | (becomeEffectFlagsFor(oop));
 			oop = longAt(array2 + fieldOffset);
-			if ((oop & 3) != 0) {
-				ec = PrimErrInappropriate;
-				goto l3;
-			}
-			if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) {
+			if (((oop & 3) == 0)
+			 && (((longAt(oop)) & 0x3FFFFF) == 8)) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(oop));
 				referent11 = longAt((oop + (BaseHeaderSize)) + (0 << 2));
@@ -42369,6 +42399,10 @@
 				oop = referent11;
 				longAtput(array2 + fieldOffset, oop);
 			}
+			if ((oop & 3) != 0) {
+				ec = PrimErrInappropriate;
+				goto l3;
+			}
 			if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) {
 				ec = PrimErrObjectIsPinned;
 				goto l3;
@@ -42427,11 +42461,8 @@
 		effectsFlags1 = 0;
 		while (fieldOffset1 >= (BaseHeaderSize)) {
 			oop1 = longAt(array1 + fieldOffset1);
-			if ((oop1 & 3) != 0) {
-				ec = PrimErrInappropriate;
-				goto l6;
-			}
-			if (((longAt(oop1)) & (0x3FFFFF - 8)) == 0) {
+			if (((oop1 & 3) == 0)
+			 && (((longAt(oop1)) & 0x3FFFFF) == 8)) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(oop1));
 				referent6 = longAt((oop1 + (BaseHeaderSize)) + (0 << 2));
@@ -42442,6 +42473,10 @@
 				oop1 = referent6;
 				longAtput(array1 + fieldOffset1, oop1);
 			}
+			if ((oop1 & 3) != 0) {
+				ec = PrimErrInappropriate;
+				goto l6;
+			}
 			if (((((usqInt) (longAt(oop1))) >> 30) & 1) != 0) {
 				ec = PrimErrObjectIsPinned;
 				goto l6;
@@ -42498,26 +42533,25 @@
 			obj2 = objOop3;
 			if (obj1 != obj2) {
 				/* begin doBecome:and:copyHash: */
-				if (!copyHashFlag) {
-
-					/* in-lined
-					   classIndex := (self isInClassTable: obj) ifTrue: [self rawHashBitsOf: obj] ifFalse: [0]
-					   for speed. */
-
-					o1ClassIndex = (longAt(obj1 + 4)) & 0x3FFFFF;
-					if ((o1ClassIndex != 0)
-					 && ((classAtIndex(o1ClassIndex)) != obj1)) {
-						o1ClassIndex = 0;
-					}
-					o2ClassIndex = (longAt(obj2 + 4)) & 0x3FFFFF;
-					if ((o2ClassIndex != 0)
-					 && ((classAtIndex(o2ClassIndex)) != obj2)) {
-						o2ClassIndex = 0;
-					}
+				o1ClassIndex = (longAt(obj1 + 4)) & 0x3FFFFF;
+				if ((o1ClassIndex != 0)
+				 && ((classAtIndex(o1ClassIndex)) != obj1)) {
+					o1ClassIndex = 0;
 				}
-				if ((numSlotsOf(obj1)) == (numSlotsOf(obj2))) {
+				o2ClassIndex = (longAt(obj2 + 4)) & 0x3FFFFF;
+				if ((o2ClassIndex != 0)
+				 && ((classAtIndex(o2ClassIndex)) != obj2)) {
+					o2ClassIndex = 0;
+				}
+				if (((numSlotsOf(obj1)) == (numSlotsOf(obj2)))
+				 && ((o1ClassIndex == 0)
+				 && (o2ClassIndex == 0))) {
 					/* begin inPlaceBecome:and:copyHashFlag: */
 					assert((numSlotsOf(obj1)) == (numSlotsOf(obj2)));
+					assert(((rawHashBitsOf(obj1)) == 0)
+					 || ((classOrNilAtIndex(rawHashBitsOf(obj1))) != obj1));
+					assert(((rawHashBitsOf(obj2)) == 0)
+					 || ((classOrNilAtIndex(rawHashBitsOf(obj2))) != obj2));
 					temp1 = ((((usqInt) (longAt(obj1))) >> 29) & 1) != 0;
 					temp2 = ((((usqInt) (longAt(obj2))) >> 29) & 1) != 0;
 					headerTemp = long64At(obj1);
@@ -42545,15 +42579,15 @@
 						longAtput(obj2 + 4, ((((longAt(obj2 + 4)) | 0x3FFFFF) - 0x3FFFFF)) + temp1);
 					}
 					o1HasYoung = (o2HasYoung = 0);
-					for (i5 = 0, iLimiT4 = ((numSlotsOf(obj1)) - 1); i5 <= iLimiT4; i5 += 1) {
-						temp1 = longAt((obj1 + (BaseHeaderSize)) + (i5 << 2));
-						temp2 = longAt((obj2 + (BaseHeaderSize)) + (i5 << 2));
+					for (i7 = 0, iLimiT4 = ((numSlotsOf(obj1)) - 1); i7 <= iLimiT4; i7 += 1) {
+						temp1 = longAt((obj1 + (BaseHeaderSize)) + (i7 << 2));
+						temp2 = longAt((obj2 + (BaseHeaderSize)) + (i7 << 2));
 						/* begin storePointerUnchecked:ofObject:withValue: */
 						assert(!(isForwarded(obj1)));
-						longAtput((obj1 + (BaseHeaderSize)) + (i5 << 2), temp2);
+						longAtput((obj1 + (BaseHeaderSize)) + (i7 << 2), temp2);
 						/* begin storePointerUnchecked:ofObject:withValue: */
 						assert(!(isForwarded(obj2)));
-						longAtput((obj2 + (BaseHeaderSize)) + (i5 << 2), temp1);
+						longAtput((obj2 + (BaseHeaderSize)) + (i7 << 2), temp1);
 						if (((temp2 & 3) == 0)
 						 && ((((usqInt) temp2)) < (((usqInt) GIV(newSpaceLimit))))) {
 							o1HasYoung = 1;
@@ -42585,11 +42619,7 @@
 							}
 						}
 					}
-					assert((o1ClassIndex == 0)
-					 || ((rawHashBitsOf(classAtIndex(o1ClassIndex))) == o1ClassIndex));
-					assert((o2ClassIndex == 0)
-					 || ((rawHashBitsOf(classAtIndex(o2ClassIndex))) == o2ClassIndex));
-					goto l9;
+					goto l8;
 				}
 				/* begin outOfPlaceBecome:and:copyHashFlag: */
 				clone1 = (((longAt(obj1)) & 0x3FFFFF) == ClassMethodContextCompactIndex
@@ -42677,29 +42707,16 @@
 					GIV(becomeEffectsFlags) = GIV(becomeEffectsFlags) | OldBecameNewFlag;
 				}
 				if (copyHashFlag) {
-					goto l9;
+					goto l8;
 				}
 				if (o1ClassIndex != 0) {
 					if (o2ClassIndex != 0) {
-
-						/* both were in the table; just swap entries */
-
-						/* begin classAtIndex: */
-						assert((o1ClassIndex <= (tagMask()))
-						 || (o1ClassIndex >= (arrayClassIndexPun())));
-						classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) o1ClassIndex) >> 10) << 2));
-						if (classTablePage == GIV(nilObj)) {
-							tmp = null;
-							goto l8;
-						}
-						tmp = longAt((classTablePage + (BaseHeaderSize)) + ((o1ClassIndex & ((1 << 10) - 1)) << 2));
-					l8:	/* end classAtIndex: */;
 						classAtIndexput(o1ClassIndex, obj2);
-						classAtIndexput(o2ClassIndex, tmp);
+						classAtIndexput(o2ClassIndex, obj1);
 					}
 					else {
 
-						/* o2 wasn't in the table; put it there */
+						/* o2 wasn't in the table; set its hash */
 
 						/* begin followForwarded: */
 						assert(isUnambiguouslyForwarder(obj1));
@@ -42714,11 +42731,13 @@
 						flag("endianness");
 						assert(((o1ClassIndex >= 0) && (o1ClassIndex <= (identityHashHalfWordMask()))));
 						longAtput(newObj2 + 4, ((((longAt(newObj2 + 4)) | 0x3FFFFF) - 0x3FFFFF)) + o1ClassIndex);
-						classAtIndexput(o1ClassIndex, newObj2);
 					}
 				}
 				else {
 					if (o2ClassIndex != 0) {
+
+						/* o1 wasn't in the table; set its hash */
+
 						/* begin followForwarded: */
 						assert(isUnambiguouslyForwarder(obj2));
 						referent13 = longAt((obj2 + (BaseHeaderSize)) + (0 << 2));
@@ -42732,10 +42751,9 @@
 						flag("endianness");
 						assert(((o2ClassIndex >= 0) && (o2ClassIndex <= (identityHashHalfWordMask()))));
 						longAtput(newObj1 + 4, ((((longAt(newObj1 + 4)) | 0x3FFFFF) - 0x3FFFFF)) + o2ClassIndex);
-						classAtIndexput(o2ClassIndex, newObj1);
 					}
 				}
-			l9:	/* end doBecome:and:copyHash: */;
+			l8:	/* end doBecome:and:copyHash: */;
 				/* begin followField:ofObject: */
 				objOop = longAt((array1 + (BaseHeaderSize)) + (i << 2));
 				if (((objOop & 3) == 0)
@@ -42861,63 +42879,15 @@
 		GIV(specialObjectsOop) = referent;
 	}
 	followForwardedObjectFieldstoDepth(GIV(specialObjectsOop), 0);
-	/* begin postBecomeScanClassTable: */
-	assert(validClassTableRootPages());
-	if (!(GIV(becomeEffectsFlags) & BecamePointerObjectFlag)) {
-		goto l7;
-	}
-	for (i4 = 0; i4 < GIV(numClassTablePages); i4 += 1) {
-		page = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i4 << 2));
-		assert(!(isForwarded(page)));
-		for (j = 0, jLimiT = ((numSlotsOf(page)) - 1); j <= jLimiT; j += 1) {
-			classOrNil = longAt((page + (BaseHeaderSize)) + (j << 2));
-			if (classOrNil != GIV(nilObj)) {
-				if (((longAt(classOrNil)) & (0x3FFFFF - 8)) == 0) {
-					/* begin followForwarded: */
-					assert(isUnambiguouslyForwarder(classOrNil));
-					referent8 = longAt((classOrNil + (BaseHeaderSize)) + (0 << 2));
-					while (((referent8 & 3) == 0)
-					 && (((longAt(referent8)) & 0x3FFFFF) == 8)) {
-						referent8 = longAt((referent8 + (BaseHeaderSize)) + (0 << 2));
-					}
-					classOrNil = referent8;
-					/* begin storePointer:ofObject:withValue: */
-					assert(!(isForwarded(page)));
-					if (isOldObject(page)) {
-
-						/* most stores into young objects */
-
-						if (((classOrNil & 3) == 0)
-						 && ((((usqInt) classOrNil)) < (((usqInt) GIV(newSpaceLimit))))) {
-							/* begin possibleRootStoreInto: */
-							if (!(((((usqInt) (longAt(page))) >> 29) & 1) != 0)) {
-								remember(page);
-							}
-						}
-					}
-					longAtput((page + (BaseHeaderSize)) + (j << 2), classOrNil);
-				}
-				if (((longAt(classOrNil + 4)) & 0x3FFFFF) == 0) {
-					/* begin storePointerUnchecked:ofObject:withValue: */
-					assert(!(isForwarded(page)));
-					longAtput((page + (BaseHeaderSize)) + (j << 2), GIV(nilObj));
-					if (((i4 << 10) + j) < GIV(classTableIndex)) {
-						GIV(classTableIndex) = (i4 << 10) + j;
-					}
-				}
-			}
-		}
-	}
-l7:	/* end postBecomeScanClassTable: */;
 	/* begin postBecomeAction: */
 	followForwardingPointersInStackZone(GIV(becomeEffectsFlags));
 	if (GIV(becomeEffectsFlags) != 0) {
 		if (GIV(becomeEffectsFlags) & BecameCompiledMethodFlag) {
 			/* begin followForwardedMethodsInMethodCache */
-			for (i2 = 0; i2 < MethodCacheSize; i2 += MethodCacheEntrySize) {
-				c = GIV(methodCache)[i2 + MethodCacheClass];
-				s = GIV(methodCache)[i2 + MethodCacheSelector];
-				m = GIV(methodCache)[i2 + MethodCacheMethod];
+			for (i4 = 0; i4 < MethodCacheSize; i4 += MethodCacheEntrySize) {
+				c = GIV(methodCache)[i4 + MethodCacheClass];
+				s = GIV(methodCache)[i4 + MethodCacheSelector];
+				m = GIV(methodCache)[i4 + MethodCacheMethod];
 				if ((c != 0)
 				 && ((s != 0)
 				 && ((m != 0)
@@ -42931,12 +42901,31 @@
 						referent4 = longAt((referent4 + (BaseHeaderSize)) + (0 << 2));
 					}
 					m = referent4;
-					GIV(methodCache)[i2 + MethodCacheMethod] = m;
+					GIV(methodCache)[i4 + MethodCacheMethod] = m;
 				}
 			}
 			/* begin followForwardedMethodsInMethodZone */
 			followForwardedMethods();
 		}
+		if (GIV(becomeEffectsFlags) & BecameActiveClassFlag) {
+			/* begin flushBecommedClassesInMethodCache */
+			for (i2 = 0; i2 < MethodCacheSize; i2 += MethodCacheEntrySize) {
+				c1 = GIV(methodCache)[i2 + MethodCacheClass];
+				s1 = GIV(methodCache)[i2 + MethodCacheSelector];
+				if ((c1 != 0)
+				 && ((s1 != 0)
+				 && (isForwarded(classOrNilAtIndex(c1))))) {
+					GIV(methodCache)[i2 + MethodCacheClass] = 0;
+					GIV(methodCache)[i2 + MethodCacheSelector] = 0;
+				}
+			}
+			/* begin flushAtCache */
+			for (i11 = 1; i11 <= AtCacheTotalSize; i11 += 1) {
+				GIV(atCache)[i11] = 0;
+			}
+			/* begin flushBecommedClassesInMethodZone */
+			unlinkSendsToForwardedClasses();
+		}
 		/* begin followForwardingPointersInScheduler */
 
 		/* the GC follows pointers in the special objects array for us. */
@@ -42957,12 +42946,12 @@
 			objOop51 = fixFollowedFieldofObjectwithInitialValue(ProcessListsIndex, sched, objOop51);
 		}
 		procLists = objOop51;
-		for (i11 = 0, iLimiT2 = ((numSlotsOf(procLists)) - 1); i11 <= iLimiT2; i11 += 1) {
+		for (i3 = 0, iLimiT2 = ((numSlotsOf(procLists)) - 1); i3 <= iLimiT2; i3 += 1) {
 			/* begin followObjField:ofObject: */
-			objOop11 = longAt((procLists + (BaseHeaderSize)) + (i11 << 2));
+			objOop11 = longAt((procLists + (BaseHeaderSize)) + (i3 << 2));
 			assert(isNonImmediate(objOop11));
 			if (((longAt(objOop11)) & (0x3FFFFF - 8)) == 0) {
-				objOop11 = fixFollowedFieldofObjectwithInitialValue(i11, procLists, objOop11);
+				objOop11 = fixFollowedFieldofObjectwithInitialValue(i3, procLists, objOop11);
 			}
 			list = objOop11;
 			/* begin followObjField:ofObject: */
@@ -43126,9 +43115,9 @@
 			}
 			longAtput((GIV(specialObjectsOop) + (BaseHeaderSize)) + (ExternalObjectsArray << 2), xArray);
 		}
-		for (i3 = 0, iLimiT3 = ((numSlotsOf(xArray)) - 1); i3 <= iLimiT3; i3 += 1) {
+		for (i5 = 0, iLimiT3 = ((numSlotsOf(xArray)) - 1); i5 <= iLimiT3; i5 += 1) {
 			/* begin followSemaphoreIn:at: */
-			obj = longAt((xArray + (BaseHeaderSize)) + (i3 << 2));
+			obj = longAt((xArray + (BaseHeaderSize)) + (i5 << 2));
 			if (((longAt(obj)) & (0x3FFFFF - 8)) == 0) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(obj));
@@ -43152,7 +43141,7 @@
 						}
 					}
 				}
-				longAtput((xArray + (BaseHeaderSize)) + (i3 << 2), obj);
+				longAtput((xArray + (BaseHeaderSize)) + (i5 << 2), obj);
 			}
 		}
 		/* begin followForwardingPointersInProfileState */
@@ -43194,6 +43183,54 @@
 	cogitPostGCAction(GIV(gcMode));
 	GIV(lastCoggableInterpretedBlockMethod) = (GIV(lastUncoggableInterpretedBlockMethod) = null);
 	GIV(gcMode) = 0;
+	/* begin postBecomeScanClassTable: */
+	assert(validClassTableRootPages());
+	if (!(GIV(becomeEffectsFlags) & BecamePointerObjectFlag)) {
+		goto l7;
+	}
+	for (i6 = 0; i6 < GIV(numClassTablePages); i6 += 1) {
+		page = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i6 << 2));
+		assert(!(isForwarded(page)));
+		for (j = 0, jLimiT = ((numSlotsOf(page)) - 1); j <= jLimiT; j += 1) {
+			classOrNil = longAt((page + (BaseHeaderSize)) + (j << 2));
+			if (classOrNil != GIV(nilObj)) {
+				if (((longAt(classOrNil)) & (0x3FFFFF - 8)) == 0) {
+					/* begin followForwarded: */
+					assert(isUnambiguouslyForwarder(classOrNil));
+					referent8 = longAt((classOrNil + (BaseHeaderSize)) + (0 << 2));
+					while (((referent8 & 3) == 0)
+					 && (((longAt(referent8)) & 0x3FFFFF) == 8)) {
+						referent8 = longAt((referent8 + (BaseHeaderSize)) + (0 << 2));
+					}
+					classOrNil = referent8;
+					/* begin storePointer:ofObject:withValue: */
+					assert(!(isForwarded(page)));
+					if (isOldObject(page)) {
+
+						/* most stores into young objects */
+
+						if (((classOrNil & 3) == 0)
+						 && ((((usqInt) classOrNil)) < (((usqInt) GIV(newSpaceLimit))))) {
+							/* begin possibleRootStoreInto: */
+							if (!(((((usqInt) (longAt(page))) >> 29) & 1) != 0)) {
+								remember(page);
+							}
+						}
+					}
+					longAtput((page + (BaseHeaderSize)) + (j << 2), classOrNil);
+				}
+				if (((longAt(classOrNil + 4)) & 0x3FFFFF) == 0) {
+					/* begin storePointerUnchecked:ofObject:withValue: */
+					assert(!(isForwarded(page)));
+					longAtput((page + (BaseHeaderSize)) + (j << 2), GIV(nilObj));
+					if (((i6 << 10) + j) < GIV(classTableIndex)) {
+						GIV(classTableIndex) = (i6 << 10) + j;
+					}
+				}
+			}
+		}
+	}
+l7:	/* end postBecomeScanClassTable: */;
 	GIV(becomeEffectsFlags) = 0;
 	assert(validClassTableHashes());
 	if ((checkForLeaks & 4) != 0) {
@@ -51174,8 +51211,10 @@
 printInvalidClassTableEntries(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt classOrNil;
+    sqInt classOrNil1;
     sqInt hash;
     sqInt i;
+    sqInt index;
     sqInt j;
     sqInt jLimiT;
     sqInt page;
@@ -51186,18 +51225,20 @@
 		printf("\n");
 		return;
 	}
+	/* begin classTableEntriesDo: */
 	for (i = 0; i < GIV(numClassTablePages); i += 1) {
 		page = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i << 2));
 		for (j = 0, jLimiT = ((1 << 10) - 1); j <= jLimiT; j += 1) {
-			classOrNil = longAt((page + (BaseHeaderSize)) + (j << 2));
-			if (classOrNil != GIV(nilObj)) {
-				if ((((longAt(classOrNil)) & (0x3FFFFF - 8)) == 0)
-				 || ((((hash = (longAt(classOrNil + 4)) & 0x3FFFFF)) == 0)
-				 || ((noCheckClassAtIndex(hash)) != classOrNil))) {
+			classOrNil1 = longAt((page + (BaseHeaderSize)) + (j << 2));
+			if (classOrNil1 != GIV(nilObj)) {
+				index = (i << 10) + j;
+				if ((((longAt(classOrNil1)) & (0x3FFFFF - 8)) == 0)
+				 || ((((hash = (longAt(classOrNil1 + 4)) & 0x3FFFFF)) == 0)
+				 || ((noCheckClassAtIndex(hash)) != classOrNil1))) {
 					print("entry ");
-					printHex((i * (1 << 10)) + j);
+					printHex(index);
 					print(" oop ");
-					printHex(classOrNil);
+					printHex(classOrNil1);
 					print(" hash ");
 					printHex(hash);
 					print(" => ");
@@ -51205,6 +51246,7 @@
 					/* begin cr */
 					printf("\n");
 				}
+
 			}
 		}
 	}

Modified: branches/Cog/nsspursrc/vm/cointerp.h
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.h	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nsspursrc/vm/cointerp.h	2014-09-25 23:12:18 UTC (rev 3084)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
 
 
@@ -121,6 +121,7 @@
 void ensureNoForwardedLiteralsIn(sqInt aMethodObj);
 usqInt freeStartAddress(void);
 usqInt getScavengeThreshold(void);
+sqInt isForwardedClassIndex(sqInt maybeClassIndex);
 sqInt isImmediateClass(sqInt classObj);
 sqInt isReallyYoungObject(sqInt objOop);
 sqInt methodHeaderOf(sqInt methodObj);

Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-09-25 23:02:22 UTC (rev 3083)
+++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c	2014-09-25 23:12:18 UTC (rev 3084)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
    from
-	CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac
+	CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -137,6 +137,7 @@
 #define AtCacheSize 2
 #define AtCacheTotalSize 64
 #define AtPutBase 32
+#define BecameActiveClassFlag 8
 #define BecameCompiledMethodFlag 2
 #define BecamePointerObjectFlag 1
 #define BitsPerByte 8
@@ -806,6 +807,7 @@
 usqInt freeStartAddress(void);
 usqInt getScavengeThreshold(void);
 static sqLong headerWhileForwardingOf(sqInt aCompiledMethodObjOop) NoDbgRegParms;
+sqInt isForwardedClassIndex(sqInt maybeClassIndex);
 sqInt isImmediateClass(sqInt classObj);
 sqInt isReallyYoungObject(sqInt objOop);
 sqInt methodHeaderOf(sqInt methodObj);
@@ -1562,11 +1564,11 @@
 _iss sqInt tempOop;
 _iss sqInt classTableIndex;
 _iss usqInt lastFreeChunk;
+_iss sqInt becomeEffectsFlags;
 _iss SpurNewSpaceSpace eden;
 _iss sqInt ephemeronList;
 _iss usqInt freeOldSpaceStart;
 _iss sqInt tenureThreshold;
-_iss sqInt becomeEffectsFlags;
 _iss sqInt extraRootCount;
 _iss sqInt invalidObjStackPage;
 _iss sqInt previousRememberedSetSize;
@@ -2329,7 +2331,7 @@
 /*540*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -5627,6 +5629,7 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
+							null;
 							goto l293;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
@@ -5644,7 +5647,7 @@
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-					/* return self */
+					null;
 				l293:	/* end baseFrameReturn */;
 					goto l292;
 				}
@@ -38732,7 +38735,29 @@
 	return long64At(aCompiledMethodObjOop);
 }
 
+
+/*	A lenient tester of forwarded class indices for inline cache management in
+	the Cogit.
+ */
+
 sqInt
+isForwardedClassIndex(sqInt maybeClassIndex)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt classTablePage;
+    sqInt entry;
+
+	if ((((usqInt)maybeClassIndex)) >= (1 << (22 - 10))) {
+		return 0;
+	}
+	classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) maybeClassIndex) >> 10) << 2));
+	if (classTablePage == GIV(nilObj)) {
+		return 0;
+	}
+	entry = longAt((classTablePage + (BaseHeaderSize)) + ((maybeClassIndex & ((1 << 10) - 1)) << 2));
+	return ((longAt(entry)) & (0x3FFFFF - 8)) == 0;
+}
+
+sqInt
 isImmediateClass(sqInt classObj)
 {
 	return ((((usqInt) (((longAt((classObj + (BaseHeaderSize)) + (InstanceSpecificationIndex << 2))) >> 1))) >> 16) & 0x1F) == 7;
@@ -42145,14 +42170,19 @@
 
 
 /*	Answer the appropriate become effect flags for objOop, or 0 if none.
-	The effect flags affect how much work is done after the become in
-	following forwarding pointers. */
+	The effect flags determine how much work is done after the become
+	in following forwarding pointers, voiding method caches, etc. */
 
 static sqInt
 becomeEffectFlagsFor(sqInt objOop)
 {
+    sqInt hash;
+
 	return (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) <= 5
-		? BecamePointerObjectFlag
+		? ((((hash = (longAt(objOop + 4)) & 0x3FFFFF)) != 0)
+			 && ((classAtIndex(hash)) == objOop)
+				? BecamePointerObjectFlag + BecameActiveClassFlag
+				: BecamePointerObjectFlag)
 		: (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) >= 24
 				? BecameCompiledMethodFlag
 				: 0));
@@ -42181,8 +42211,8 @@
 becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt c;
+    sqInt c1;
     sqInt classOrNil;
-    sqInt classTablePage;
     sqInt clone1;
     sqInt clone2;
     sqInt contextSize;
@@ -42208,6 +42238,8 @@
     sqInt i3;
     sqInt i4;
     sqInt i5;
+    sqInt i6;
+    sqInt i7;
     sqInt iLimiT;
     sqInt iLimiT1;
     sqInt iLimiT2;
@@ -42271,13 +42303,13 @@
     sqInt referent8;
     sqInt referent9;
     sqInt s;
+    sqInt s1;
     sqInt sched;
     sqInt schedAssoc;
     sqInt sp;
     sqInt sp1;
     sqInt temp1;
     sqInt temp2;
-    sqInt tmp;
     sqInt xArray;
 
 	assert(GIV(becomeEffectsFlags) == 0);
@@ -42342,11 +42374,8 @@
 		effectsFlags = 0;
 		while (fieldOffset >= (BaseHeaderSize)) {
 			oop = longAt(array1 + fieldOffset);
-			if ((oop & 3) != 0) {
-				ec = PrimErrInappropriate;
-				goto l3;
-			}
-			if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) {
+			if (((oop & 3) == 0)
+			 && (((longAt(oop)) & 0x3FFFFF) == 8)) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(oop));
 				referent5 = longAt((oop + (BaseHeaderSize)) + (0 << 2));
@@ -42357,17 +42386,18 @@
 				oop = referent5;
 				longAtput(array1 + fieldOffset, oop);
 			}
+			if ((oop & 3) != 0) {
+				ec = PrimErrInappropriate;
+				goto l3;
+			}
 			if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) {
 				ec = PrimErrObjectIsPinned;
 				goto l3;
 			}
 			effectsFlags = effectsFlags | (becomeEffectFlagsFor(oop));
 			oop = longAt(array2 + fieldOffset);
-			if ((oop & 3) != 0) {
-				ec = PrimErrInappropriate;
-				goto l3;
-			}
-			if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) {
+			if (((oop & 3) == 0)
+			 && (((longAt(oop)) & 0x3FFFFF) == 8)) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(oop));
 				referent11 = longAt((oop + (BaseHeaderSize)) + (0 << 2));
@@ -42378,6 +42408,10 @@
 				oop = referent11;
 				longAtput(array2 + fieldOffset, oop);
 			}
+			if ((oop & 3) != 0) {
+				ec = PrimErrInappropriate;
+				goto l3;
+			}
 			if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) {
 				ec = PrimErrObjectIsPinned;
 				goto l3;
@@ -42436,11 +42470,8 @@
 		effectsFlags1 = 0;
 		while (fieldOffset1 >= (BaseHeaderSize)) {
 			oop1 = longAt(array1 + fieldOffset1);
-			if ((oop1 & 3) != 0) {
-				ec = PrimErrInappropriate;
-				goto l6;
-			}
-			if (((longAt(oop1)) & (0x3FFFFF - 8)) == 0) {
+			if (((oop1 & 3) == 0)
+			 && (((longAt(oop1)) & 0x3FFFFF) == 8)) {
 				/* begin followForwarded: */
 				assert(isUnambiguouslyForwarder(oop1));
 				referent6 = longAt((oop1 + (BaseHeaderSize)) + (0 << 2));
@@ -42451,6 +42482,10 @@
 				oop1 = referent6;
 				longAtput(array1 + fieldOffset1, oop1);
 			}

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list