[Vm-dev] [commit][3163] CogVM source as per VMMaker.oscog-eem.972

commits at squeakvm.org commits at squeakvm.org
Sat Dec 6 20:31:50 UTC 2014


Revision: 3163
Author:   eliot
Date:     2014-12-06 12:31:43 -0800 (Sat, 06 Dec 2014)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.972

Fix a devilishly tricky bug with 32-bit Spur and PICs in the Cogit.  In 32-bit
Spur only zero is a valid cache tag, that for Characters, due to SmallIntegers
having both 2r11 and 2r01 as valid tags.  The cache check prolog collapses
these down onto 1 by anding with 1 and hence collapses Character's 2r10 to 0.

The cache tag is also tested in the PIC abort routine to distinguish between
an MNU abort and an interpret abort.  A PIC MNU entry jumps to code that first
zeros the cache tag (held in ClassReg) before calling the abort routine, which
tests ClassReg and selects the relevant abort processing.

Hence in 32-bit Spur if a send site is linked for Character and later extended
to a PIC with an interpret case, that interpret case will instead invoke MNU
processing.  This is rare; first there needs to be a send to a CHaracter, then
a send to something else which binds to something that must be interpreted.
Ouch.

The fix is simple; if a send site that was linked with a zero cache tag (which
can only happen in 32-bit Spur) link to an open PIC instead of to a closed PIC,
or in the case of an MNU do not link.

Changes:
Rename compilePICProlog:, mnuCall and interpretCall to the more accurate
compilePICAbort:, picMNUAbort and picInterpretAbort.  Coment compilePICAbort:
and compileAbort. Name the zero value picAbortDiscriminatorValue to make the
code more comprehensible/browsable.

Assert that the cache tag is not zero in ceCPICMiss:...

Refactor cogMNUPICSelector:methodOperand:numArgs: to add receiver: parameter
for the check for a zero cache tag.

Eliminate some duplication introduced in early versions of the ARM abort code.
Specifically lose sendMissCall mnuCall interpretCall & interpretLabel.

Fix type regression in cogMethodOf: with cCoerceSimple:to:; CogClass's version
should be marked <doNotGenerate>.

Fix type warnings in primitiveCopyObject and printStackCallStackOf:.

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/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/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/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-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nscogsrc/vm/cogit.c	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92
+	CCodeGenerator VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92
+	StackToRegisterMappingCogit VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -609,12 +609,12 @@
 static sqInt cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) NoDbgRegParms;
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
-CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
+CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs);
 static CogMethod * cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) NoDbgRegParms;
 static CogMethod * cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) NoDbgRegParms;
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
-static void compileAbort(void);
+static AbstractInstruction * compileAbort(void);
 static sqInt compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) NoDbgRegParms;
 static void compileBlockEntry(BlockStart *blockStart) NoDbgRegParms;
 static void compileCallFornumArgsargargargargresultRegsaveRegs(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNil, sqInt saveRegs) NoDbgRegParms;
@@ -624,7 +624,7 @@
 static void compileEntry(void);
 static sqInt compileMethodBody(void);
 static sqInt compileMNUCPICmethodOperandnumArgs(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs) NoDbgRegParms;
-static sqInt compilePICProlog(sqInt numArgs) NoDbgRegParms;
+static sqInt compilePICAbort(sqInt numArgs) NoDbgRegParms;
 static sqInt compilePrimitive(void);
 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);
@@ -746,6 +746,7 @@
 static AbstractInstruction * gPushCw(sqInt wordConstant) NoDbgRegParms;
 sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver);
 sqInt pcisWithinMethod(char *address, CogMethod *cogMethod);
+static sqInt picAbortDiscriminatorValue(void);
 static PrimitiveDescriptor * primitiveGeneratorOrNil(void);
 void printCogMethodFor(void *address);
 void printTrampolineTable(void);
@@ -1765,8 +1766,6 @@
 static sqInt inBlock;
 static sqInt indexOfIRC;
 static sqInt initialPC;
-static AbstractInstruction * interpretCall;
-static AbstractInstruction * interpretLabel;
 static int labelCounter;
 static sqInt lastSend;
 static usqInt limitAddress;
@@ -1781,7 +1780,6 @@
 static sqInt methodZoneBase;
 static unsigned long minValidCallAddress;
 sqInt missOffset;
-static AbstractInstruction * mnuCall;
 static usqInt mzFreeStart;
 static sqInt needsFrame;
 static AbstractInstruction * noCheckEntry;
@@ -1794,7 +1792,9 @@
 static sqInt openPICSize;
 static CogSSOptStatus optStatus;
 static sqInt picAbortTrampolines[4];
+static AbstractInstruction * picInterpretAbort;
 static sqInt picMissTrampolines[4];
+static AbstractInstruction * picMNUAbort;
 static void (*postCompileHook)(CogMethod *, void *);
 static BytecodeDescriptor * prevBCDescriptor;
 static AbstractInstruction * primInvokeLabel;
@@ -1807,7 +1807,6 @@
 static sqInt regArgsHaveBeenPushed;
 static sqInt runtimeObjectRefIndex;
 static AbstractInstruction * sendMiss;
-static AbstractInstruction * sendMissCall;
 static sqInt sendTrampolines[NumSendTrampolines];
 static CogSimStackEntry simSelf;
 static sqInt simSpillBase;
@@ -8590,6 +8589,7 @@
 	
 	
 	outerReturn = stackTop();
+	assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue()))));
 	if (((cPIC->cPICNumCases)) < numPICCases) {
 		/* begin lookup:for:methodAndErrorSelectorInto: */
 		selector = (cPIC->selector);
@@ -8806,8 +8806,9 @@
 	if (((errorSelectorOrNil != null)
 	 && (errorSelectorOrNil != SelectorDoesNotUnderstand))
 	 || ((inlineCacheTagIsYoung(cacheTag))
+	 || (((inlineCacheTagAt(backEnd, outerReturn)) == 0)
 	 || ((newTargetMethodOrNil == null)
-	 || (isYoung(newTargetMethodOrNil))))) {
+	 || (isYoung(newTargetMethodOrNil)))))) {
 		result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver);
 		assert(!result);
 		return ceSendFromInLineCacheMiss(targetMethod);
@@ -9491,14 +9492,15 @@
  */
 
 CogMethod *
-cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs)
+cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs)
 {
     sqInt end;
     sqInt headerSize;
     sqInt size;
     sqInt startAddress;
 
-	if (isYoung(selector)) {
+	if ((isYoung(selector))
+	 || ((inlineCacheTagForInstance(rcvr)) == 0)) {
 		return 0;
 	}
 	compilationBreakpointisMNUCase(selector, numBytesOf(selector), 1);
@@ -9519,7 +9521,7 @@
 	/* The missOffset is the same as the interpretOffset. */
 
 	end = outputInstructionsAt(startAddress + headerSize);
-	assert(missOffset == ((((interpretCall->address)) + ((interpretCall->machineCodeSize))) - startAddress));
+	assert(missOffset == ((((picInterpretAbort->address)) + ((picInterpretAbort->machineCodeSize))) - startAddress));
 	assert((startAddress + cmEntryOffset) == ((entry->address)));
 	return fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(((CogMethod *) startAddress), closedPICSize, numArgs, 1, 1, selector);
 }
@@ -9595,7 +9597,7 @@
 	/* The missOffset is th same as the interpretOffset. */
 
 	end = outputInstructionsAt(startAddress + headerSize);
-	assert(missOffset == ((((interpretCall->address)) + ((interpretCall->machineCodeSize))) - startAddress));
+	assert(missOffset == ((((picInterpretAbort->address)) + ((picInterpretAbort->machineCodeSize))) - startAddress));
 	assert((startAddress + cmEntryOffset) == ((entry->address)));
 	assert(((endCPICCase0->address)) == (startAddress + firstCPICCaseOffset));
 	assert(((endCPICCase1->address)) == ((startAddress + firstCPICCaseOffset) + cPICCaseSize));
@@ -9675,16 +9677,19 @@
 	path; if nonzero the in-line cache miss path. Neither of these paths
 	returns. The abort routine must be called; In the callee the method is
 	located by
-	adding the relevant offset to the return address of the call. */
+	adding the relevant offset to the return address of the call.
+	
+	N.B. This code must match that in compilePICAbort: so that the offset of
+	the return address of the call is the same in methods and closed PICs. */
 
-static void
+static AbstractInstruction *
 compileAbort(void)
 {
     sqInt callTarget;
 
 	/* begin MoveCq:R: */
 	stackOverflowCall = genoperandoperand(MoveCqR, 0, ReceiverResultReg);
-	sendMiss = (sendMissCall = gCall(methodAbortTrampolineFor(methodOrBlockNumArgs)));
+	return (sendMiss = gCall(methodAbortTrampolineFor(methodOrBlockNumArgs)));
 
 }
 
@@ -9871,7 +9876,7 @@
     sqInt numArgs;
 
 	numArgs = 0;
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, 99282957, SendNumArgsReg);
@@ -9936,7 +9941,7 @@
     void *targetEntry;
 
 	assert(case1Method != null);
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	assert(!(inlineCacheTagIsYoung(case1Tag)));
 	if ((!isMNUCase)
 	 && (methodHasCogMethod(case1Method))) {
@@ -9948,8 +9953,8 @@
 		 || (!(isYoungObject(case1Method))));
 		operand = case1Method;
 		targetEntry = (case1Method == null
-			? mnuCall
-			: interpretLabel);
+			? picMNUAbort
+			: picInterpretAbort);
 	}
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
@@ -9963,7 +9968,7 @@
 	genoperandoperand(MoveCwR, operand, SendNumArgsReg);
 	/* begin JumpLongZero: */
 	jumpTarget = ((sqInt)((isMNUCase
-	? mnuCall
+	? picMNUAbort
 	: targetEntry)));
 	genoperand(JumpLongZero, ((sqInt)jumpTarget));
 	/* begin MoveCw:R: */
@@ -10029,12 +10034,12 @@
     AbstractInstruction *jumpNext;
     sqInt jumpTarget;
 
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, methodOperand, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, ((sqInt)mnuCall));
+	genoperand(JumpLong, ((sqInt)picMNUAbort));
 	jmpTarget(jumpNext, gMoveCwR(((sqInt)cPIC), ClassReg));
 	/* begin JumpLong: */
 	jumpTarget = cPICMissTrampolineFor(numArgs);
@@ -10044,20 +10049,32 @@
 
 
 /*	The start of a PIC has a call to a run-time abort routine that either
-	handles a dispatch to an interpreted method or a dispatch of an MNU case.
-	The routine selects the path depending on ClassReg; if zero it takes the
-	MNU path; if nonzero the dispatch to interpreter path. Neither of these
-	paths returns. The abort routine must be called; In the callee the PIC is
-	located by adding the relevant offset to the return address of the call. */
+	handles a dispatch to an
+	interpreted method or a dispatch of an MNU case. The routine selects the
+	path by testing
+	ClassReg, which holds the inline cache tag; if equal to the
+	picAbortDiscriminatorValue (zero)
+	it takes the MNU path; if nonzero the dispatch to interpreter path.
+	Neither of these paths
+	returns. The abort routine must be called; In the callee the PIC is
+	located by adding the
+	relevant offset to the return address of the call.
+	
+	N.B. This code must match that in compileAbort so that the offset of the
+	return address of
+	the call is the same in methods and closed PICs. */
 
 static sqInt
-compilePICProlog(sqInt numArgs)
+compilePICAbort(sqInt numArgs)
 {
     sqInt callTarget;
+    sqInt callTarget1;
 
 	/* begin MoveCq:R: */
-	mnuCall = genoperandoperand(MoveCqR, 0, ClassReg);
-	interpretLabel = (interpretCall = gCall(picAbortTrampolineFor(numArgs)));
+	picMNUAbort = genoperandoperand(MoveCqR, 0, ClassReg);
+	/* begin Call: */
+	callTarget1 = picAbortTrampolineFor(numArgs);
+	picInterpretAbort = genoperand(Call, callTarget1);
 
 	return 0;
 }
@@ -10132,9 +10149,11 @@
 static void
 computeEntryOffsets(void)
 {
+    AbstractInstruction *sendMissCall;
+
 	allocateOpcodesbytecodes(20, 0);
 	methodOrBlockNumArgs = 0;
-	compileAbort();
+	sendMissCall = compileAbort();
 	compileEntry();
 	computeMaximumSizes();
 	generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)));
@@ -11244,10 +11263,17 @@
 
 
 /*	Generate the abort for a PIC. This abort performs either a call of
-	ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged
-	target or a call of ceMNUFromPICMNUMethod:receiver: to handle an
-	MNU dispatch in a closed PIC. It distinguishes the two by testing
-	ClassReg. If the register is zero then this is an MNU. */
+	ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target
+	or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch
+	in a closed PIC. It distinguishes the two by testing ClassReg. If the
+	register is zero then this is an MNU.
+	
+	This poses a problem in 32-bit Spur, where zero is the cache tag for
+	immediate characters (tag pattern 2r10) because SmallIntegers have tag
+	patterns 2r11
+	and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity
+	by patching send sites with a 0 cache tag to open PICs instead of closed
+	PICs.  */
 
 static sqInt
 genInnerPICAbortTrampoline(char *name)
@@ -13270,6 +13296,16 @@
 }
 
 
+/*	This value is used to decide between MNU processing
+	or interpretation in the closed PIC aborts. */
+
+static sqInt
+picAbortDiscriminatorValue(void)
+{
+	return 0;
+}
+
+
 /*	If there is a generator for the current primitive then answer it;
 	otherwise answer nil. */
 
@@ -19036,7 +19072,7 @@
     sqInt offset5;
     sqInt offset6;
 
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	/* begin Nop */
 	gen(Nop);
 	/* begin Nop */
@@ -19076,7 +19112,7 @@
 	/* begin MoveR:R: */
 	genoperandoperand(MoveRR, TempReg, ClassReg);
 	jumpBCMethod = genJumpSmallIntegerInScratchReg(TempReg);
-	jmpTarget(jumpBCMethod, interpretLabel);
+	jmpTarget(jumpBCMethod, picInterpretAbort);
 	/* begin AddCq:R: */
 	genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg);
 	/* begin JumpR: */

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nscogsrc/vm/cogit.h	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92
+	CCodeGenerator VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef
  */
 
 
@@ -39,7 +39,7 @@
 sqInt cogCodeConstituents(void);
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
-CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
+CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs);
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
 void enterCogCodePopReceiver(void);

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
    from
-	CoInterpreter VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CoInterpreter VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2098,7 +2098,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.969";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.971";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -4842,7 +4842,6 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
-							null;
 							goto l300;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
@@ -4860,7 +4859,7 @@
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-					null;
+					/* return self */
 				l300:	/* end baseFrameReturn */;
 					goto l299;
 				}
@@ -15100,7 +15099,7 @@
 		GIV(messageSelector) = selector;
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classTag))) != 0) {
 			if ((errSelIdx == SelectorDoesNotUnderstand)
-			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress()))) {
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectorreceivermethodOperandnumArgs(GIV(messageSelector), rcvr, mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress()))) {
 				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
 					? entryOffset()
 					: noCheckEntryOffset()), rcvr);
@@ -26102,7 +26101,7 @@
 			(GIV(primFailCode) = PrimErrBadArgument);
 			return;
 		}
-		memcpy(rcvr + BaseHeaderSize, arg + BaseHeaderSize, length);
+		memcpy(((void *)(rcvr + BaseHeaderSize)), ((void *)(arg + BaseHeaderSize)), length);
 	}
 	else {
 		if (!(isAppropriateForCopyObject(rcvr))) {
@@ -50484,7 +50483,7 @@
 		if ((((frameOrContext & 1) == 0)
 		 && (((((usqInt) (longAt(frameOrContext))) >> (compactClassFieldLSB())) & 0x1F) == ClassMethodContextCompactIndex))
 		 && (checkIsStillMarriedContextcurrentFP(frameOrContext, null))) {
-			return printStackCallStackOf(frameOfMarriedContext(frameOrContext));
+			return printStackCallStackOf(((sqInt)(frameOfMarriedContext(frameOrContext))));
 		}
 		return null;
 	}

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
  */
 
 

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2014-12-06 20:31:43 UTC (rev 3163)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
    from
-	CoInterpreter VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CoInterpreter VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2101,7 +2101,7 @@
 	/* 574 */ (void (*)(void))0,
 	/* 575 */ (void (*)(void))0,
  0 };
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.969";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.971";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -4851,7 +4851,6 @@
 							GIV(framePointer) = localFP;
 							
 							ceEnterCogCodePopReceiverReg();
-							null;
 							goto l300;
 						}
 						localIP = pointerForOop(longAt(localFP + FoxIFSavedIP));
@@ -4869,7 +4868,7 @@
 					/* begin fetchNextBytecode */
 					currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
 
-					null;
+					/* return self */
 				l300:	/* end baseFrameReturn */;
 					goto l299;
 				}
@@ -15109,7 +15108,7 @@
 		GIV(messageSelector) = selector;
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(classTag))) != 0) {
 			if ((errSelIdx == SelectorDoesNotUnderstand)
-			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress()))) {
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectorreceivermethodOperandnumArgs(GIV(messageSelector), rcvr, mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress()))) {
 				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
 					? entryOffset()
 					: noCheckEntryOffset()), rcvr);
@@ -26111,7 +26110,7 @@
 			(GIV(primFailCode) = PrimErrBadArgument);
 			return;
 		}
-		memcpy(rcvr + BaseHeaderSize, arg + BaseHeaderSize, length);
+		memcpy(((void *)(rcvr + BaseHeaderSize)), ((void *)(arg + BaseHeaderSize)), length);
 	}
 	else {
 		if (!(isAppropriateForCopyObject(rcvr))) {
@@ -50493,7 +50492,7 @@
 		if ((((frameOrContext & 1) == 0)
 		 && (((((usqInt) (longAt(frameOrContext))) >> (compactClassFieldLSB())) & 0x1F) == ClassMethodContextCompactIndex))
 		 && (checkIsStillMarriedContextcurrentFP(frameOrContext, null))) {
-			return printStackCallStackOf(frameOfMarriedContext(frameOrContext));
+			return printStackCallStackOf(((sqInt)(frameOfMarriedContext(frameOrContext))));
 		}
 		return null;
 	}

Modified: branches/Cog/nsspursrc/vm/cogit.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.c	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nsspursrc/vm/cogit.c	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92
+	CCodeGenerator VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92
+	StackToRegisterMappingCogit VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -604,12 +604,12 @@
 static sqInt cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase) NoDbgRegParms;
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
-CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
+CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs);
 static CogMethod * cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs) NoDbgRegParms;
 static CogMethod * cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase) NoDbgRegParms;
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
-static void compileAbort(void);
+static AbstractInstruction * compileAbort(void);
 static sqInt compileBlockDispatchFromto(sqInt lowBlockStartIndex, sqInt highBlockStartIndex) NoDbgRegParms;
 static void compileBlockEntry(BlockStart *blockStart) NoDbgRegParms;
 static void compileCallFornumArgsargargargargresultRegsaveRegs(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNil, sqInt saveRegs) NoDbgRegParms;
@@ -619,7 +619,7 @@
 static void compileEntry(void);
 static sqInt compileMethodBody(void);
 static sqInt compileMNUCPICmethodOperandnumArgs(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs) NoDbgRegParms;
-static sqInt compilePICProlog(sqInt numArgs) NoDbgRegParms;
+static sqInt compilePICAbort(sqInt numArgs) NoDbgRegParms;
 static sqInt compilePrimitive(void);
 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);
@@ -746,6 +746,7 @@
 static AbstractInstruction * gPushCw(sqInt wordConstant) NoDbgRegParms;
 sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver);
 sqInt pcisWithinMethod(char *address, CogMethod *cogMethod);
+static sqInt picAbortDiscriminatorValue(void);
 static PrimitiveDescriptor * primitiveGeneratorOrNil(void);
 void printCogMethodFor(void *address);
 void printTrampolineTable(void);
@@ -1784,8 +1785,6 @@
 static sqInt inBlock;
 static sqInt indexOfIRC;
 static sqInt initialPC;
-static AbstractInstruction * interpretCall;
-static AbstractInstruction * interpretLabel;
 static int labelCounter;
 static sqInt lastSend;
 static usqInt limitAddress;
@@ -1800,7 +1799,6 @@
 static sqInt methodZoneBase;
 static unsigned long minValidCallAddress;
 sqInt missOffset;
-static AbstractInstruction * mnuCall;
 static usqInt mzFreeStart;
 static sqInt needsFrame;
 static AbstractInstruction * noCheckEntry;
@@ -1813,7 +1811,9 @@
 static sqInt openPICSize;
 static CogSSOptStatus optStatus;
 static sqInt picAbortTrampolines[4];
+static AbstractInstruction * picInterpretAbort;
 static sqInt picMissTrampolines[4];
+static AbstractInstruction * picMNUAbort;
 static void (*postCompileHook)(CogMethod *, void *);
 static BytecodeDescriptor * prevBCDescriptor;
 static AbstractInstruction * primInvokeLabel;
@@ -1826,7 +1826,6 @@
 static sqInt regArgsHaveBeenPushed;
 static sqInt runtimeObjectRefIndex;
 static AbstractInstruction * sendMiss;
-static AbstractInstruction * sendMissCall;
 static sqInt sendTrampolines[NumSendTrampolines];
 static CogSimStackEntry simSelf;
 static sqInt simSpillBase;
@@ -8617,6 +8616,7 @@
 		return ceSendFromInLineCacheMiss(cPIC);
 	}
 	outerReturn = stackTop();
+	assert(!(((inlineCacheTagAt(backEnd, outerReturn)) == (picAbortDiscriminatorValue()))));
 	if (((cPIC->cPICNumCases)) < numPICCases) {
 		/* begin lookup:for:methodAndErrorSelectorInto: */
 		selector = (cPIC->selector);
@@ -8827,8 +8827,9 @@
 	if (((errorSelectorOrNil != null)
 	 && (errorSelectorOrNil != SelectorDoesNotUnderstand))
 	 || ((inlineCacheTagIsYoung(cacheTag))
+	 || (((inlineCacheTagAt(backEnd, outerReturn)) == 0)
 	 || ((newTargetMethodOrNil == null)
-	 || (isYoung(newTargetMethodOrNil))))) {
+	 || (isYoung(newTargetMethodOrNil)))))) {
 		result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver);
 		assert(!result);
 		return ceSendFromInLineCacheMiss(targetMethod);
@@ -9449,14 +9450,15 @@
  */
 
 CogMethod *
-cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs)
+cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs)
 {
     sqInt end;
     sqInt headerSize;
     sqInt size;
     sqInt startAddress;
 
-	if (isYoung(selector)) {
+	if ((isYoung(selector))
+	 || ((inlineCacheTagForInstance(rcvr)) == 0)) {
 		return 0;
 	}
 	compilationBreakpointisMNUCase(selector, numBytesOf(selector), 1);
@@ -9477,7 +9479,7 @@
 	/* The missOffset is the same as the interpretOffset. */
 
 	end = outputInstructionsAt(startAddress + headerSize);
-	assert(missOffset == ((((interpretCall->address)) + ((interpretCall->machineCodeSize))) - startAddress));
+	assert(missOffset == ((((picInterpretAbort->address)) + ((picInterpretAbort->machineCodeSize))) - startAddress));
 	assert((startAddress + cmEntryOffset) == ((entry->address)));
 	return fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(((CogMethod *) startAddress), closedPICSize, numArgs, 1, 1, selector);
 }
@@ -9553,7 +9555,7 @@
 	/* The missOffset is th same as the interpretOffset. */
 
 	end = outputInstructionsAt(startAddress + headerSize);
-	assert(missOffset == ((((interpretCall->address)) + ((interpretCall->machineCodeSize))) - startAddress));
+	assert(missOffset == ((((picInterpretAbort->address)) + ((picInterpretAbort->machineCodeSize))) - startAddress));
 	assert((startAddress + cmEntryOffset) == ((entry->address)));
 	assert(((endCPICCase0->address)) == (startAddress + firstCPICCaseOffset));
 	assert(((endCPICCase1->address)) == ((startAddress + firstCPICCaseOffset) + cPICCaseSize));
@@ -9633,16 +9635,19 @@
 	path; if nonzero the in-line cache miss path. Neither of these paths
 	returns. The abort routine must be called; In the callee the method is
 	located by
-	adding the relevant offset to the return address of the call. */
+	adding the relevant offset to the return address of the call.
+	
+	N.B. This code must match that in compilePICAbort: so that the offset of
+	the return address of the call is the same in methods and closed PICs. */
 
-static void
+static AbstractInstruction *
 compileAbort(void)
 {
     sqInt callTarget;
 
 	/* begin MoveCq:R: */
 	stackOverflowCall = genoperandoperand(MoveCqR, 0, ReceiverResultReg);
-	sendMiss = (sendMissCall = gCall(methodAbortTrampolineFor(methodOrBlockNumArgs)));
+	return (sendMiss = gCall(methodAbortTrampolineFor(methodOrBlockNumArgs)));
 
 }
 
@@ -9829,7 +9834,7 @@
     sqInt numArgs;
 
 	numArgs = 0;
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, 99282957, SendNumArgsReg);
@@ -9894,7 +9899,7 @@
     void *targetEntry;
 
 	assert(case1Method != null);
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	assert(!(inlineCacheTagIsYoung(case1Tag)));
 	if ((!isMNUCase)
 	 && (methodHasCogMethod(case1Method))) {
@@ -9906,8 +9911,8 @@
 		 || (!(isYoungObject(case1Method))));
 		operand = case1Method;
 		targetEntry = (case1Method == null
-			? mnuCall
-			: interpretLabel);
+			? picMNUAbort
+			: picInterpretAbort);
 	}
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
@@ -9921,7 +9926,7 @@
 	genoperandoperand(MoveCwR, operand, SendNumArgsReg);
 	/* begin JumpLongZero: */
 	jumpTarget = ((sqInt)((isMNUCase
-	? mnuCall
+	? picMNUAbort
 	: targetEntry)));
 	genoperand(JumpLongZero, ((sqInt)jumpTarget));
 	/* begin MoveCw:R: */
@@ -9987,12 +9992,12 @@
     AbstractInstruction *jumpNext;
     sqInt jumpTarget;
 
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, methodOperand, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, ((sqInt)mnuCall));
+	genoperand(JumpLong, ((sqInt)picMNUAbort));
 	jmpTarget(jumpNext, gMoveCwR(((sqInt)cPIC), ClassReg));
 	/* begin JumpLong: */
 	jumpTarget = cPICMissTrampolineFor(numArgs);
@@ -10002,20 +10007,32 @@
 
 
 /*	The start of a PIC has a call to a run-time abort routine that either
-	handles a dispatch to an interpreted method or a dispatch of an MNU case.
-	The routine selects the path depending on ClassReg; if zero it takes the
-	MNU path; if nonzero the dispatch to interpreter path. Neither of these
-	paths returns. The abort routine must be called; In the callee the PIC is
-	located by adding the relevant offset to the return address of the call. */
+	handles a dispatch to an
+	interpreted method or a dispatch of an MNU case. The routine selects the
+	path by testing
+	ClassReg, which holds the inline cache tag; if equal to the
+	picAbortDiscriminatorValue (zero)
+	it takes the MNU path; if nonzero the dispatch to interpreter path.
+	Neither of these paths
+	returns. The abort routine must be called; In the callee the PIC is
+	located by adding the
+	relevant offset to the return address of the call.
+	
+	N.B. This code must match that in compileAbort so that the offset of the
+	return address of
+	the call is the same in methods and closed PICs. */
 
 static sqInt
-compilePICProlog(sqInt numArgs)
+compilePICAbort(sqInt numArgs)
 {
     sqInt callTarget;
+    sqInt callTarget1;
 
 	/* begin MoveCq:R: */
-	mnuCall = genoperandoperand(MoveCqR, 0, ClassReg);
-	interpretLabel = (interpretCall = gCall(picAbortTrampolineFor(numArgs)));
+	picMNUAbort = genoperandoperand(MoveCqR, 0, ClassReg);
+	/* begin Call: */
+	callTarget1 = picAbortTrampolineFor(numArgs);
+	picInterpretAbort = genoperand(Call, callTarget1);
 
 	return 0;
 }
@@ -10090,9 +10107,11 @@
 static void
 computeEntryOffsets(void)
 {
+    AbstractInstruction *sendMissCall;
+
 	allocateOpcodesbytecodes(20, 0);
 	methodOrBlockNumArgs = 0;
-	compileAbort();
+	sendMissCall = compileAbort();
 	compileEntry();
 	computeMaximumSizes();
 	generateInstructionsAt(methodZoneBase + (sizeof(CogMethod)));
@@ -11360,10 +11379,17 @@
 
 
 /*	Generate the abort for a PIC. This abort performs either a call of
-	ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged
-	target or a call of ceMNUFromPICMNUMethod:receiver: to handle an
-	MNU dispatch in a closed PIC. It distinguishes the two by testing
-	ClassReg. If the register is zero then this is an MNU. */
+	ceInterpretMethodFromPIC:receiver: to handle invoking an uncogged target
+	or a call of ceMNUFromPICMNUMethod:receiver: to handle an MNU dispatch
+	in a closed PIC. It distinguishes the two by testing ClassReg. If the
+	register is zero then this is an MNU.
+	
+	This poses a problem in 32-bit Spur, where zero is the cache tag for
+	immediate characters (tag pattern 2r10) because SmallIntegers have tag
+	patterns 2r11
+	and 2r01, so anding with 1 reduces these to 0 & 1. We solve the ambiguity
+	by patching send sites with a 0 cache tag to open PICs instead of closed
+	PICs.  */
 
 static sqInt
 genInnerPICAbortTrampoline(char *name)
@@ -13187,6 +13213,16 @@
 }
 
 
+/*	This value is used to decide between MNU processing
+	or interpretation in the closed PIC aborts. */
+
+static sqInt
+picAbortDiscriminatorValue(void)
+{
+	return 0;
+}
+
+
 /*	If there is a generator for the current primitive then answer it;
 	otherwise answer nil. */
 
@@ -20757,7 +20793,7 @@
     sqInt offset5;
     sqInt offset6;
 
-	compilePICProlog(numArgs);
+	compilePICAbort(numArgs);
 	/* begin Nop */
 	gen(Nop);
 	/* begin Nop */
@@ -20797,7 +20833,7 @@
 	/* begin MoveR:R: */
 	genoperandoperand(MoveRR, TempReg, ClassReg);
 	jumpBCMethod = genJumpSmallIntegerInScratchReg(TempReg);
-	jmpTarget(jumpBCMethod, interpretLabel);
+	jmpTarget(jumpBCMethod, picInterpretAbort);
 	/* begin AddCq:R: */
 	genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg);
 	/* begin JumpR: */

Modified: branches/Cog/nsspursrc/vm/cogit.h
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.h	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nsspursrc/vm/cogit.h	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.970 uuid: 3869e39d-0172-4f38-9db5-cdca677eab92
+	CCodeGenerator VMMaker.oscog-eem.972 uuid: 741005af-763d-4a93-918d-014972c404ef
  */
 
 
@@ -39,7 +39,7 @@
 sqInt cogCodeConstituents(void);
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
-CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
+CogMethod * cogMNUPICSelectorreceivermethodOperandnumArgs(sqInt selector, sqInt rcvr, sqInt methodOperand, sqInt numArgs);
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
 void enterCogCodePopReceiver(void);

Modified: branches/Cog/nsspursrc/vm/cointerp.c
===================================================================
--- branches/Cog/nsspursrc/vm/cointerp.c	2014-12-06 04:31:14 UTC (rev 3162)
+++ branches/Cog/nsspursrc/vm/cointerp.c	2014-12-06 20:31:43 UTC (rev 3163)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
    from
-	CoInterpreter VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955
+	CoInterpreter VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.969 uuid: cdd723c1-bec0-42d5-970f-354702984955 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.971 uuid: ed756b25-4d7e-45a8-8a3b-c06199675128 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -390,7 +390,7 @@
 #endif
 
 sqInt interpret(void);
-static sqInt cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) NoDbgRegParms;
+static CogMethod * cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod) NoDbgRegParms;
 sqInt accessorDepthForPrimitiveIndex(sqInt primIndex);
 static void activateCoggedNewMethod(sqInt inInterpreter) NoDbgRegParms;
 static void activateNewMethod(void);
@@ -435,7 +435,7 @@
 static sqInt checkOkayFields(sqInt oop) NoDbgRegParms;
 static sqInt checkStackIntegrity(void);
 void clearTraceLog(void);
-sqInt cogMethodOf(sqInt aMethodOop);
+CogMethod * cogMethodOf(sqInt aMethodOop);
 static void commenceCogCompiledCodeCompaction(void);
 void compilationBreakpointFor(sqInt selectorOop);
 static sqInt contextInstructionPointerframe(sqInt theIP, char *theFP) NoDbgRegParms;
@@ -500,6 +500,7 @@
 sqInt methodNeedsLargeContext(sqInt methodObj);
 sqInt methodShouldBeCogged(sqInt aMethodObj);
 static sqInt methodWithHeaderShouldBeCogged(sqInt methodHeader) NoDbgRegParms;
+static CogBlockMethod * mframeCogMethod(char *theFP) NoDbgRegParms;
 CogMethod * mframeHomeMethodExport(void);
 CogMethod * mframeHomeMethod(char *theFP);
 static sqInt mframeIsBlockActivation(char *theFP) NoDbgRegParms;
@@ -2347,7 +2348,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.969";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.971";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -5101,7 +5102,7 @@
 					goto l248;
 				}
 				closure = longAt(localFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(localFP + FoxMethod)))) < (startOfMemory())
-	? ((((CogBlockMethod *) ((longAt(localFP + FoxMethod)) & MFMethodMask)))->cmNumArgs)
+	? ((mframeCogMethod(localFP))->cmNumArgs)
 	: byteAt((localFP + FoxIFrameFlags) + 1)))));
 
 				/* Walk the closure's lexical chain to find the context or frame to return from (home). */
@@ -5203,8 +5204,8 @@
 						/* begin stackPageAt: */
 						/* begin pageIndexFor: */
 						assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-						index2 = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
-						thePage1 = stackPageAtpages(index2, GIV(pages));
+						index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+						thePage1 = stackPageAtpages(index, GIV(pages));
 						callerContextOrNil = longAt((thePage1->baseAddress));
 						assert(addressCouldBeObj(callerContextOrNil));
 						assert((callerContextOrNil == (nilObject()))
@@ -5263,8 +5264,8 @@
 				/* begin stackPageAt: */
 				/* begin pageIndexFor: */
 				assert((((((char *) frameToReturnTo)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) frameToReturnTo)) <= (((char *) GIV(pages))))));
-				index1 = pageIndexForstackBasePlus1bytesPerPage(frameToReturnTo, GIV(stackBasePlus1), GIV(bytesPerPage));
-				newPage = stackPageAtpages(index1, GIV(pages));
+				index4 = pageIndexForstackBasePlus1bytesPerPage(frameToReturnTo, GIV(stackBasePlus1), GIV(bytesPerPage));
+				newPage = stackPageAtpages(index4, GIV(pages));
 				if (newPage != GIV(stackPage)) {
 					/* begin frameCallerContext: */
 					theFP2 = (GIV(stackPage)->baseFP);
@@ -5273,8 +5274,8 @@
 					/* begin stackPageAt: */
 					/* begin pageIndexFor: */
 					assert((((((char *) theFP2)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP2)) <= (((char *) GIV(pages))))));
-					index4 = pageIndexForstackBasePlus1bytesPerPage(theFP2, GIV(stackBasePlus1), GIV(bytesPerPage));
-					thePage3 = stackPageAtpages(index4, GIV(pages));
+					index3 = pageIndexForstackBasePlus1bytesPerPage(theFP2, GIV(stackBasePlus1), GIV(bytesPerPage));
+					thePage3 = stackPageAtpages(index3, GIV(pages));
 					callerContextOrNil2 = longAt((thePage3->baseAddress));
 					assert(addressCouldBeObj(callerContextOrNil2));
 					assert((callerContextOrNil2 == (nilObject()))
@@ -5289,8 +5290,8 @@
 							/* begin stackPageAt: */
 							/* begin pageIndexFor: */
 							assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-							index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
-							thePage = stackPageAtpages(index, GIV(pages));
+							index1 = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+							thePage = stackPageAtpages(index1, GIV(pages));
 							if (theFP != ((thePage->headFP))) {
 
 								/* Since we've just deallocated a page we know that newStackPage won't deallocate an existing one. */
@@ -5304,8 +5305,8 @@
 							/* begin stackPageAt: */
 							/* begin pageIndexFor: */
 							assert((((((char *) theFP1)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP1)) <= (((char *) GIV(pages))))));
-							index3 = pageIndexForstackBasePlus1bytesPerPage(theFP1, GIV(stackBasePlus1), GIV(bytesPerPage));
-							thePage2 = stackPageAtpages(index3, GIV(pages));
+							index2 = pageIndexForstackBasePlus1bytesPerPage(theFP1, GIV(stackBasePlus1), GIV(bytesPerPage));
+							thePage2 = stackPageAtpages(index2, GIV(pages));
 							callerContextOrNil1 = longAt((thePage2->baseAddress));
 							assert(addressCouldBeObj(callerContextOrNil1));
 							assert((callerContextOrNil1 == (nilObject()))
@@ -5612,7 +5613,7 @@
 				/* begin frameCallerSavedIP: */
 				localIP = pointerForOop(longAt(localFP + FoxCallerSavedIP));
 				localSP = localFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(localFP + FoxMethod)))) < (startOfMemory())
-	? ((((CogBlockMethod *) ((longAt(localFP + FoxMethod)) & MFMethodMask)))->cmNumArgs)
+	? ((mframeCogMethod(localFP))->cmNumArgs)
 	: byteAt((localFP + FoxIFrameFlags) + 1))));
 				localFP = callersFPOrNull;
 				if ((((usqInt)localIP)) < (startOfMemory())) {
@@ -6523,7 +6524,7 @@
 							/* begin frameCallerStackPointer: */
 							assert(!(isBaseFrame(spouseFP)));
 							theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < (startOfMemory())
-	? ((((CogBlockMethod *) ((longAt(spouseFP + FoxMethod)) & MFMethodMask)))->cmNumArgs)
+	? ((mframeCogMethod(spouseFP))->cmNumArgs)
 	: byteAt((spouseFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
 							if (((((usqInt)(longAt(callerFP + FoxMethod)))) < (startOfMemory())
 								? ((longAt(callerFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
@@ -13156,7 +13157,7 @@
 						/* begin frameCallerStackPointer: */
 						assert(!(isBaseFrame(spouseFP)));
 						theSP = (spouseFP + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(spouseFP + FoxMethod)))) < (startOfMemory())
-	? ((((CogBlockMethod *) ((longAt(spouseFP + FoxMethod)) & MFMethodMask)))->cmNumArgs)
+	? ((mframeCogMethod(spouseFP))->cmNumArgs)
 	: byteAt((spouseFP + FoxIFrameFlags) + 1))))) + BytesPerWord;
 						if (((((usqInt)(longAt(callerFP + FoxMethod)))) < (startOfMemory())
 							? ((longAt(callerFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0
@@ -14243,7 +14244,7 @@
 	return null;
 }
 
-static sqInt
+static CogMethod *
 cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod)
 {
 	return ((CogMethod *) ((((usqInt)self_in_cmHomeMethod)) - ((self_in_cmHomeMethod->homeOffset))));
@@ -14669,6 +14670,7 @@
     CogMethod *homeMethod;
 
 	assert(isMachineCodeFrame(GIV(framePointer)));
+	/* begin mframeCogMethod: */
 	cogMethod = ((CogBlockMethod *) ((longAt(GIV(framePointer) + FoxMethod)) & MFMethodMask));
 	homeMethod = (((cogMethod->cmType)) == CMMethod
 		? ((CogMethod *) cogMethod)
@@ -14806,7 +14808,7 @@
 		methodHeader = longAt((GIV(method) + BaseHeaderSize) + (HeaderIndex << (shiftForWord())));
 		assert((isNonImmediate(methodHeader))
 		 && ((((usqInt)methodHeader)) < (startOfMemory())));
-		cogMethod = ((sqInt) (((CogMethod *) methodHeader)));
+		cogMethod = ((CogMethod *) methodHeader);
 		/* begin convertToMachineCodeFrame:bcpc: */
 		assert(!(isMachineCodeFrame(GIV(framePointer))));
 		if ((longAt(GIV(framePointer) + FoxSavedFP)) == 0) {
@@ -14825,7 +14827,7 @@
 		}
 		if ((byteAt((GIV(framePointer) + FoxIFrameFlags) + 3)) != 0) {
 			closure = longAt(GIV(framePointer) + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(GIV(framePointer) + FoxMethod)))) < (startOfMemory())
-	? ((((CogBlockMethod *) ((longAt(GIV(framePointer) + FoxMethod)) & MFMethodMask)))->cmNumArgs)
+	? ((mframeCogMethod(GIV(framePointer)))->cmNumArgs)
 	: byteAt((GIV(framePointer) + FoxIFrameFlags) + 1)))));
 			startBcpc = (((longAt((closure + BaseHeaderSize) + (ClosureStartPCIndex << (shiftForWord())))) >> 1)) - 1;
 			cogMethod2 = findMethodForStartBcpcinHomeMethod(startBcpc, cogMethod);
@@ -14851,6 +14853,7 @@
 		pc = pc1;
 		/* begin assertValidMachineCodeFrame: */
 		assert(isMachineCodeFrame(GIV(framePointer)));
+		/* begin mframeCogMethod: */
 		cogMethod1 = ((CogBlockMethod *) ((longAt(GIV(framePointer) + FoxMethod)) & MFMethodMask));
 		homeMethod = (((cogMethod1->cmType)) == CMMethod
 			? ((CogMethod *) cogMethod1)
@@ -15476,7 +15479,7 @@
 		methodHeader1 = longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << (shiftForWord())));
 		assert((isNonImmediate(methodHeader1))
 		 && ((((usqInt)methodHeader1)) < (startOfMemory())));
-		cogMethod = ((sqInt) (((CogMethod *) methodHeader1)));
+		cogMethod = ((CogMethod *) methodHeader1);
 		if (((cogMethod->selector)) == GIV(nilObj)) {
 			setSelectorOfto(cogMethod, selector);
 		}
@@ -15731,7 +15734,7 @@
 	assert(isMachineCodeFrame(GIV(framePointer)));
 	assert(frameIsBlockActivation(GIV(framePointer)));
 	closure = longAt(GIV(framePointer) + (frameStackedReceiverOffsetNumArgs(((((usqInt)(longAt(GIV(framePointer) + FoxMethod)))) < (startOfMemory())
-	? ((((CogBlockMethod *) ((longAt(GIV(framePointer) + FoxMethod)) & MFMethodMask)))->cmNumArgs)
+	? ((mframeCogMethod(GIV(framePointer)))->cmNumArgs)
 	: byteAt((GIV(framePointer) + FoxIFrameFlags) + 1)))));
 
 	/* Walk the closure's lexical chain to find the context or frame to return from (home). */
@@ -15759,11 +15762,11 @@
 		theMethod = longAt((home + BaseHeaderSize) + (MethodIndex << (shiftForWord())));
 		if ((primitiveIndexOfMethodheader(theMethod, methodHeaderOf(theMethod))) == 198) {
 			unwindContextOrNilOrZero = home;
-			goto l3;
+			goto l1;
 		}
 	}
 	unwindContextOrNilOrZero = ctxtOrNilOrZero;
-l3:	/* end findUnwindThroughContext: */;
+l1:	/* end findUnwindThroughContext: */;
 	if (unwindContextOrNilOrZero == GIV(nilObj)) {
 
 		/* error: can't find home on chain; cannot return */
@@ -15775,10 +15778,10 @@
 			: (byteAt((GIV(framePointer) + FoxIFrameFlags) + 2)) != 0)) {
 			assert(isContext(frameContext(GIV(framePointer))));
 			ourContext = longAt(GIV(framePointer) + FoxThisContext);
-			goto l1;
+			goto l2;
 		}
 		ourContext = marryFrameSP(GIV(framePointer), theSP);
-	l1:	/* end ensureFrameIsMarried:SP: */;
+	l2:	/* end ensureFrameIsMarried:SP: */;
 		/* begin externalCannotReturn:from: */
 		/* begin push: */
 		longAtput((sp = GIV(stackPointer) - BytesPerWord), ourContext);
@@ -15833,8 +15836,8 @@
 			/* begin stackPageAt: */
 			/* begin pageIndexFor: */
 			assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-			index2 = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
-			thePage1 = stackPageAtpages(index2, GIV(pages));
+			index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+			thePage1 = stackPageAtpages(index, GIV(pages));
 			callerContextOrNil = longAt((thePage1->baseAddress));
 			assert(addressCouldBeObj(callerContextOrNil));
 			assert((callerContextOrNil == (nilObject()))
@@ -15873,10 +15876,10 @@
 				: (byteAt((GIV(framePointer) + FoxIFrameFlags) + 2)) != 0)) {
 				assert(isContext(frameContext(GIV(framePointer))));
 				ourContext = longAt(GIV(framePointer) + FoxThisContext);
-				goto l2;
+				goto l3;
 			}
 			ourContext = marryFrameSP(GIV(framePointer), theSP1);
-		l2:	/* end ensureFrameIsMarried:SP: */;
+		l3:	/* end ensureFrameIsMarried:SP: */;
 			/* begin externalCannotReturn:from: */
 			/* begin push: */
 			longAtput((sp3 = GIV(stackPointer) - BytesPerWord), ourContext);
@@ -15895,8 +15898,8 @@
 	/* begin stackPageAt: */
 	/* begin pageIndexFor: */
 	assert((((((char *) frameToReturnTo)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) frameToReturnTo)) <= (((char *) GIV(pages))))));
-	index1 = pageIndexForstackBasePlus1bytesPerPage(frameToReturnTo, GIV(stackBasePlus1), GIV(bytesPerPage));
-	newPage = stackPageAtpages(index1, GIV(pages));
+	index4 = pageIndexForstackBasePlus1bytesPerPage(frameToReturnTo, GIV(stackBasePlus1), GIV(bytesPerPage));
+	newPage = stackPageAtpages(index4, GIV(pages));
 	if (newPage != GIV(stackPage)) {
 		/* begin frameCallerContext: */
 		theFP2 = (GIV(stackPage)->baseFP);
@@ -15905,8 +15908,8 @@
 		/* begin stackPageAt: */
 		/* begin pageIndexFor: */
 		assert((((((char *) theFP2)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP2)) <= (((char *) GIV(pages))))));
-		index4 = pageIndexForstackBasePlus1bytesPerPage(theFP2, GIV(stackBasePlus1), GIV(bytesPerPage));
-		thePage3 = stackPageAtpages(index4, GIV(pages));
+		index3 = pageIndexForstackBasePlus1bytesPerPage(theFP2, GIV(stackBasePlus1), GIV(bytesPerPage));
+		thePage3 = stackPageAtpages(index3, GIV(pages));
 		callerContextOrNil2 = longAt((thePage3->baseAddress));
 		assert(addressCouldBeObj(callerContextOrNil2));
 		assert((callerContextOrNil2 == (nilObject()))
@@ -15923,8 +15926,8 @@
 				/* begin stackPageAt: */
 				/* begin pageIndexFor: */
 				assert((((((char *) theFP)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP)) <= (((char *) GIV(pages))))));
-				index = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
-				thePage = stackPageAtpages(index, GIV(pages));
+				index1 = pageIndexForstackBasePlus1bytesPerPage(theFP, GIV(stackBasePlus1), GIV(bytesPerPage));
+				thePage = stackPageAtpages(index1, GIV(pages));
 				/* begin frameCallerContext: */
 				theFP1 = (thePage->baseFP);
 				assert(isBaseFrame(theFP1));
@@ -15932,8 +15935,8 @@
 				/* begin stackPageAt: */
 				/* begin pageIndexFor: */
 				assert((((((char *) theFP1)) >= (GIV(stackBasePlus1) - 1)) && ((((char *) theFP1)) <= (((char *) GIV(pages))))));

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list