[Vm-dev] [commit][3245] CogVM source as per VMMaker.oscog-eem.1035

commits at squeakvm.org commits at squeakvm.org
Mon Feb 2 02:24:38 UTC 2015


Revision: 3245
Author:   eliot
Date:     2015-02-01 18:24:35 -0800 (Sun, 01 Feb 2015)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1035

Newspeak:
Refactor absent receiver shuffling in the interpreter to get more common code.

Spur:
Comment more carefully the receiver and supersend forwarding invariants,
and therefore eliminate internalForwardedReceiver.

Update the newspeak AsynchFilePlugin as per VMMaker.oscog-eem.1031.

Modified Paths:
--------------
    branches/Cog/nscogsrc/plugins/AsynchFilePlugin/AsynchFilePlugin.c
    branches/Cog/nscogsrc/vm/cointerp.c
    branches/Cog/nscogsrc/vm/cointerp.h
    branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
    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/sistasrc/vm/cointerp.c
    branches/Cog/sistasrc/vm/cointerp.h
    branches/Cog/sistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spurstack64src/vm/gcc3x-interp.c
    branches/Cog/spurstack64src/vm/interp.c
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    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/plugins/AsynchFilePlugin/AsynchFilePlugin.c
===================================================================
--- branches/Cog/nscogsrc/plugins/AsynchFilePlugin/AsynchFilePlugin.c	2015-01-31 02:15:58 UTC (rev 3244)
+++ branches/Cog/nscogsrc/plugins/AsynchFilePlugin/AsynchFilePlugin.c	2015-02-02 02:24:35 UTC (rev 3245)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	SmartSyntaxPluginCodeGenerator VMMaker.oscog-eem.983 uuid: 4cdca841-6318-4c49-95de-8c47d0d7e91d
+	SmartSyntaxPluginCodeGenerator VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
    from
-	AsynchFilePlugin VMMaker.oscog-eem.983 uuid: 4cdca841-6318-4c49-95de-8c47d0d7e91d
+	AsynchFilePlugin VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
  */
-static char __buildInfo[] = "AsynchFilePlugin VMMaker.oscog-eem.983 uuid: 4cdca841-6318-4c49-95de-8c47d0d7e91d " __DATE__ ;
+static char __buildInfo[] = "AsynchFilePlugin VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57 " __DATE__ ;
 
 
 
@@ -102,9 +102,9 @@
 struct VirtualMachine* interpreterProxy;
 static const char *moduleName =
 #ifdef SQUEAK_BUILTIN_PLUGIN
-	"AsynchFilePlugin VMMaker.oscog-eem.983 (i)"
+	"AsynchFilePlugin VMMaker.oscog-eem.1035 (i)"
 #else
-	"AsynchFilePlugin VMMaker.oscog-eem.983 (e)"
+	"AsynchFilePlugin VMMaker.oscog-eem.1035 (e)"
 #endif
 ;
 static void * sCOAFfn;
@@ -182,6 +182,9 @@
 	primitiveFailFor(PrimErrBadArgument);
 	f = null;
 l1:	/* end asyncFileValueOf: */;
+	if (failed()) {
+		return null;
+	}
 	asyncFileClose(f);
 	if (failed()) {
 		return null;
@@ -287,13 +290,11 @@
 	}
 	success((startIndex >= 1)
 	 && (((startIndex + count) - 1) <= bufferSize));
-
-	/* adjust for zero-origin indexing */
-
+	if (failed()) {
+		return null;
+	}
 	bufferPtr = ((((sqInt) (firstIndexableField(buffer)))) + startIndex) - 1;
-	if (!(failed())) {
-		r = asyncFileReadResult(f, bufferPtr, count);
-	}
+	r = asyncFileReadResult(f, ((void *)bufferPtr), count);
 	_return_value = integerObjectOf(r);
 	if (failed()) {
 		return null;
@@ -325,6 +326,9 @@
 	primitiveFailFor(PrimErrBadArgument);
 	f = null;
 l1:	/* end asyncFileValueOf: */;
+	if (failed()) {
+		return null;
+	}
 	asyncFileReadStart(f, fPosition, count);
 	if (failed()) {
 		return null;
@@ -354,7 +358,10 @@
 	primitiveFailFor(PrimErrBadArgument);
 	f = null;
 l1:	/* end asyncFileValueOf: */;
-	r =  asyncFileWriteResult(f);
+	if (failed()) {
+		return null;
+	}
+	r = asyncFileWriteResult(f);
 	_return_value = integerObjectOf(r);
 	if (failed()) {
 		return null;
@@ -394,9 +401,6 @@
 	primitiveFailFor(PrimErrBadArgument);
 	f = null;
 l1:	/* end asyncFileValueOf: */;
-	if (failed()) {
-		return null;
-	}
 	count = num;
 	startIndex = start;
 
@@ -413,13 +417,11 @@
 	}
 	success((startIndex >= 1)
 	 && (((startIndex + count) - 1) <= bufferSize));
-
-	/* adjust for zero-origin indexing */
-
+	if (failed()) {
+		return null;
+	}
 	bufferPtr = ((((sqInt) (firstIndexableField(buffer)))) + startIndex) - 1;
-	if (!(failed())) {
-		asyncFileWriteStart(f, fPosition, bufferPtr, count);
-	}
+	asyncFileWriteStart(f, fPosition, ((void *)bufferPtr), count);
 	if (failed()) {
 		return null;
 	}

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2015-01-31 02:15:58 UTC (rev 3244)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2015-02-02 02:24:35 UTC (rev 3245)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
    from
-	CoInterpreter VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424
+	CoInterpreter VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -806,6 +806,7 @@
 static sqInt checkHeapIntegrity(void);
 sqInt checkOkayOop(usqInt oop);
 static sqInt checkOopIntegritynamed(sqInt obj, char *name) NoDbgRegParms;
+static sqInt classForClassTag(sqInt classObj) NoDbgRegParms;
 sqInt clone(sqInt obj);
 static double dbgFloatValueOf(sqInt oop) NoDbgRegParms;
 static sqInt defaultEdenBytes(void);
@@ -2097,7 +2098,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1029";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1035";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -2171,6 +2172,7 @@
     sqInt extA;
     sqInt extB;
     sqInt lkupClassTag;
+    sqInt localAbsentReceiver;
     char * localFP;
     char * localIP;
     sqInt localReturnValue;
@@ -4901,6 +4903,7 @@
 			/* dynamicSuperSendBytecode */
 			{
 				sqInt aBehavior;
+				sqInt aValue;
 				sqInt ccIndex;
 				sqInt mClassMixin;
 				sqInt mixin;
@@ -4913,6 +4916,8 @@
 				/* begin literal: */
 				assert(GIV(method) == (iframeMethod(localFP)));
 				GIV(messageSelector) = longAt((GIV(method) + BaseHeaderSize) + (((byteAtPointer(++localIP)) + LiteralStart) << (shiftForWord())));
+				/* begin ensureReceiverUnforwarded */
+				;
 				rcvr = longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop));
 				mClassMixin = methodClassOf(GIV(method));
 				/* begin findApplicationOfTargetMixin:startingAtBehavior: */
@@ -4937,9 +4942,7 @@
 		case 127:
 			/* pushImplicitReceiverBytecode */
 			{
-				sqInt followedReceiver;
 				sqInt object;
-				sqInt rcvr;
 				sqInt selector;
 
 				VM_LABEL(pushImplicitReceiverBytecode);
@@ -4949,12 +4952,8 @@
 				/* begin fetchNextBytecode */
 				currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-				/* begin internalFollowedReceiver */
-				rcvr = longAt(localFP + FoxIFReceiver);
-				
-				followedReceiver = rcvr;
 				/* begin internalPush: */
-				object = implicitReceiverFormixinimplementing(followedReceiver, methodClassOf(GIV(method)), selector);
+				object = implicitReceiverFormixinimplementing(longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)), selector);
 				longAtPointerput((localSP -= BytesPerOop), object);
 			}
 			break;
@@ -5785,6 +5784,7 @@
 		superclassSend:
 			/* superclassSend */
 			{
+				sqInt aValue;
 				sqInt classPointer;
 				sqInt superclass;
 
@@ -5793,7 +5793,15 @@
 				classPointer = methodClassOf(GIV(method));
 				superclass = longAt((classPointer + BaseHeaderSize) + (SuperclassIndex << (shiftForWord())));
 				(((usqInt) (longAt(superclass))) >> HashBitsOffset) & HashMaskUnshifted;
+
+				/* To maintain the invariant that all receivers are unforwarded we need an explicit
+				   read barrier in the super send cases.  Even though we always follow receivers
+				   on become  e.g. super doSomethingWith: (self become: other) forwards the receiver
+				   self pushed on the stack. */
+
 				lkupClassTag = superclass;
+				/* begin ensureReceiverUnforwarded */
+				;
 				assert(lkupClassTag != (nilObject()));
 				goto commonSend;
 			}
@@ -12719,7 +12727,7 @@
 							? (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask
 							: (/* begin fetchPointer:ofObject: */
 								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				assert(lkupClassTag != (nilObject()));
+				assert((classForClassTag(lkupClassTag)) != (nilObject()));
 				goto commonSend;
 			}
 			break;
@@ -12758,37 +12766,36 @@
 		commonSendAbsentImplicit:
 			/* commonSendAbsentImplicit */
 			{
-				sqInt ccIndex;
-				sqInt followedReceiver;
-				sqInt i;
-				sqInt implicitReceiver;
-				sqInt oop;
-				sqInt rcvr;
-
 				VM_LABEL(commonSendAbsentImplicit);
-				/* begin internalFollowedReceiver */
-				rcvr = longAt(localFP + FoxIFReceiver);
+				localAbsentReceiver = implicitReceiverFormixinimplementing(longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)), GIV(messageSelector));
 				
-				followedReceiver = rcvr;
-				implicitReceiver = implicitReceiverFormixinimplementing(followedReceiver, methodClassOf(GIV(method)), GIV(messageSelector));
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
+			commonSendAbsent:
+				/* commonSendAbsent */
+				{
+					sqInt ccIndex;
+					sqInt i;
+					sqInt oop;
 
-				/* a.k.a. self internalPush: anything */
+					VM_LABEL(commonSendAbsent);
+					/* begin shuffleArgumentsAndStoreAbsentReceiver: */
 
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
+					/* a.k.a. self internalPush: anything */
+
+					localSP -= BytesPerOop;
+					for (i = 1; i <= GIV(argumentCount); i += 1) {
+						oop = longAtPointer(localSP + (i * BytesPerOop));
+						longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
+					}
+					longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), localAbsentReceiver);
+					lkupClassTag = ((localAbsentReceiver & 1)
+						? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
+						: (((ccIndex = (((usqInt) (longAt(localAbsentReceiver))) >> (compactClassFieldLSB())) & 0x1F)) == 0
+								? (longAt(localAbsentReceiver - BaseHeaderSize)) & AllButTypeMask
+								: (/* begin fetchPointer:ofObject: */
+									longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
+					assert((classForClassTag(lkupClassTag)) != (nilObject()));
+					goto commonSend;
 				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), implicitReceiver);
-				lkupClassTag = ((implicitReceiver & 1)
-					? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
-					: (((ccIndex = (((usqInt) (longAt(implicitReceiver))) >> (compactClassFieldLSB())) & 0x1F)) == 0
-							? (longAt(implicitReceiver - BaseHeaderSize)) & AllButTypeMask
-							: (/* begin fetchPointer:ofObject: */
-								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				assert(lkupClassTag != (nilObject()));
-				goto commonSend;
 			}
 			break;
 		case 497: /*241*/
@@ -12986,10 +12993,6 @@
 			/* extSendAbsentSelfBytecode */
 			{
 				sqInt byte;
-				sqInt ccIndex;
-				sqInt classObj;
-				sqInt i;
-				sqInt oop;
 
 				VM_LABEL(extSendAbsentSelfBytecode);
 				byte = byteAtPointer(++localIP);
@@ -12999,25 +13002,8 @@
 				extA = 0;
 				GIV(argumentCount) = (byte & 7) + (extB << 3);
 				extB = 0;
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
-
-				/* a.k.a. self internalPush: anything */
-
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
-				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), longAt(localFP + FoxIFReceiver));
-				/* begin classTagForClass: */
-				classObj = (((longAt(localFP + FoxIFReceiver)) & 1)
-					? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
-					: (((ccIndex = (((usqInt) (longAt(longAt(localFP + FoxIFReceiver)))) >> (compactClassFieldLSB())) & 0x1F)) == 0
-							? (longAt((longAt(localFP + FoxIFReceiver)) - BaseHeaderSize)) & AllButTypeMask
-							: (/* begin fetchPointer:ofObject: */
-								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				lkupClassTag = classObj;
-				goto commonSend;
+				localAbsentReceiver = longAt(localFP + FoxIFReceiver);
+				goto commonSendAbsent;
 			}
 			break;
 		case 502: /*246*/
@@ -13140,13 +13126,8 @@
 		case 510: /*254*/
 			/* extSendAbsentOuterBytecode */
 			{
-				sqInt absentReceiver;
 				sqInt byte;
-				sqInt ccIndex;
-				sqInt classObj;
 				sqInt depth;
-				sqInt i;
-				sqInt oop;
 
 				VM_LABEL(extSendAbsentOuterBytecode);
 				byte = byteAtPointer(++localIP);
@@ -13157,26 +13138,8 @@
 				GIV(argumentCount) = (byte & 7) + (extB << 3);
 				extB = 0;
 				depth = byteAtPointer(++localIP);
-				absentReceiver = enclosingObjectAtwithObjectwithMixin(depth, longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)));
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
-
-				/* a.k.a. self internalPush: anything */
-
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
-				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), absentReceiver);
-				/* begin classTagForClass: */
-				classObj = ((absentReceiver & 1)
-					? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
-					: (((ccIndex = (((usqInt) (longAt(absentReceiver))) >> (compactClassFieldLSB())) & 0x1F)) == 0
-							? (longAt(absentReceiver - BaseHeaderSize)) & AllButTypeMask
-							: (/* begin fetchPointer:ofObject: */
-								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				lkupClassTag = classObj;
-				goto commonSend;
+				localAbsentReceiver = enclosingObjectAtwithObjectwithMixin(depth, longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)));
+				goto commonSendAbsent;
 			}
 			break;
 		}
@@ -35401,6 +35364,17 @@
 }
 
 
+/*	Compatibility with SpurObjectMemory. In ObjectMemory there is no
+	distinction between a
+	classTag in the first-level method cache and a class itself. */
+
+static sqInt
+classForClassTag(sqInt classObj)
+{
+	return classObj;
+}
+
+
 /*	Return a shallow copy of the given object. May cause GC.
 	Assume: Oop is a real object, not a small integer.
 	Override to assert it's not a married context and maybe fix cloned

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2015-01-31 02:15:58 UTC (rev 3244)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2015-02-02 02:24:35 UTC (rev 3245)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2015-01-31 02:15:58 UTC (rev 3244)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2015-02-02 02:24:35 UTC (rev 3245)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
    from
-	CoInterpreter VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424
+	CoInterpreter VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1029 uuid: a2c6da7a-d111-4184-bf10-039ed2bea424 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -809,6 +809,7 @@
 static sqInt checkHeapIntegrity(void);
 sqInt checkOkayOop(usqInt oop);
 static sqInt checkOopIntegritynamed(sqInt obj, char *name) NoDbgRegParms;
+static sqInt classForClassTag(sqInt classObj) NoDbgRegParms;
 sqInt clone(sqInt obj);
 static double dbgFloatValueOf(sqInt oop) NoDbgRegParms;
 static sqInt defaultEdenBytes(void);
@@ -2100,7 +2101,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1029";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1035";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -2174,6 +2175,7 @@
     sqInt extA;
     sqInt extB;
     sqInt lkupClassTag;
+    sqInt localAbsentReceiver;
 	register char* localFP FP_REG;
 	register char* localIP IP_REG;
     sqInt localReturnValue;
@@ -4910,6 +4912,7 @@
 			/* dynamicSuperSendBytecode */
 			{
 				sqInt aBehavior;
+				sqInt aValue;
 				sqInt ccIndex;
 				sqInt mClassMixin;
 				sqInt mixin;
@@ -4922,6 +4925,8 @@
 				/* begin literal: */
 				assert(GIV(method) == (iframeMethod(localFP)));
 				GIV(messageSelector) = longAt((GIV(method) + BaseHeaderSize) + (((byteAtPointer(++localIP)) + LiteralStart) << (shiftForWord())));
+				/* begin ensureReceiverUnforwarded */
+				;
 				rcvr = longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop));
 				mClassMixin = methodClassOf(GIV(method));
 				/* begin findApplicationOfTargetMixin:startingAtBehavior: */
@@ -4946,9 +4951,7 @@
 		CASE(127)
 			/* pushImplicitReceiverBytecode */
 			{
-				sqInt followedReceiver;
 				sqInt object;
-				sqInt rcvr;
 				sqInt selector;
 
 				VM_LABEL(pushImplicitReceiverBytecode);
@@ -4958,12 +4961,8 @@
 				/* begin fetchNextBytecode */
 				currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-				/* begin internalFollowedReceiver */
-				rcvr = longAt(localFP + FoxIFReceiver);
-				
-				followedReceiver = rcvr;
 				/* begin internalPush: */
-				object = implicitReceiverFormixinimplementing(followedReceiver, methodClassOf(GIV(method)), selector);
+				object = implicitReceiverFormixinimplementing(longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)), selector);
 				longAtPointerput((localSP -= BytesPerOop), object);
 			}
 			BREAK;
@@ -5794,6 +5793,7 @@
 		superclassSend:
 			/* superclassSend */
 			{
+				sqInt aValue;
 				sqInt classPointer;
 				sqInt superclass;
 
@@ -5802,7 +5802,15 @@
 				classPointer = methodClassOf(GIV(method));
 				superclass = longAt((classPointer + BaseHeaderSize) + (SuperclassIndex << (shiftForWord())));
 				(((usqInt) (longAt(superclass))) >> HashBitsOffset) & HashMaskUnshifted;
+
+				/* To maintain the invariant that all receivers are unforwarded we need an explicit
+				   read barrier in the super send cases.  Even though we always follow receivers
+				   on become  e.g. super doSomethingWith: (self become: other) forwards the receiver
+				   self pushed on the stack. */
+
 				lkupClassTag = superclass;
+				/* begin ensureReceiverUnforwarded */
+				;
 				assert(lkupClassTag != (nilObject()));
 				goto commonSend;
 			}
@@ -12728,7 +12736,7 @@
 							? (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask
 							: (/* begin fetchPointer:ofObject: */
 								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				assert(lkupClassTag != (nilObject()));
+				assert((classForClassTag(lkupClassTag)) != (nilObject()));
 				goto commonSend;
 			}
 			BREAK;
@@ -12767,37 +12775,36 @@
 		commonSendAbsentImplicit:
 			/* commonSendAbsentImplicit */
 			{
-				sqInt ccIndex;
-				sqInt followedReceiver;
-				sqInt i;
-				sqInt implicitReceiver;
-				sqInt oop;
-				sqInt rcvr;
-
 				VM_LABEL(commonSendAbsentImplicit);
-				/* begin internalFollowedReceiver */
-				rcvr = longAt(localFP + FoxIFReceiver);
+				localAbsentReceiver = implicitReceiverFormixinimplementing(longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)), GIV(messageSelector));
 				
-				followedReceiver = rcvr;
-				implicitReceiver = implicitReceiverFormixinimplementing(followedReceiver, methodClassOf(GIV(method)), GIV(messageSelector));
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
+			commonSendAbsent:
+				/* commonSendAbsent */
+				{
+					sqInt ccIndex;
+					sqInt i;
+					sqInt oop;
 
-				/* a.k.a. self internalPush: anything */
+					VM_LABEL(commonSendAbsent);
+					/* begin shuffleArgumentsAndStoreAbsentReceiver: */
 
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
+					/* a.k.a. self internalPush: anything */
+
+					localSP -= BytesPerOop;
+					for (i = 1; i <= GIV(argumentCount); i += 1) {
+						oop = longAtPointer(localSP + (i * BytesPerOop));
+						longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
+					}
+					longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), localAbsentReceiver);
+					lkupClassTag = ((localAbsentReceiver & 1)
+						? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
+						: (((ccIndex = (((usqInt) (longAt(localAbsentReceiver))) >> (compactClassFieldLSB())) & 0x1F)) == 0
+								? (longAt(localAbsentReceiver - BaseHeaderSize)) & AllButTypeMask
+								: (/* begin fetchPointer:ofObject: */
+									longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
+					assert((classForClassTag(lkupClassTag)) != (nilObject()));
+					goto commonSend;
 				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), implicitReceiver);
-				lkupClassTag = ((implicitReceiver & 1)
-					? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
-					: (((ccIndex = (((usqInt) (longAt(implicitReceiver))) >> (compactClassFieldLSB())) & 0x1F)) == 0
-							? (longAt(implicitReceiver - BaseHeaderSize)) & AllButTypeMask
-							: (/* begin fetchPointer:ofObject: */
-								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				assert(lkupClassTag != (nilObject()));
-				goto commonSend;
 			}
 			BREAK;
 		CASE(497) /*241*/
@@ -12995,10 +13002,6 @@
 			/* extSendAbsentSelfBytecode */
 			{
 				sqInt byte;
-				sqInt ccIndex;
-				sqInt classObj;
-				sqInt i;
-				sqInt oop;
 
 				VM_LABEL(extSendAbsentSelfBytecode);
 				byte = byteAtPointer(++localIP);
@@ -13008,25 +13011,8 @@
 				extA = 0;
 				GIV(argumentCount) = (byte & 7) + (extB << 3);
 				extB = 0;
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
-
-				/* a.k.a. self internalPush: anything */
-
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
-				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), longAt(localFP + FoxIFReceiver));
-				/* begin classTagForClass: */
-				classObj = (((longAt(localFP + FoxIFReceiver)) & 1)
-					? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
-					: (((ccIndex = (((usqInt) (longAt(longAt(localFP + FoxIFReceiver)))) >> (compactClassFieldLSB())) & 0x1F)) == 0
-							? (longAt((longAt(localFP + FoxIFReceiver)) - BaseHeaderSize)) & AllButTypeMask
-							: (/* begin fetchPointer:ofObject: */
-								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				lkupClassTag = classObj;
-				goto commonSend;
+				localAbsentReceiver = longAt(localFP + FoxIFReceiver);
+				goto commonSendAbsent;
 			}
 			BREAK;
 		CASE(502) /*246*/
@@ -13149,13 +13135,8 @@
 		CASE(510) /*254*/
 			/* extSendAbsentOuterBytecode */
 			{
-				sqInt absentReceiver;
 				sqInt byte;
-				sqInt ccIndex;
-				sqInt classObj;
 				sqInt depth;
-				sqInt i;
-				sqInt oop;
 
 				VM_LABEL(extSendAbsentOuterBytecode);
 				byte = byteAtPointer(++localIP);
@@ -13166,26 +13147,8 @@
 				GIV(argumentCount) = (byte & 7) + (extB << 3);
 				extB = 0;
 				depth = byteAtPointer(++localIP);
-				absentReceiver = enclosingObjectAtwithObjectwithMixin(depth, longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)));
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
-
-				/* a.k.a. self internalPush: anything */
-
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
-				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), absentReceiver);
-				/* begin classTagForClass: */
-				classObj = ((absentReceiver & 1)
-					? longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassSmallInteger << (shiftForWord())))
-					: (((ccIndex = (((usqInt) (longAt(absentReceiver))) >> (compactClassFieldLSB())) & 0x1F)) == 0
-							? (longAt(absentReceiver - BaseHeaderSize)) & AllButTypeMask
-							: (/* begin fetchPointer:ofObject: */
-								longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << (shiftForWord())))) + BaseHeaderSize) + ((ccIndex - 1) << (shiftForWord()))))));
-				lkupClassTag = classObj;
-				goto commonSend;
+				localAbsentReceiver = enclosingObjectAtwithObjectwithMixin(depth, longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)));
+				goto commonSendAbsent;
 			}
 			BREAK;
 		}
@@ -35410,6 +35373,17 @@
 }
 
 
+/*	Compatibility with SpurObjectMemory. In ObjectMemory there is no
+	distinction between a
+	classTag in the first-level method cache and a class itself. */
+
+static sqInt
+classForClassTag(sqInt classObj)
+{
+	return classObj;
+}
+
+
 /*	Return a shallow copy of the given object. May cause GC.
 	Assume: Oop is a real object, not a small integer.
 	Override to assert it's not a married context and maybe fix cloned

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2015-01-31 02:15:58 UTC (rev 3244)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2015-02-02 02:24:35 UTC (rev 3245)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1034 uuid: 1a93b31c-cf2c-4a2c-b53f-9eae1d7863c7
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
    from
-	CoInterpreter VMMaker.oscog-eem.1034 uuid: 1a93b31c-cf2c-4a2c-b53f-9eae1d7863c7
+	CoInterpreter VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1034 uuid: 1a93b31c-cf2c-4a2c-b53f-9eae1d7863c7 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1035 uuid: 33a34378-0618-40c7-8fbb-c467fb40fc57 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2353,7 +2353,7 @@
 /*560*/	-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1
 	};
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1034";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1035";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -2430,6 +2430,7 @@
     sqInt extA;
     sqInt extB;
     sqInt lkupClassTag;
+    sqInt localAbsentReceiver;
     char * localFP;
     char * localIP;
     sqInt localReturnValue;
@@ -5102,7 +5103,7 @@
 
 				if (!((byteAt((localFP + FoxIFrameFlags) + 3)) != 0)) {
 					goto commonCallerReturn;
-					goto l256;
+					goto l250;
 				}
 				closure = longAt(localFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(localFP + FoxMethod)))) < (startOfMemory())
 	? ((mframeCogMethod(localFP))->cmNumArgs)
@@ -5155,10 +5156,10 @@
 						: (byteAt((localFP + FoxIFrameFlags) + 2)) != 0)) {
 						assert(isContext(frameContext(localFP)));
 						ourContext = longAt(localFP + FoxThisContext);
-						goto l260;
+						goto l254;
 					}
 					ourContext = marryFrameSP(localFP, localSP);
-				l260:	/* end ensureFrameIsMarried:SP: */;
+				l254:	/* end ensureFrameIsMarried:SP: */;
 					/* begin internalPush: */
 					longAtPointerput((localSP -= BytesPerOop), ourContext);
 					/* begin internalPush: */
@@ -5167,7 +5168,7 @@
 					GIV(argumentCount) = 1;
 					goto normalSend;
 					/* return self */
-					goto l256;
+					goto l250;
 				}
 				if (unwindContextOrNilOrZero != 0) {
 					/* begin internalAboutToReturn:through: */
@@ -5177,10 +5178,10 @@
 						: (byteAt((localFP + FoxIFrameFlags) + 2)) != 0)) {
 						assert(isContext(frameContext(localFP)));
 						ourContext1 = longAt(localFP + FoxThisContext);
-						goto l257;
+						goto l251;
 					}
 					ourContext1 = marryFrameSP(localFP, localSP);
-				l257:	/* end ensureFrameIsMarried:SP: */;
+				l251:	/* end ensureFrameIsMarried:SP: */;
 					/* begin internalPush: */
 					longAtPointerput((localSP -= BytesPerOop), ourContext1);
 					/* begin internalPush: */
@@ -5191,7 +5192,7 @@
 					GIV(argumentCount) = 2;
 					goto normalSend;
 					/* return self */
-					goto l256;
+					goto l250;
 				}
 				contextToReturnTo = null;
 				if (((longAt((home + BaseHeaderSize) + (SenderIndex << (shiftForWord())))) & 1)) {
@@ -5248,10 +5249,10 @@
 							: (byteAt((localFP + FoxIFrameFlags) + 2)) != 0)) {
 							assert(isContext(frameContext(localFP)));
 							ourContext2 = longAt(localFP + FoxThisContext);
-							goto l259;
+							goto l253;
 						}
 						ourContext2 = marryFrameSP(localFP, localSP);
-					l259:	/* end ensureFrameIsMarried:SP: */;
+					l253:	/* end ensureFrameIsMarried:SP: */;
 						/* begin internalPush: */
 						longAtPointerput((localSP -= BytesPerOop), ourContext2);
 						/* begin internalPush: */
@@ -5260,7 +5261,7 @@
 						GIV(argumentCount) = 1;
 						goto normalSend;
 						/* return self */
-						goto l256;
+						goto l250;
 					}
 				}
 				assert(pageListIsWellFormed());
@@ -5379,11 +5380,11 @@
 						GIV(framePointer) = localFP;
 						
 						ceEnterCogCodePopReceiverReg();
-						goto l258;
+						goto l252;
 					}
 					localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
 				}
-			l258:	/* end maybeReturnToMachineCodeFrame */;
+			l252:	/* end maybeReturnToMachineCodeFrame */;
 				/* begin setMethod: */
 				assert((((usqInt)(longAt(localFP + FoxMethod)))) >= (startOfMemory()));
 				GIV(method) = longAt(localFP + FoxMethod);
@@ -5397,7 +5398,7 @@
 
 				longAtPointerput(localSP, localReturnValue);
 			}
-		l256:	/* end case */;
+		l250:	/* end case */;
 			break;
 		case 121:
 			/* returnTrue */
@@ -5516,27 +5517,27 @@
 							fp = (thePage->headFP);
 							if (fp == theFP) {
 								frameAbove = 0;
-								goto l263;
+								goto l257;
 							}
 							while (((callerFP = frameCallerFP(fp))) != 0) {
 								if (callerFP == theFP) {
 									frameAbove = fp;
-									goto l263;
+									goto l257;
 								}
 								fp = callerFP;
 							}
 							error("did not find theFP in stack page");
 							frameAbove = 0;
-						l263:	/* end findFrameAbove:inPage: */;
+						l257:	/* end findFrameAbove:inPage: */;
 							/* begin newStackPage */
 							lruOrFree = ((mostRecentlyUsedPage())->nextPage);
 							if (isFree(lruOrFree)) {
 								newPage = lruOrFree;
-								goto l264;
+								goto l258;
 							}
 							divorceFramesIn(lruOrFree);
 							newPage = lruOrFree;
-						l264:	/* end newStackPage */;
+						l258:	/* end newStackPage */;
 							assert(newPage == GIV(stackPage));
 							moveFramesInthroughtoPage(thePage, frameAbove, newPage);
 							markStackPageMostRecentlyUsed(newPage);
@@ -5560,7 +5561,7 @@
 							longAtput((sp2 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 							GIV(stackPointer) = sp2;
 							ceSendAborttonumArgs(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorCannotReturn << (shiftForWord()))), contextToReturnFrom, 1);
-							goto l262;
+							goto l256;
 						}
 						GIV(instructionPointer) = 0;
 						thePage = makeBaseFrameFor(contextToReturnTo);
@@ -5598,7 +5599,7 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
-							goto l262;
+							goto l256;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
 					}
@@ -5616,8 +5617,8 @@
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
 					/* return self */
-				l262:	/* end baseFrameReturn */;
-					goto l261;
+				l256:	/* end baseFrameReturn */;
+					goto l255;
 				}
 				/* begin frameCallerSavedIP: */
 				localIP = pointerForOop(longAt(localFP + FoxCallerSavedIP));
@@ -5645,7 +5646,7 @@
 						GIV(framePointer) = localFP;
 						
 						ceEnterCogCodePopReceiverReg();
-						goto l261;
+						goto l255;
 					}
 					localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
 				}
@@ -5662,12 +5663,13 @@
 
 				longAtPointerput(localSP, localReturnValue);
 			}
-		l261:	/* end case */;
+		l255:	/* end case */;
 			break;
 		case 126:
 			/* dynamicSuperSendBytecode */
 			{
 				sqInt aBehavior;
+				sqInt aValue;
 				sqInt classIndex;
 				sqInt classObj;
 				sqInt classTablePage;
@@ -5678,7 +5680,9 @@
 				sqInt mixinApplication1;
 				sqInt newHash;
 				sqInt objOop;
+				sqInt objOop1;
 				sqInt rcvr;
+				sqInt referent;
 				sqInt tagBits;
 
 				VM_LABEL(dynamicSuperSendBytecode);
@@ -5686,6 +5690,21 @@
 				/* begin literal: */
 				assert(GIV(method) == (iframeMethod(localFP)));
 				GIV(messageSelector) = longAt((GIV(method) + BaseHeaderSize) + (((byteAtPointer(++localIP)) + LiteralStart) << (shiftForWord())));
+				/* begin ensureReceiverUnforwarded */
+				if ((((longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop))) & 3) == 0)
+				 && (((longAt(longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop)))) & 0x3FFFFF) == 8)) {
+					/* begin internalStackValue:put: */
+					/* begin followForwarded: */
+					objOop1 = longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop));
+					assert(isUnambiguouslyForwarder(objOop1));
+					referent = longAt((objOop1 + BaseHeaderSize) + (0 << (shiftForWord())));
+					while (((referent & 3) == 0)
+					 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
+						referent = longAt((referent + BaseHeaderSize) + (0 << (shiftForWord())));
+					}
+					aValue = referent;
+					longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), aValue);
+				}
 				rcvr = longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop));
 				mClassMixin = methodClassOf(GIV(method));
 				/* begin findApplicationOfTargetMixin:startingAtBehavior: */
@@ -5755,10 +5774,7 @@
 		case 127:
 			/* pushImplicitReceiverBytecode */
 			{
-				sqInt followedReceiver;
 				sqInt object;
-				sqInt rcvr;
-				sqInt referent;
 				sqInt selector;
 
 				VM_LABEL(pushImplicitReceiverBytecode);
@@ -5768,23 +5784,8 @@
 				/* begin fetchNextBytecode */
 				currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-				/* begin internalFollowedReceiver */
-				rcvr = longAt(localFP + FoxIFReceiver);
-				if (((rcvr & 3) == 0)
-				 && (((longAt(rcvr)) & 0x3FFFFF) == 8)) {
-					/* begin followForwarded: */
-					assert(isUnambiguouslyForwarder(rcvr));
-					referent = longAt((rcvr + BaseHeaderSize) + (0 << (shiftForWord())));
-					while (((referent & 3) == 0)
-					 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
-						referent = longAt((referent + BaseHeaderSize) + (0 << (shiftForWord())));
-					}
-					rcvr = referent;
-					longAtput(localFP + FoxIFReceiver, rcvr);
-				}
-				followedReceiver = rcvr;
 				/* begin internalPush: */
-				object = implicitReceiverFormixinimplementing(followedReceiver, methodClassOf(GIV(method)), selector);
+				object = implicitReceiverFormixinimplementing(longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)), selector);
 				longAtPointerput((localSP -= BytesPerOop), object);
 			}
 			break;
@@ -6052,10 +6053,10 @@
 					lkupClassTag = ((tagBits & 1) != 0
 						? 1
 						: tagBits);
-					goto l265;
+					goto l259;
 				}
 				lkupClassTag = (longAt(rcvr)) & 0x3FFFFF;
-			l265:	/* end fetchClassTagOf: */;
+			l259:	/* end fetchClassTagOf: */;
 				assert(lkupClassTag != (nilObject()));
 				
 			commonSend:
@@ -6098,10 +6099,10 @@
 						classTablePage = longAt((GIV(hiddenRootsObj) + BaseHeaderSize) + ((((usqInt) lkupClassTag) >> 10) << (shiftForWord())));
 						if (classTablePage == GIV(nilObj)) {
 							classOrInteger = null;
-							goto l272;
+							goto l266;
 						}
 						classOrInteger = longAt((classTablePage + BaseHeaderSize) + ((lkupClassTag & ((1 << 10) - 1)) << (shiftForWord())));
-					l272:	/* end classAtIndex: */;
+					l266:	/* end classAtIndex: */;
 						GIV(traceLog)[GIV(traceLogIndex)] = classOrInteger;
 						GIV(traceLog)[GIV(traceLogIndex) + 1] = GIV(messageSelector);
 						GIV(traceLog)[GIV(traceLogIndex) + 2] = TraceIsFromInterpreter;
@@ -6127,7 +6128,7 @@
 						GIV(newMethod) = GIV(methodCache)[probe + MethodCacheMethod];
 						primitiveFunctionPointer = ((void (*)()) (GIV(methodCache)[probe + MethodCachePrimFunction]));
 						ok = 1;
-						goto l267;
+						goto l261;
 					}
 
 					/* second probe */
@@ -6138,7 +6139,7 @@
 						GIV(newMethod) = GIV(methodCache)[probe + MethodCacheMethod];
 						primitiveFunctionPointer = ((void (*)()) (GIV(methodCache)[probe + MethodCachePrimFunction]));
 						ok = 1;
-						goto l267;
+						goto l261;
 					}
 					probe = (((usqInt) hash) >> 2) & MethodCacheMask;
 					if (((GIV(methodCache)[probe + MethodCacheSelector]) == GIV(messageSelector))
@@ -6146,10 +6147,10 @@
 						GIV(newMethod) = GIV(methodCache)[probe + MethodCacheMethod];
 						primitiveFunctionPointer = ((void (*)()) (GIV(methodCache)[probe + MethodCachePrimFunction]));
 						ok = 1;
-						goto l267;
+						goto l261;
 					}
 					ok = 0;
-				l267:	/* end inlineLookupInMethodCacheSel:classTag: */;
+				l261:	/* end inlineLookupInMethodCacheSel:classTag: */;
 					if (ok) {
 						/* begin ifAppropriateCompileToNativeCode:selector: */
 						methodHeader2 = longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << (shiftForWord())));
@@ -6207,7 +6208,7 @@
 										maybeFlagMethodAsInterpreted(GIV(newMethod));
 									}
 								}
-								goto l270;
+								goto l264;
 							}
 						}
 						/* begin classForClassTag: */
@@ -6218,10 +6219,10 @@
 						classTablePage1 = longAt((GIV(hiddenRootsObj) + BaseHeaderSize) + ((((usqInt) lkupClassTag) >> 10) << (shiftForWord())));
 						if (classTablePage1 == GIV(nilObj)) {
 							GIV(lkupClass) = null;
-							goto l266;
+							goto l260;
 						}
 						GIV(lkupClass) = longAt((classTablePage1 + BaseHeaderSize) + ((lkupClassTag & ((1 << 10) - 1)) << (shiftForWord())));
-					l266:	/* end classAtIndex: */;
+					l260:	/* end classAtIndex: */;
 						lookupMethodInClass(GIV(lkupClass));
 						/* begin internalizeIPandSP */
 						assert(GIV(instructionPointer) != (ceReturnToInterpreterPC()));
@@ -6230,7 +6231,7 @@
 						localFP = pointerForOop(GIV(framePointer));
 						addNewMethodToCache(GIV(lkupClass));
 					}
-				l270:	/* end internalFindNewMethod */;
+				l264:	/* end internalFindNewMethod */;
 					/* begin internalExecuteNewMethod */
 					if (primitiveFunctionPointer != 0) {
 						if ((((unsigned long) primitiveFunctionPointer)) <= MaxQuickPrimitiveIndex) {
@@ -6243,31 +6244,31 @@
 								/* begin internalStackTopPut: */
 								longAtPointerput(localSP, longAt(((longAtPointer(localSP)) + BaseHeaderSize) + ((localPrimIndex - 264) << (shiftForWord()))));
 								1;
-								goto l268;
+								goto l262;
 							}
 							if (localPrimIndex == 256) {
 								1;
-								goto l268;
+								goto l262;
 							}
 							if (localPrimIndex == 257) {
 								longAtPointerput(localSP, GIV(trueObj));
 								1;
-								goto l268;
+								goto l262;
 							}
 							if (localPrimIndex == 258) {
 								longAtPointerput(localSP, GIV(falseObj));
 								1;
-								goto l268;
+								goto l262;
 							}
 							if (localPrimIndex == 259) {
 								longAtPointerput(localSP, GIV(nilObj));
 								1;
-								goto l268;
+								goto l262;
 							}
 							longAtPointerput(localSP, (((localPrimIndex - 261) << 1) | 1));
 							1;
-						l268:	/* end internalQuickPrimitiveResponse */;
-							goto l269;
+						l262:	/* end internalQuickPrimitiveResponse */;
+							goto l263;
 						}
 						/* begin externalizeIPandSP */
 						assert((((usqInt)localIP)) != (ceReturnToInterpreterPC()));
@@ -6331,7 +6332,7 @@
 							returntoExecutive(popStack(), 1);
 							browserPluginReturnIfNeeded();
 							null;
-							goto l269;
+							goto l263;
 						}
 					}
 					if (methodHasCogMethod(GIV(newMethod))) {
@@ -6408,11 +6409,11 @@
 										table = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (PrimErrTableIndex << (shiftForWord())));
 										if (GIV(primFailCode) <= ((lastPointerOf(table)) / BytesPerWord)) {
 											errorCode = longAt((table + BaseHeaderSize) + ((GIV(primFailCode) - 1) << (shiftForWord())));
-											goto l271;
+											goto l265;
 										}
 									}
 									errorCode = ((GIV(primFailCode) << 1) | 1);
-								l271:	/* end getErrorObjectFromPrimFailCode */;
+								l265:	/* end getErrorObjectFromPrimFailCode */;
 									longAtPointerput(localSP, errorCode);
 								}
 								GIV(primFailCode) = 0;
@@ -6436,7 +6437,7 @@
 							localFP = pointerForOop(GIV(framePointer));
 						}
 					}
-				l269:	/* end internalExecuteNewMethod */;
+				l263:	/* end internalExecuteNewMethod */;
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
@@ -6817,12 +6818,15 @@
 		superclassSend:
 			/* superclassSend */
 			{
+				sqInt aValue;
 				sqInt classPointer;
 				sqInt err;
 				sqInt err1;
 				sqInt newHash;
 				sqInt newHash1;
 				sqInt objOop;
+				sqInt objOop1;
+				sqInt referent;
 				sqInt superclass;
 
 				VM_LABEL(superclassSend);
@@ -6840,17 +6844,17 @@
 				if (((newHash = (long32At(superclass + 4)) & 0x3FFFFF)) == 0) {
 					if (!(objCouldBeClassObj(superclass))) {
 						-PrimErrBadReceiver;
-						goto l273;
+						goto l267;
 					}
 					if (((err = enterIntoClassTable(superclass))) != 0) {
 						-err;
-						goto l273;
+						goto l267;
 					}
 					newHash = (long32At(superclass + 4)) & 0x3FFFFF;
 					assert((classAtIndex(newHash)) == superclass);
 				}
 				newHash;
-			l273:	/* end ensureBehaviorHash: */;
+			l267:	/* end ensureBehaviorHash: */;
 				/* begin classTagForClass: */
 				assert(addressCouldBeClassObj(superclass));
 				/* begin ensureBehaviorHash: */
@@ -6858,17 +6862,32 @@
 				if (((newHash1 = (long32At(superclass + 4)) & 0x3FFFFF)) == 0) {
 					if (!(objCouldBeClassObj(superclass))) {
 						lkupClassTag = -PrimErrBadReceiver;
-						goto l274;
+						goto l268;
 					}
 					if (((err1 = enterIntoClassTable(superclass))) != 0) {
 						lkupClassTag = -err1;
-						goto l274;
+						goto l268;
 					}
 					newHash1 = (long32At(superclass + 4)) & 0x3FFFFF;
 					assert((classAtIndex(newHash1)) == superclass);
 				}
 				lkupClassTag = newHash1;
-			l274:	/* end ensureBehaviorHash: */;
+			l268:	/* end ensureBehaviorHash: */;
+				/* begin ensureReceiverUnforwarded */
+				if ((((longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop))) & 3) == 0)
+				 && (((longAt(longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop)))) & 0x3FFFFF) == 8)) {
+					/* begin internalStackValue:put: */
+					/* begin followForwarded: */
+					objOop1 = longAtPointer(localSP + (GIV(argumentCount) * BytesPerOop));
+					assert(isUnambiguouslyForwarder(objOop1));
+					referent = longAt((objOop1 + BaseHeaderSize) + (0 << (shiftForWord())));
+					while (((referent & 3) == 0)
+					 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
+						referent = longAt((referent + BaseHeaderSize) + (0 << (shiftForWord())));
+					}
+					aValue = referent;
+					longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), aValue);
+				}
 				assert(lkupClassTag != (nilObject()));
 				goto commonSend;
 			}
@@ -7870,7 +7889,7 @@
 						/* begin fetchNextBytecode */
 						currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-						goto l275;
+						goto l269;
 					}
 					if (bytecode == 172) {
 
@@ -7880,7 +7899,7 @@
 						/* begin fetchNextBytecode */
 						currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-						goto l275;
+						goto l269;
 					}
 					if (bytecode > 167) {
 
@@ -7891,7 +7910,7 @@
 						localIP = (localIP + offset) + 1;
 						currentBytecode = (byteAtPointer(localIP)) + GIV(bytecodeSetSelector);
 
-						goto l275;
+						goto l269;
 					}
 				}
 				currentBytecode = bytecode + GIV(bytecodeSetSelector);
@@ -7899,7 +7918,7 @@
 				/* begin internalPush: */
 				longAtPointerput((localSP -= BytesPerOop), GIV(trueObj));
 			}
-		l275:	/* end case */;
+		l269:	/* end case */;
 			break;
 		case 179:
 			/* bytecodePrimGreaterThan */
@@ -8016,7 +8035,7 @@
 					localIP = (localIP + (bytecode - 151)) + 1;
 					currentBytecode = (byteAtPointer(localIP)) + GIV(bytecodeSetSelector);
 
-					goto l276;
+					goto l270;
 				}
 				if (bytecode == 172) {
 
@@ -8027,14 +8046,14 @@
 					localIP = (localIP + offset) + 1;
 					currentBytecode = (byteAtPointer(localIP)) + GIV(bytecodeSetSelector);
 
-					goto l276;
+					goto l270;
 				}
 				currentBytecode = bytecode + GIV(bytecodeSetSelector);
 
 				/* begin internalPush: */
 				longAtPointerput((localSP -= BytesPerOop), GIV(falseObj));
 			}
-		l276:	/* end case */;
+		l270:	/* end case */;
 			break;
 		case 180:
 			/* bytecodePrimLessOrEqual */
@@ -10616,7 +10635,7 @@
 						/* begin fetchNextBytecode */
 						currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-						goto l277;
+						goto l271;
 					}
 					if (bytecode == 244) {
 
@@ -10626,7 +10645,7 @@
 						/* begin fetchNextBytecode */
 						currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-						goto l277;
+						goto l271;
 					}
 					if (bytecode == 243) {
 
@@ -10637,7 +10656,7 @@
 						localIP = (localIP + offset) + 1;
 						currentBytecode = (byteAtPointer(localIP)) + GIV(bytecodeSetSelector);
 
-						goto l277;
+						goto l271;
 					}
 				}
 				currentBytecode = bytecode + GIV(bytecodeSetSelector);
@@ -10645,7 +10664,7 @@
 				/* begin internalPush: */
 				longAtPointerput((localSP -= BytesPerOop), GIV(trueObj));
 			}
-		l277:	/* end case */;
+		l271:	/* end case */;
 			break;
 		case 339: /*83*/
 			/* bytecodePrimGreaterThanV4 */
@@ -10762,7 +10781,7 @@
 					localIP = (localIP + (bytecode - 207)) + 1;
 					currentBytecode = (byteAtPointer(localIP)) + GIV(bytecodeSetSelector);
 
-					goto l278;
+					goto l272;
 				}
 				if (bytecode == 244) {
 
@@ -10773,14 +10792,14 @@
 					localIP = (localIP + offset) + 1;
 					currentBytecode = (byteAtPointer(localIP)) + GIV(bytecodeSetSelector);
 
-					goto l278;
+					goto l272;
 				}
 				currentBytecode = bytecode + GIV(bytecodeSetSelector);
 
 				/* begin internalPush: */
 				longAtPointerput((localSP -= BytesPerOop), GIV(falseObj));
 			}
-		l278:	/* end case */;
+		l272:	/* end case */;
 			break;
 		case 340: /*84*/
 			/* bytecodePrimLessOrEqualV4 */
@@ -13077,10 +13096,10 @@
 					: (byteAt((localFP + FoxIFrameFlags) + 2)) != 0)) {
 					assert(isContext(frameContext(localFP)));
 					ourContext = longAt(localFP + FoxThisContext);
-					goto l279;
+					goto l273;
 				}
 				ourContext = marryFrameSP(localFP, localSP);
-			l279:	/* end ensureFrameIsMarried:SP: */;
+			l273:	/* end ensureFrameIsMarried:SP: */;
 				localIP -= 1;
 				/* begin internalPush: */
 				longAtPointerput((localSP -= BytesPerOop), ourContext);
@@ -13848,7 +13867,7 @@
 				}
 				lkupClassTag = (longAt(rcvr)) & 0x3FFFFF;
 			l240:	/* end fetchClassTagOf: */;
-				assert(lkupClassTag != (nilObject()));
+				assert((classForClassTag(lkupClassTag)) != (nilObject()));
 				goto commonSend;
 			}
 			break;
@@ -13887,52 +13906,39 @@
 		commonSendAbsentImplicit:
 			/* commonSendAbsentImplicit */
 			{
-				sqInt followedReceiver;
-				sqInt i;
-				sqInt implicitReceiver;
-				sqInt oop;
-				sqInt rcvr;
-				sqInt referent;
-				sqInt tagBits;
-
 				VM_LABEL(commonSendAbsentImplicit);
-				/* begin internalFollowedReceiver */
-				rcvr = longAt(localFP + FoxIFReceiver);
-				if (((rcvr & 3) == 0)
-				 && (((longAt(rcvr)) & 0x3FFFFF) == 8)) {
-					/* begin followForwarded: */
-					assert(isUnambiguouslyForwarder(rcvr));
-					referent = longAt((rcvr + BaseHeaderSize) + (0 << (shiftForWord())));
-					while (((referent & 3) == 0)
-					 && (((longAt(referent)) & 0x3FFFFF) == 8)) {
-						referent = longAt((referent + BaseHeaderSize) + (0 << (shiftForWord())));
-					}
-					rcvr = referent;
-					longAtput(localFP + FoxIFReceiver, rcvr);
-				}
-				followedReceiver = rcvr;
-				implicitReceiver = implicitReceiverFormixinimplementing(followedReceiver, methodClassOf(GIV(method)), GIV(messageSelector));
-				/* begin shuffleArgumentsAndStoreAbsentReceiver: */
+				localAbsentReceiver = implicitReceiverFormixinimplementing(longAt(localFP + FoxIFReceiver), methodClassOf(GIV(method)), GIV(messageSelector));
+				
+			commonSendAbsent:
+				/* commonSendAbsent */
+				{
+					sqInt i;
+					sqInt oop;
+					sqInt tagBits;
 
-				/* a.k.a. self internalPush: anything */
+					VM_LABEL(commonSendAbsent);
+					/* begin shuffleArgumentsAndStoreAbsentReceiver: */
 
-				localSP -= BytesPerOop;
-				for (i = 1; i <= GIV(argumentCount); i += 1) {
-					oop = longAtPointer(localSP + (i * BytesPerOop));
-					longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
+					/* a.k.a. self internalPush: anything */
+
+					localSP -= BytesPerOop;
+					for (i = 1; i <= GIV(argumentCount); i += 1) {
+						oop = longAtPointer(localSP + (i * BytesPerOop));
+						longAtPointerput(localSP + ((i - 1) * BytesPerOop), oop);
+					}
+					longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), localAbsentReceiver);
+					/* begin fetchClassTagOf: */
+					if (((tagBits = localAbsentReceiver & 3)) != 0) {
+						lkupClassTag = ((tagBits & 1) != 0
+							? 1
+							: tagBits);
+						goto l274;
+					}
+					lkupClassTag = (longAt(localAbsentReceiver)) & 0x3FFFFF;
+				l274:	/* end fetchClassTagOf: */;
+					assert((classForClassTag(lkupClassTag)) != (nilObject()));
+					goto commonSend;
 				}
-				longAtPointerput(localSP + (GIV(argumentCount) * BytesPerOop), implicitReceiver);
-				/* begin fetchClassTagOf: */
-				if (((tagBits = implicitReceiver & 3)) != 0) {
-					lkupClassTag = ((tagBits & 1) != 0
-						? 1
-						: tagBits);
-					goto l280;
-				}
-				lkupClassTag = (longAt(implicitReceiver)) & 0x3FFFFF;

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list