[Vm-dev] [commit] r2487 - CogVM source as per VMMaker.oscog-eem.117.

commits at squeakvm.org commits at squeakvm.org
Tue Aug 16 22:28:13 UTC 2011


Author: eliot
Date: 2011-08-16 15:28:12 -0700 (Tue, 16 Aug 2011)
New Revision: 2487

Modified:
   branches/Cog/
   branches/Cog/cygwinbuild/Pharo.ico
   branches/Cog/macbuild/CoreVM.plist
   branches/Cog/nscogsrc/vm/cogit.c
   branches/Cog/nscogsrc/vm/cogit.h
   branches/Cog/nscogsrc/vm/cogmethod.h
   branches/Cog/nscogsrc/vm/cointerp.c
   branches/Cog/nscogsrc/vm/cointerp.h
   branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
   branches/Cog/nscogsrc/vm/interp.h
   branches/Cog/nscogsrc/vm/vmCallback.h
   branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
   branches/Cog/scripts/mkvmarchives
   branches/Cog/src/examplePlugins.ext
   branches/Cog/src/vm/cogit.c
   branches/Cog/src/vm/cogit.h
   branches/Cog/src/vm/cogmethod.h
   branches/Cog/src/vm/cointerp.c
   branches/Cog/src/vm/cointerp.h
   branches/Cog/src/vm/cointerpmt.c
   branches/Cog/src/vm/cointerpmt.h
   branches/Cog/src/vm/gcc3x-cointerp.c
   branches/Cog/src/vm/gcc3x-cointerpmt.c
   branches/Cog/src/vm/interp.h
   branches/Cog/src/vm/vmCallback.h
Log:
CogVM source as per VMMaker.oscog-eem.117.
Fix bugs described in the "[Pharo-project] Troubles with #flushCache and
#run:with:in:" thread http://lists.gforge.inria.fr/pipermail/pharo-project/
2011-July/050858.html.  The PIC machinery wrongly treated invoke-as-method
sends as MNUs.

Closely related, finally fully implement PIC MNU cacheing where, by calling a
special abort, a PIC is able to record that a gven selector is an MNU for a
particular class.  Speeds up a simple MNU benchmark by 33% (with more
performance the deeper the receiver's cass hierarchy is).

On Mac fix mis-editing of Info.plist to insert revision info so that VM .app
once again starts on 10.5.x.

Update Pharo icon to the nice Cog one.



Property changes on: branches/Cog
___________________________________________________________________
Added: svn:ignore
   + README.*
*.app
*.dmg
*.msi
*.tgz
*.zip
Cog.app
CogMT.app
coglinux
cogmtlinux
cogwin
cogmtwin
Newspeak Virtual Machine.app
nsvmwin
nsvmlinux


Modified: branches/Cog/cygwinbuild/Pharo.ico
===================================================================
(Binary files differ)

Modified: branches/Cog/macbuild/CoreVM.plist
===================================================================
--- branches/Cog/macbuild/CoreVM.plist	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/macbuild/CoreVM.plist	2011-08-16 22:28:12 UTC (rev 2487)
@@ -368,11 +368,11 @@
 	<key>CFBundleExecutable</key>
 	<string>Croquet</string>
 	<key>CFBundleGetInfoString</key>
-	<string>Croquet Cog 4.0.0 http://www.mirandabanda.org</string>
+	<string>Croquet Cog 4.0.0 http://www.mirandabanda.org</string><!--version-->
 	<key>CFBundleShortVersionString</key>
-	<string>Croquet Cog 4.0.0</string>
+	<string>Croquet Cog 4.0.0</string><!--version-->
 	<key>CFBundleVersion</key>
-	<string>4.0.0</string>
+	<string>4.0.0</string><!--version-->
 	<key>CFBundleIconFile</key>
 	<string>Croquet.icns</string>
 	<key>CFBundleIdentifier</key>

Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/cogit.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGenerator VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	StackToRegisterMappingCogit VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -314,6 +314,7 @@
 #define RetN 10
 #define RootBit 0x40000000
 #define RootBitDigitLength 4
+#define SelectorDoesNotUnderstand 20
 #define SenderIndex 0
 #define SendNumArgsReg -6
 #define SFENCE 109
@@ -412,11 +413,12 @@
 char * codeEntryNameFor(char *address);
 sqInt cogCodeBase(void);
 sqInt cogCodeConstituents(void);
-static sqInt cogExtendPICCaseNMethodtag(CogMethod *cPIC, sqInt caseNMethodOrNil, sqInt caseNTag);
+static sqInt cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase);
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
+CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
 static CogMethod * cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs);
-static CogMethod * cogPICSelectornumArgsCase0MethodCase1Methodtag(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag);
+static CogMethod * cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase);
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
 static void compactCompiledCode(sqInt objectHeaderValue);
@@ -430,13 +432,14 @@
 static sqInt compileClosedPICPrototype(void);
 static CogMethod * compileCogMethod(sqInt selector);
 static AbstractInstruction * compileCPICEntry(void);
-static sqInt compileCPICCase0Case1MethodtagnumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt numArgs);
+static sqInt compileCPICCase0Case1MethodtagisMNUCasenumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs);
 static sqInt compileEntireMethod(void);
 static void compileEntry(void);
 static void compileFrameBuild(void);
 static void compileGetErrorCode(void);
 static sqInt compileInterpreterPrimitive(void (*primitiveRoutine)(void));
 static sqInt compileMethodBody(void);
+static sqInt compileMNUCPICmethodOperandnumArgs(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs);
 static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs);
 static sqInt compilePICProlog(sqInt numArgs);
 static sqInt compilePrimitive(void);
@@ -540,7 +543,7 @@
 static sqInt extendedStoreAndPopBytecode(void);
 static sqInt extendedStoreBytecode(void);
 static void fillInBlockHeadersAt(sqInt startAddress);
-static CogMethod * fillInCPICHeadersizenumArgsnumCasesselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt selector);
+static CogMethod * fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt hasMNUCase, sqInt selector);
 static CogMethod * fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector);
 static CogMethod * fillInOPICHeadersizenumArgsselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt selector);
 static usqInt findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc);
@@ -823,7 +826,6 @@
 static sqInt loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize);
 static sqInt longBranchDistance(unsigned char byteZero, unsigned char byteOne);
 static sqInt longForwardBranchDistance(unsigned char byteZero, unsigned char byteOne);
-static sqInt lookupAndCogfor(sqInt selector, sqInt receiver);
 static AbstractInstruction * gMoveAwR(sqInt address, sqInt reg);
 static AbstractInstruction * gMoveCwR(sqInt wordConstant, sqInt reg);
 static AbstractInstruction * gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg);
@@ -983,9 +985,9 @@
 static sqInt unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity);
 static sqInt unlinkIfLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector);
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod);
-void unlinkSendsOf(sqInt selector);
+void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(CogMethod *targetMethod);
+void unlinkSendsTo(sqInt targetMethodObject);
 static sqInt unsignedShortAt(AbstractInstruction * self_in_unsignedShortAt, sqInt byteAddress);
 static void updateLabel(AbstractInstruction * self_in_updateLabel, AbstractInstruction *labelInstruction);
 static sqInt updateMaybeObjRefAt(sqInt mcpc);
@@ -2208,27 +2210,65 @@
 ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver)
 {
     sqInt cacheTag;
+    sqInt errorSelectorOrNil;
+    sqInt errsel;
+    sqInt method;
+    sqInt methodOrSelectorIndex;
     sqInt newTargetMethodOrNil;
     sqInt outerReturn;
     sqInt result;
+    sqInt selector;
 
 	;
 	outerReturn = stackTop();
+	if (((cPIC->cPICNumCases)) < numPICCases) {
+		/* begin lookup:for:methodAndErrorSelectorInto: */
+		VM_LABEL(0lookupformethodAndErrorSelectorInto);
+		selector = (cPIC->selector);
+		methodOrSelectorIndex = lookupreceiver(selector, receiver);
+		if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+			assert(isOopCompiledMethod(methodOrSelectorIndex));
+			if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+			 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+				cogselector(methodOrSelectorIndex, selector);
+			}
+						newTargetMethodOrNil = methodOrSelectorIndex;
+			errorSelectorOrNil = 0;
 
-	/* We assume lookupAndCog:for: will *not* reclaim the method zone */
+			goto l1;
+		}
+		if (methodOrSelectorIndex == SelectorDoesNotUnderstand) {
+			methodOrSelectorIndex = lookupreceiver(splObj(SelectorDoesNotUnderstand), receiver);
+			if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+				assert(isOopCompiledMethod(methodOrSelectorIndex));
+				if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+				 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+					cogselector(methodOrSelectorIndex, selector);
+				}
+								newTargetMethodOrNil = methodOrSelectorIndex;
+				errorSelectorOrNil = SelectorDoesNotUnderstand;
 
-	newTargetMethodOrNil = lookupAndCogfor((cPIC->selector), receiver);
+				goto l1;
+			}
+		}
+				newTargetMethodOrNil = methodOrSelectorIndex;
+		errorSelectorOrNil = null;
+
+	l1:	/* end lookup:for:methodAndErrorSelectorInto: */;
+	}
 	assert(outerReturn == (stackTop()));
 	cacheTag = inlineCacheTagForInstance(receiver);
 	if ((((cPIC->cPICNumCases)) >= numPICCases)
+	 || (((errorSelectorOrNil != null)
+ && (errorSelectorOrNil != SelectorDoesNotUnderstand))
 	 || ((inlineCacheTagIsYoung(cacheTag))
-	 || ((newTargetMethodOrNil != null)
-	 && (isYoung(newTargetMethodOrNil))))) {
+	 || ((newTargetMethodOrNil == null)
+	 || (isYoung(newTargetMethodOrNil)))))) {
 		result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver);
 		assert(!result);
 		return ceSendFromInLineCacheMiss(cPIC);
 	}
-	cogExtendPICCaseNMethodtag(cPIC, newTargetMethodOrNil, cacheTag);
+	cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand);
 	executeCogMethodFromLinkedSendwithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn));
 	return null;
 }
@@ -2301,12 +2341,17 @@
 {
     sqInt cacheTag;
     sqInt entryPoint;
+    sqInt errorSelectorOrNil;
+    sqInt errsel;
     sqInt extent;
     sqInt innerReturn;
+    sqInt method;
+    sqInt methodOrSelectorIndex;
     sqInt newTargetMethodOrNil;
     sqInt outerReturn;
     CogMethod *pic;
     sqInt result;
+    sqInt selector;
     CogMethod *targetMethod;
 
 
@@ -2329,15 +2374,46 @@
 #  endif /* NewspeakVM */
 
 	assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint);
+	/* begin lookup:for:methodAndErrorSelectorInto: */
+	VM_LABEL(1lookupformethodAndErrorSelectorInto);
+	selector = (targetMethod->selector);
+	methodOrSelectorIndex = lookupreceiver(selector, receiver);
+	if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+		assert(isOopCompiledMethod(methodOrSelectorIndex));
+		if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+		 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+			cogselector(methodOrSelectorIndex, selector);
+		}
+				newTargetMethodOrNil = methodOrSelectorIndex;
+		errorSelectorOrNil = 0;
 
-	/* We assume lookupAndCog:for: will *not* reclaim the method zone */
+		goto l1;
+	}
+	if (methodOrSelectorIndex == SelectorDoesNotUnderstand) {
+		methodOrSelectorIndex = lookupreceiver(splObj(SelectorDoesNotUnderstand), receiver);
+		if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+			assert(isOopCompiledMethod(methodOrSelectorIndex));
+			if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+			 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+				cogselector(methodOrSelectorIndex, selector);
+			}
+						newTargetMethodOrNil = methodOrSelectorIndex;
+			errorSelectorOrNil = SelectorDoesNotUnderstand;
 
-	newTargetMethodOrNil = lookupAndCogfor((targetMethod->selector), receiver);
+			goto l1;
+		}
+	}
+		newTargetMethodOrNil = methodOrSelectorIndex;
+	errorSelectorOrNil = null;
+
+l1:	/* end lookup:for:methodAndErrorSelectorInto: */;
 	assert(outerReturn == (stackTop()));
 	cacheTag = inlineCacheTagForInstance(receiver);
-	if ((inlineCacheTagIsYoung(cacheTag))
-	 || ((newTargetMethodOrNil != null)
-	 && (isYoung(newTargetMethodOrNil)))) {
+	if (((errorSelectorOrNil != null)
+ && (errorSelectorOrNil != SelectorDoesNotUnderstand))
+	 || ((inlineCacheTagIsYoung(cacheTag))
+	 || ((newTargetMethodOrNil == null)
+	 || (isYoung(newTargetMethodOrNil))))) {
 		result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver);
 		assert(!result);
 		return ceSendFromInLineCacheMiss(targetMethod);
@@ -2347,8 +2423,9 @@
 
 		/* otherwise attempt to create a closed PIC for the two cases. */
 
-		pic = cogPICSelectornumArgsCase0MethodCase1Methodtag((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag);
-		if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) {
+		pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand);
+		if ((errorSelectorOrNil != null)
+		 || ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1)))) {
 			if ((((sqInt)pic)) == InsufficientCodeSpace) {
 				callForCogCompiledCodeCompaction();
 			}
@@ -2833,11 +2910,17 @@
 }
 
 
+/*	Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch
+	direct to
+	its unchecked entry-point. If caseNMethod is not cogged, jump to the fast
+	interpreter dispatch, and if isMNUCase then dispatch to fast MNU
+	invocation and mark the cPIC as
+	having the MNU case for cache flushing. */
 /*	stack allocate the various collections so that they
 	are effectively garbage collected on return. */
 
 static sqInt
-cogExtendPICCaseNMethodtag(CogMethod *cPIC, sqInt caseNMethodOrNil, sqInt caseNTag)
+cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase)
 {
     sqInt address;
     sqInt end;
@@ -2849,16 +2932,19 @@
 	compilationBreakpoint((cPIC->selector), lengthOf((cPIC->selector)));
 	allocateOpcodesbytecodes(5, 0);
 	assert(!(inlineCacheTagIsYoung(caseNTag)));
-	if ((caseNMethodOrNil != null)
-	 && (methodHasCogMethod(caseNMethodOrNil))) {
+	assert((caseNMethod != null)
+	 && (!(isYoung(caseNMethod))));
+	if ((!isMNUCase)
+	 && (methodHasCogMethod(caseNMethod))) {
 		operand = 0;
-		target = (((sqInt)(cogMethodOf(caseNMethodOrNil)))) + cmNoCheckEntryOffset;
+		target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset;
 	}
 	else {
-		assert((caseNMethodOrNil == null)
-		 || (!(isYoung(caseNMethodOrNil))));
-		operand = caseNMethodOrNil;
-		target = (((sqInt)cPIC)) + ((caseNMethodOrNil == null
+		if (isMNUCase) {
+			(cPIC->cpicHasMNUCase = 1);
+		}
+		operand = caseNMethod;
+		target = (((sqInt)cPIC)) + ((isMNUCase
 	? sizeof(CogMethod)
 	: (interpretOffset()) - (callInstructionByteSize(backEnd))));
 	}
@@ -2871,8 +2957,8 @@
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, ((sqInt)cPIC), ClassReg);
 	/* begin JumpLong: */
-	jumpTarget = ((void *) (cPICMissTrampolineFor((cPIC->cmNumArgs))));
-	genoperand(JumpLong, ((sqInt)jumpTarget));
+	jumpTarget = cPICMissTrampolineFor((cPIC->cmNumArgs));
+	genoperand(JumpLong, jumpTarget);
 	computeMaximumSizes();
 	address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) - 1, cPIC);
 	size = generateInstructionsAt(address);
@@ -2961,6 +3047,44 @@
 }
 
 
+/*	Attempt to create a one-case PIC for an MNU.
+	The tag for the case is at the send site and so doesn't need to be
+	generated. 
+ */
+
+CogMethod *
+cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs)
+{
+    sqInt end;
+    sqInt headerSize;
+    sqInt size;
+    sqInt startAddress;
+
+	compilationBreakpoint(selector, lengthOf(selector));
+	if (endCPICCase0 == null) {
+		return NotFullyInitialized;
+	}
+	startAddress = allocate(closedPICSize);
+	if (startAddress == 0) {
+		return ((CogMethod *) InsufficientCodeSpace);
+	}
+	(methodLabel->address = startAddress);
+	(methodLabel->dependent = null);
+	allocateOpcodesbytecodes(numPICCases * 7, 0);
+	compileMNUCPICmethodOperandnumArgs(((CogMethod *) startAddress), methodOperand, numArgs);
+	computeMaximumSizes();
+	headerSize = sizeof(CogMethod);
+	size = generateInstructionsAt(startAddress + headerSize);
+
+	/* The missOffset is th same as the interpretOffset. */
+
+	end = outputInstructionsAt(startAddress + headerSize);
+	assert(missOffset == ((((interpretCall->address)) + ((interpretCall->machineCodeSize))) - startAddress));
+	assert((startAddress + cmEntryOffset) == ((entry->address)));
+	return fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(((CogMethod *) startAddress), closedPICSize, numArgs, 1, 1, selector);
+}
+
+
 /*	Create an Open PIC. Temporarily create a direct call of
 	ceSendFromOpenPIC:. Should become a probe of the first-level method lookup
 	cache followed by a
@@ -2997,15 +3121,15 @@
 
 
 /*	Attempt to create a two-case PIC for case0CogMethod and
-	case1MethodOrNil,case1Tag. The tag for case0CogMethod is at the send site
-	and so doesn't need to be generated.
-	case1MethodOrNil may be any of
+	case1Method,case1Tag. The tag for case0CogMethod is at the send site and
+	so doesn't need to be generated.
+	case1Method may be any of
 	- a Cog method; link to its unchecked entry-point
 	- a CompiledMethod; link to ceInterpretMethodFromPIC:
-	- nil; link to ceMNUFromPICMNUMethod:receiver: */
+	- a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */
 
 static CogMethod *
-cogPICSelectornumArgsCase0MethodCase1Methodtag(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag)
+cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase)
 {
     sqInt end;
     sqInt headerSize;
@@ -3020,7 +3144,7 @@
 	(methodLabel->address = startAddress);
 	(methodLabel->dependent = null);
 	allocateOpcodesbytecodes(numPICCases * 7, 0);
-	compileCPICCase0Case1MethodtagnumArgs(((CogMethod *) startAddress), case0CogMethod, case1MethodOrNil, case1Tag, numArgs);
+	compileCPICCase0Case1MethodtagisMNUCasenumArgs(((CogMethod *) startAddress), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs);
 	computeMaximumSizes();
 	headerSize = sizeof(CogMethod);
 	size = generateInstructionsAt(startAddress + headerSize);
@@ -3032,7 +3156,7 @@
 	assert((startAddress + cmEntryOffset) == ((entry->address)));
 	assert(((endCPICCase0->address)) == (startAddress + firstCPICCaseOffset));
 	assert(((endCPICCase1->address)) == ((startAddress + firstCPICCaseOffset) + cPICCaseSize));
-	return fillInCPICHeadersizenumArgsnumCasesselector(((CogMethod *) startAddress), closedPICSize, numArgs, 2, selector);
+	return fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(((CogMethod *) startAddress), closedPICSize, numArgs, 2, isMNUCase, selector);
 }
 
 
@@ -3512,15 +3636,15 @@
 	compilePICProlog(numArgs);
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
-	genoperandoperand(MoveCwR, 99282957, ClassReg);
+	genoperandoperand(MoveCwR, 99282957, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, ((sqInt)(((void *) 1592642142))));
+	genoperand(JumpLong, 1592642142);
 	jmpTarget(jumpNext, (endCPICCase0 = gLabel()));
 	for (h = 1; h <= (numPICCases - 1); h += 1) {
 		/* begin CmpCw:R: */
 		genoperandoperand(CmpCwR, 3133021973UL + h, TempReg);
 		/* begin MoveCw:R: */
-		genoperandoperand(MoveCwR, 195929424 + h, ClassReg);
+		genoperandoperand(MoveCwR, 195929424 + h, SendNumArgsReg);
 		/* begin JumpLongZero: */
 		genoperand(JumpLongZero, ((sqInt)(((void *) (3202131424UL + h)))));
 		if (h == 1) {
@@ -3532,7 +3656,7 @@
 	genoperandoperand(MoveCwR, 179686997, ClassReg);
 	/* begin JumpLong: */
 	jumpTarget = ((void *) (cPICMissTrampolineFor(numArgs)));
-	genoperand(JumpLong, ((sqInt)jumpTarget));
+	genoperand(JumpLong, jumpTarget);
 	return 0;
 }
 
@@ -3598,33 +3722,35 @@
 
 
 /*	Compile the code for a two-case PIC for case0CogMethod and
-	case1MethodOrNil,case1Tag. The tag for case0CogMethod is at the send site
-	and so doesn't need to be generated.
-	case1MethodOrNil may be any of
+	case1Method,case1Tag. The tag for case0CogMethod is at the send site and
+	so doesn't need to be generated.
+	case1Method may be any of
 	- a Cog method; jump to its unchecked entry-point
 	- a CompiledMethod; jump to the ceInterpretFromPIC trampoline
 	- nil; call ceMNUFromPIC */
 
 static sqInt
-compileCPICCase0Case1MethodtagnumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt numArgs)
+compileCPICCase0Case1MethodtagisMNUCasenumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs)
 {
     AbstractInstruction *jumpNext;
     void *jumpTarget;
+    sqInt jumpTarget1;
     sqInt operand;
     void *targetEntry;
 
-	compilePICProlog((case0CogMethod->cmNumArgs));
+	assert(case1Method != null);
+	compilePICProlog(numArgs);
 	assert(!(inlineCacheTagIsYoung(case1Tag)));
-	if ((case1MethodOrNil != null)
-	 && (methodHasCogMethod(case1MethodOrNil))) {
+	if ((!isMNUCase)
+	 && (methodHasCogMethod(case1Method))) {
 		operand = 0;
-		targetEntry = ((void *) ((((sqInt)(cogMethodOf(case1MethodOrNil)))) + cmNoCheckEntryOffset));
+		targetEntry = ((void *) ((((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset));
 	}
 	else {
-		assert((case1MethodOrNil == null)
-		 || (!(isYoung(case1MethodOrNil))));
-		operand = case1MethodOrNil;
-		targetEntry = (case1MethodOrNil == null
+		assert((case1Method == null)
+		 || (!(isYoung(case1Method))));
+		operand = case1Method;
+		targetEntry = (case1Method == null
 			? mnuCall
 			: interpretCall);
 	}
@@ -3632,19 +3758,22 @@
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, 0, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, ((sqInt)(((void *) ((((sqInt)case0CogMethod)) + cmNoCheckEntryOffset)))));
+	genoperand(JumpLong, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset);
 	/* begin CmpCw:R: */
 	endCPICCase0 = genoperandoperand(CmpCwR, case1Tag, TempReg);
 	jmpTarget(jumpNext, endCPICCase0);
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, operand, SendNumArgsReg);
 	/* begin JumpLongZero: */
-	genoperand(JumpLongZero, ((sqInt)targetEntry));
+	jumpTarget = (isMNUCase
+		? mnuCall
+		: targetEntry);
+	genoperand(JumpLongZero, ((sqInt)jumpTarget));
 	/* begin MoveCw:R: */
 	endCPICCase1 = genoperandoperand(MoveCwR, ((sqInt)cPIC), ClassReg);
 	/* begin JumpLong: */
-	jumpTarget = ((void *) (cPICMissTrampolineFor(numArgs)));
-	genoperand(JumpLong, ((sqInt)jumpTarget));
+	jumpTarget1 = ((void *) (cPICMissTrampolineFor(numArgs)));
+	genoperand(JumpLong, jumpTarget1);
 	return 0;
 }
 
@@ -4032,6 +4161,31 @@
 }
 
 
+/*	Compile the code for a one-case MNU PIC that calls ceMNUFromPIC for
+	case0Tag The tag for case0 is at the send site and so doesn't need to be
+	generated. 
+ */
+
+static sqInt
+compileMNUCPICmethodOperandnumArgs(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs)
+{
+    AbstractInstruction *jumpNext;
+    sqInt jumpTarget;
+
+	compilePICProlog(numArgs);
+	jumpNext = compileCPICEntry();
+	/* begin MoveCw:R: */
+	genoperandoperand(MoveCwR, methodOperand, SendNumArgsReg);
+	/* begin JumpLong: */
+	genoperand(JumpLong, ((sqInt)mnuCall));
+	jmpTarget(jumpNext, gMoveCwR(((sqInt)cPIC), ClassReg));
+	/* begin JumpLong: */
+	jumpTarget = cPICMissTrampolineFor(numArgs);
+	genoperand(JumpLong, jumpTarget);
+	return 0;
+}
+
+
 /*	Compile the code for an open PIC. Perform a probe of the first-level
 	method lookup cache followed by a call of ceSendFromOpenPIC: if the probe
 	fails. Override to push the register args when calling ceSendFromOpenPIC: */
@@ -7179,7 +7333,7 @@
 }
 
 static CogMethod *
-fillInCPICHeadersizenumArgsnumCasesselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt selector)
+fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt hasMNUCase, sqInt selector)
 {
 	assert(!(isYoung(selector)));
 	(pic->cmType = CMClosedPIC);
@@ -7191,7 +7345,7 @@
 	(pic->cmNumArgs = numArgs);
 	(pic->cmRefersToYoung = 0);
 	(pic->cmUsageCount = initialClosedPICUsageCount());
-	(pic->cmIsUnlinked = 0);
+	(pic->cpicHasMNUCase = hasMNUCase);
 	(pic->cPICNumCases = numCases);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMClosedPIC);
@@ -7233,7 +7387,7 @@
 		addToYoungReferrers(method);
 	}
 	(method->cmUsageCount = initialMethodUsageCount());
-	(method->cmIsUnlinked = 0);
+	(method->cpicHasMNUCase = 0);
 	(method->blockEntryOffset = (blockEntryLabel != null
 		? ((blockEntryLabel->address)) - (((sqInt)method))
 		: 0));
@@ -7259,7 +7413,7 @@
 		addToYoungReferrers(pic);
 	}
 	(pic->cmUsageCount = initialOpenPICUsageCount());
-	(pic->cmIsUnlinked = 0);
+	(pic->cpicHasMNUCase = 0);
 	(pic->cPICNumCases = 0);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMOpenPIC);
@@ -8464,11 +8618,11 @@
 	/* Generate the non-send runtime support for Newspeak, explicit outer and implicit receiver.
 	 The dynamic frequency of explicit outer is so low we merely cann an interpreter routine. */
 	/* Cached push implicit receiver implementation.  Caller looks like
-		mov selector, ClassReg
-				call cePushImplicitReceiver
+				mov selector, ClassReg
+				call ceImplicitReceiver
 				br continue
-		Lclass	.word
-		Lmixin:	.word
+		Lclass:	.word
+		Lmixin::	.word
 		continue:
 	 If class matches class of receiver then mixin contains either 0 or the implicit receiver.
 	 If 0, answer the actual receiver, otherwise the mixin.
@@ -12926,7 +13080,7 @@
 
 	/* begin annotateCall: */
 	/* begin JumpLong: */
-	abstractInstruction = genoperand(JumpLong, ((sqInt)(((void *) callTarget))));
+	abstractInstruction = genoperand(JumpLong, callTarget);
 	return annotatewith(abstractInstruction, IsRelativeCall);
 }
 
@@ -13173,28 +13327,6 @@
 	return ((byteZero & 3) * 256) + byteOne;
 }
 
-
-/*	Lookup selector in the class of receiver. If not found answer nil.
-	If not a method (objectAsMethod) answer nil. Otherwise try to
-	compile it to machine code if appropriate. Answer the method. */
-
-static sqInt
-lookupAndCogfor(sqInt selector, sqInt receiver)
-{
-    sqInt newTargetMethodOrNil;
-
-	newTargetMethodOrNil = lookupreceiver(selector, receiver);
-	if (!((newTargetMethodOrNil != null)
-		 && (isOopCompiledMethod(newTargetMethodOrNil)))) {
-		return null;
-	}
-	if ((!(methodHasCogMethod(newTargetMethodOrNil)))
-	 && (methodShouldBeCogged(newTargetMethodOrNil))) {
-		cogselector(newTargetMethodOrNil, selector);
-	}
-	return newTargetMethodOrNil;
-}
-
 static AbstractInstruction *
 gMoveAwR(sqInt address, sqInt reg)
 {
@@ -16868,7 +17000,7 @@
 /*	Unlink all sends in cog methods. */
 
 void
-unlinkSendsOf(sqInt selector)
+unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector)
 {
     CogMethod *cogMethod;
 
@@ -16895,7 +17027,9 @@
 		}
 		else {
 			if ((((cogMethod->cmType)) != CMFree)
-			 && (((cogMethod->selector)) == selector)) {
+			 && ((isMNUSelector
+ && ((cogMethod->cpicHasMNUCase)))
+			 || (((cogMethod->selector)) == selector))) {
 				freeMethod(cogMethod);
 			}
 		}
@@ -16936,14 +17070,23 @@
 }
 
 
-/*	Unlink all sends in cog methods to a particular target method. */
+/*	Unlink all sends in cog methods to a particular target method.
+	If targetMethodObject isn't actually a method (perhaps being
+	used via invokeAsMethod) then flush all sends since anything
+	could be affected. */
 
 void
-unlinkSendsTo(CogMethod *targetMethod)
+unlinkSendsTo(sqInt targetMethodObject)
 {
     CogMethod *cogMethod;
     sqInt freedPIC;
+    CogMethod *targetMethod;
 
+	if (!((isOopCompiledMethod(targetMethodObject))
+		 && (methodHasCogMethod(targetMethodObject)))) {
+		return;
+	}
+	targetMethod = cogMethodOf(targetMethodObject);
 	if (methodZoneBase == null) {
 		return;
 	}

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/cogit.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGenerator VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 
@@ -26,6 +26,7 @@
 sqInt cogCodeConstituents(void);
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
+CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
 void enterCogCodePopReceiver(void);
@@ -68,9 +69,9 @@
 sqInt stackPageHeadroomBytes(void);
 sqInt traceLinkedSendOffset(void);
 void unlinkAllSends(void);
-void unlinkSendsOf(sqInt selector);
+void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(CogMethod *targetMethod);
+void unlinkSendsTo(sqInt targetMethodObject);
 void voidCogCompiledCode(void);
 
 

Modified: branches/Cog/nscogsrc/vm/cogmethod.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogmethod.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/cogmethod.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGenerator VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 typedef struct {
@@ -8,7 +8,7 @@
 	unsigned		cmNumArgs : 8;
 	unsigned		cmType : 3;
 	unsigned		cmRefersToYoung : 1;
-	unsigned		cmIsUnlinked : 1;
+	unsigned		cpicHasMNUCase : 1;
 	unsigned		cmUsageCount : 3;
 	unsigned		stackCheckOffset : 16;
  } CogBlockMethod;
@@ -18,7 +18,7 @@
 	unsigned		cmNumArgs : 8;
 	unsigned		cmType : 3;
 	unsigned		cmRefersToYoung : 1;
-	unsigned		cmIsUnlinked : 1;
+	unsigned		cpicHasMNUCase : 1;
 	unsigned		cmUsageCount : 3;
 	unsigned		stackCheckOffset : 16;
 	unsigned short	blockSize;

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -471,6 +471,7 @@
 void dumpTraceLog(void);
 static sqInt eeInstantiateAndInitializeClassindexableSize(sqInt classPointer, sqInt size);
 sqInt eeInstantiateClassindexableSize(sqInt classPointer, sqInt size);
+static sqInt eeInstantiateMethodContextByteSize(sqInt sizeInBytes);
 static sqInt eeInstantiateSmallClasssizeInBytes(sqInt classPointer, sqInt sizeInBytes);
 static sqInt encodedNativePCOfcogMethod(sqInt mcpc, CogBlockMethod *cogMethod);
 static sqInt ensureCallerContext(char *theFP);
@@ -518,7 +519,7 @@
 double floatArg(sqInt index);
 sqInt floatObjectOf(double aFloat);
 double floatValueOf(sqInt oop);
-static void flushExternalPrimitiveOf(sqInt methodObj);
+void flushExternalPrimitiveOf(sqInt methodObj);
 static void flushExternalPrimitives(void);
 void forceInterruptCheck(void);
 void forceInterruptCheckFromHeartbeat(void);
@@ -557,7 +558,7 @@
 static sqInt getShortFromFileswap(sqImageFile aFile, sqInt swapFlag);
 sqInt getStackPointer(void);
 sqInt getThisSessionID(void);
-static sqInt handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean);
+static sqInt handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage);
 static void handleStackOverflow(void);
 static sqInt handleStackOverflowOrEventAllowContextSwitch(sqInt mayContextSwitch);
 sqInt headerOf(sqInt methodPointer);
@@ -685,6 +686,7 @@
 static sqInt mframeIsBlockActivation(char *theFP);
 static sqInt mframeReceiver(char *theFP);
 sqInt mMethodClass(void);
+static sqInt mnuMethodOrNilFor(sqInt rcvr);
 EXPORT(void) moduleUnloaded(char *aModuleName);
 static char * moveFramesInthroughtoPage(StackPage *oldPage, char *theFP, StackPage *newPage);
 static sqInt mustMapMachineCodePCcontext(sqInt theIP, sqInt aOnceMarriedContext);
@@ -984,6 +986,8 @@
 void printInstancesOf(sqInt aClassOop);
 static void printLogEntryAt(sqInt i);
 void printMemory(void);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 static void printNameOfClasscount(sqInt classOop, sqInt cnt);
 static void printNum(sqInt n);
@@ -1142,8 +1146,8 @@
 _iss sqInt nilObj;
 _iss usqInt instructionPointer;
 _iss usqInt method;
+_iss sqInt argumentCount;
 _iss usqInt freeStart;
-_iss sqInt argumentCount;
 _iss usqInt newMethod;
 _iss sqInt messageSelector;
 _iss StackPage * pages;
@@ -1885,7 +1889,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.114";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.117";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -10373,7 +10377,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(GIV(lkupClass)))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, GIV(lkupClass), 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, GIV(lkupClass));
 			assert(0);
 		}
 	}
@@ -10468,13 +10472,45 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     CogMethod *cPIC;
+    sqInt primBits;
+    sqInt primitiveIndex;
+    char *sp;
+    sqInt top;
 
 	assert(((rcvr & 1))
 	 || (addressCouldBeObj(rcvr)));
+	assert((aMethodObj == 0)
+	 || ((addressCouldBeObj(aMethodObj))
+	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
 	assert(((cPIC->cmType)) == CMClosedPIC);
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
+	if (aMethodObj != 0) {
+		/* begin popStack */
+		top = longAt(GIV(stackPointer));
+		GIV(stackPointer) += BytesPerWord;
+		GIV(instructionPointer) = ((sqInt) top);
+		createActualMessageTo(fetchClassOf(rcvr));
+		if (((aMethodObj & 1) == 0)
+		 && ((((((usqInt) (longAt(aMethodObj))) >> 8) & 15) >= 12)
+		 && (isCogMethodReference(longAt((aMethodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+			/* begin push: */
+			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+			GIV(stackPointer) = sp;
+			executeCogMethodFromUnlinkedSendwithReceiver(cogMethodOf(aMethodObj), rcvr);
+			assert(0);
+		}
+		GIV(newMethod) = aMethodObj;
+		/* begin primitiveIndexOf: */
+		primBits = (((usqInt) (headerOf(aMethodObj))) >> 1) & 268435967;
+		primitiveIndex = (primBits & 511) + (((usqInt) primBits) >> 19);
+		/* begin functionPointerFor:inClass: */
+		primitiveFunctionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex
+	? 0
+	: primitiveTable[primitiveIndex])));
+		interpretMethodFromMachineCode(); return;
+	}
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
 		GIV(lkupClass) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
@@ -10489,7 +10525,8 @@
 		goto l1;
 	}
 l1:	/* end fetchClassOf: */;
-	handleMNUInMachineCodeToclassForMessagemayLink(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass), 0);
+	handleMNUInMachineCodeToclassForMessage(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass));
+	assert(0);
 }
 
 sqInt
@@ -10899,7 +10936,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10988,7 +11025,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -11118,7 +11155,14 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, canLinkCacheTag);
+			if (canLinkCacheTag
+			 && ((errSelIdx == SelectorDoesNotUnderstand)
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
+				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
+					? entryOffset()
+					: noCheckEntryOffset()), rcvr);
+			}
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -12413,8 +12457,8 @@
 
 	assert((!(isOopCompiledMethod(obj)))
 	 || (!(methodHasCogMethod(obj))));
-	assert((!(isContext(oop)))
-	 || (!(isMarriedOrWidowedContext(oop))));
+	assert((!(isContext(obj)))
+	 || (!(isMarriedOrWidowedContext(obj))));
 	assert(isNonIntegerObject(obj));
 	extraHdrBytes = headerTypeBytes[(longAt(obj)) & TypeMask];
 	/* begin sizeBitsOf: */
@@ -14195,6 +14239,91 @@
 }
 
 
+/*	This version of instantiateClass assumes that the total object 
+	size is under 256 bytes, the limit for objects with only one or 
+	two header words. Note that the size is specified in bytes 
+	and should include four bytes for the base header word.
+	Will *not* cause a GC. */
+
+static sqInt
+eeInstantiateMethodContextByteSize(sqInt sizeInBytes)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt hash;
+    sqInt header1;
+    usqInt newChunk;
+    usqInt newFreeStart;
+    sqInt newObj;
+
+	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
+	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
+	assert(sizeInBytes <= SizeMask);
+	assert((header1 & CompactClassMask) > 0);
+	header1 += sizeInBytes - (header1 & SizeMask);
+	flag("Dan");
+	/* begin eeAllocate:headerSize:h1:h2:h3: */
+	/* begin allocateInterpreterChunk: */
+	newChunk = GIV(freeStart);
+	newFreeStart = GIV(freeStart) + (sizeInBytes + ((1 - 1) * BytesPerWord));
+	if (newFreeStart < GIV(scavengeThreshold)) {
+		if ((AllocationCheckFiller != 0)
+		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
+	? newChunk
+	: AllocationCheckFiller)))) {
+			error("last object overwritten");
+		}
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	if (GIV(freeStart) < GIV(scavengeThreshold)) {
+		/* begin scheduleIncrementalGC */
+		GIV(needGCFlag) = 1;
+		forceInterruptCheck();
+	}
+	if (newFreeStart < GIV(reserveStart)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	/* begin scheduleIncrementalGC */
+	GIV(needGCFlag) = 1;
+	forceInterruptCheck();
+	if (GIV(freeStart) <= GIV(endOfMemory)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	error("out of memory");
+	newObj = null;
+l1:	/* end allocateInterpreterChunk: */;
+	if (newObj == 0) {
+		return newObj;
+	}
+	if (1 == 3) {
+		longAtput(newObj, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
+		newObj += BytesPerWord * 2;
+	}
+	if (1 == 2) {
+		longAtput(newObj, null | HeaderTypeClass);
+		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
+		newObj += BytesPerWord;
+	}
+	if (1 == 1) {
+		longAtput(newObj, header1 | HeaderTypeShort);
+	}
+	if (DoExpensiveAssertionChecks) {
+		okayOop(newObj);
+		oopHasOkayClass(newObj);
+		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
+			error("allocate bug: did not set header of new oop correctly");
+		}
+	}
+	return newObj;
+}
+
+
 /*	This version of instantiateClass assumes that the total object
 	size is under 256 bytes, the limit for objects with only one or
 	two header words. Note that the size is specified in bytes
@@ -16106,6 +16235,10 @@
 			 && (((lengthOf(obj)) == cssz)
 			 && ((strncmp(aCString, pointerForOop(obj + BaseHeaderSize), cssz)) == 0))) {
 				printHex(obj);
+				/* begin space */
+				/* begin printChar: */
+				putchar(' ');
+				printOopShort(obj);
 				/* begin cr */
 				printf("\n");
 			}
@@ -16298,11 +16431,14 @@
 }
 
 
+/*	methodObj is a CompiledMethod containing an external primitive. Flush the
+	function address and session ID of the CM
+ */
 /*	methodObj is a CompiledMethod containing an external primitive.
 	Flush the function address and session ID of the CM. Override
 	to also flush the machine code call if one exists. */
 
-static void
+void
 flushExternalPrimitiveOf(sqInt methodObj)
 {
     sqInt lit;
@@ -17068,14 +17204,11 @@
 }
 
 
-/*	A message send from either an open PIC or an unlinked send has not
-	been understood. Load newMethod with the MNU method. If linking
-	is allowed and the target MNU method is in the cache then create a
-	closed PIC with an mnu-entry and link the send to it. messageSelector,
-	argumentCount and lkupClass have already been set by the caller. */
+/*	A message send from either an open PIC or an unlinked send has
+	not been understood. Execute the relevant resulting MNU method. */
 
 static sqInt
-handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean)
+handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt class;
     sqInt classForThisMessage;
@@ -17139,24 +17272,18 @@
 		errSelIdx = SelectorDoesNotUnderstand;
 	l1:	/* end lookupMethodNoMNUEtcInClass: */;
 		if (errSelIdx != 0) {
-			if (errSelIdx == SelectorDoesNotUnderstand) {
+			if (selectorIndex == SelectorDoesNotUnderstand) {
 				error("Recursive not understood error encountered");
 			}
 			/* begin push: */
 			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 			GIV(stackPointer) = sp;
-			return handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, classForThisMessage, 0);
+			return handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForThisMessage);
 		}
 	}
 	if (((GIV(newMethod) & 1) == 0)
 	 && ((((((usqInt) (longAt(GIV(newMethod)))) >> 8) & 15) >= 12)
 	 && (isCogMethodReference(longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
-		if (mayLinkBoolean) {
-			flag("implement creating an MNU PIC sometime");
-			if (0) {
-				error("shouldBeImplemented");
-			}
-		}
 		/* begin push: */
 		longAtput((sp1 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp1;
@@ -20394,6 +20521,7 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     sqInt class;
+    sqInt erridx;
 
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
@@ -20411,8 +20539,8 @@
 l1:	/* end fetchClassOf: */;
 	if (!(lookupInMethodCacheSelclass(selector, class))) {
 		GIV(messageSelector) = selector;
-		if ((lookupMethodNoMNUEtcInClass(class)) != 0) {
-			return null;
+		if (((erridx = lookupMethodNoMNUEtcInClass(class))) != 0) {
+			return erridx;
 		}
 	}
 	return GIV(newMethod);
@@ -21869,13 +21997,8 @@
     CogMethod *cogMethod;
     sqInt frameNumArgs;
     sqInt frameNumArgs1;
-    sqInt hash;
-    sqInt header1;
-    usqInt i;
+    sqInt i;
     sqInt methodFieldOrObj;
-    usqInt newChunk;
-    usqInt newFreeStart;
-    sqInt newObj;
     sqInt numArgs;
     sqInt numStack;
     sqInt rcvr;
@@ -21918,77 +22041,7 @@
 		rcvr = longAt(theFP + FoxIFReceiver);
 		numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs;
 	}
-	/* begin eeInstantiateMethodContextByteSize: */
-	VM_LABEL(0eeInstantiateMethodContextByteSize);
-	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
-	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
-	assert(byteSize <= SizeMask);
-	assert((header1 & CompactClassMask) > 0);
-	header1 += byteSize - (header1 & SizeMask);
-	flag("Dan");
-	/* begin eeAllocate:headerSize:h1:h2:h3: */
-	/* begin allocateInterpreterChunk: */
-	newChunk = GIV(freeStart);
-	newFreeStart = GIV(freeStart) + (byteSize + ((1 - 1) * BytesPerWord));
-	if (newFreeStart < GIV(scavengeThreshold)) {
-		if ((AllocationCheckFiller != 0)
-		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
-	? newChunk
-	: AllocationCheckFiller)))) {
-			error("last object overwritten");
-		}
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	if (GIV(freeStart) < GIV(scavengeThreshold)) {
-		/* begin scheduleIncrementalGC */
-		GIV(needGCFlag) = 1;
-		forceInterruptCheck();
-	}
-	if (newFreeStart < GIV(reserveStart)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	/* begin scheduleIncrementalGC */
-	GIV(needGCFlag) = 1;
-	forceInterruptCheck();
-	if (GIV(freeStart) <= GIV(endOfMemory)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	error("out of memory");
-	newObj = null;
-l1:	/* end allocateInterpreterChunk: */;
-	if (newObj == 0) {
-		theContext = newObj;
-		goto l2;
-	}
-	if (1 == 3) {
-		longAtput(newObj, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
-		newObj += BytesPerWord * 2;
-	}
-	if (1 == 2) {
-		longAtput(newObj, null | HeaderTypeClass);
-		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
-		newObj += BytesPerWord;
-	}
-	if (1 == 1) {
-		longAtput(newObj, header1 | HeaderTypeShort);
-	}
-	if (DoExpensiveAssertionChecks) {
-		okayOop(newObj);
-		oopHasOkayClass(newObj);
-		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
-			error("allocate bug: did not set header of new oop correctly");
-		}
-	}
-	theContext = newObj;
-l2:	/* end eeInstantiateMethodContextByteSize: */;
+	theContext = eeInstantiateMethodContextByteSize(byteSize);
 	longAtput(theFP + FoxThisContext, theContext);
 	/* begin storePointerUnchecked:ofObject:withValue: */
 	/* begin withSmallIntegerTags: */
@@ -22278,6 +22331,104 @@
 }
 
 
+/*	Lookup the doesNotUnderstand: selector in the class of the argument rcvr.
+	Answer either the matching method (cogged if appropriate), or nil, if not
+	found. 
+ */
+
+static sqInt
+mnuMethodOrNilFor(sqInt rcvr)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt currentClass;
+    sqInt dictionary;
+    sqInt header;
+    sqInt index;
+    sqInt length;
+    sqInt mask;
+    sqInt methodArray;
+    sqInt methodHeader;
+    sqInt mnuMethod;
+    sqInt mnuSelector;
+    sqInt nextSelector;
+    sqInt sz;
+    sqInt wrapAround;
+
+	/* begin fetchClassOf: */
+	if ((rcvr & 1)) {
+		currentClass = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
+		goto l2;
+	}
+	if (((ccIndex = (((usqInt) (longAt(rcvr))) >> 12) & 31)) == 0) {
+		currentClass = (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask;
+		goto l2;
+	}
+	else {
+		currentClass = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord));
+		goto l2;
+	}
+l2:	/* end fetchClassOf: */;
+	mnuSelector = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord));
+	while (currentClass != GIV(nilObj)) {
+		dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord));
+		if (dictionary == GIV(nilObj)) {
+			return null;
+		}
+		/* begin lookupMethodFor:InDictionary: */
+		/* begin fetchWordLengthOf: */
+		/* begin sizeBitsOf: */
+		header = longAt(dictionary);
+		sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+			? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
+			: header & SizeMask);
+		length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
+		mask = (length - SelectorStart) - 1;
+
+		/* It is assumed that there are some nils in this dictionary, and search will 
+	 stop when one is encountered. However, if there are no nils, then wrapAround 
+	 will be detected the second time the loop gets to the end of the table. */
+
+		index = SelectorStart + (mask & (((mnuSelector & 1)
+	? (mnuSelector >> 1)
+	: (((usqInt) (longAt(mnuSelector))) >> HashBitsOffset) & HashMaskUnshifted)));
+		wrapAround = 0;
+		while (1) {
+			nextSelector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+			if (nextSelector == GIV(nilObj)) {
+				mnuMethod = null;
+				goto l1;
+			}
+			if (nextSelector == mnuSelector) {
+				methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+				mnuMethod = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
+				goto l1;
+			}
+			index += 1;
+			if (index == length) {
+				if (wrapAround) {
+					mnuMethod = null;
+					goto l1;
+				}
+				wrapAround = 1;
+				index = SelectorStart;
+			}
+		}
+		mnuMethod = null;
+	l1:	/* end lookupMethodFor:InDictionary: */;
+		if (mnuMethod != null) {
+			methodHeader = longAt((mnuMethod + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+			if ((!(isCogMethodReference(methodHeader)))
+			 && (((((usqInt) methodHeader) >> 10) & 255) <= maxLiteralCountForCompile)) {
+				cogselector(mnuMethod, mnuSelector);
+			}
+			return mnuMethod;
+		}
+		currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex << ShiftForWord));
+	}
+	return null;
+}
+
+
 /*	The module with the given name was just unloaded. 
 	Make sure we have no dangling references. */
 
@@ -25007,7 +25158,7 @@
 		if (((((usqInt) objHeader) >> 12) & 31) == ClassMethodContextCompactIndex) {
 			/* begin cloneContext: */
 			VM_LABEL(0cloneContext);
-			cloned = clone(receiver);
+			cloned = eeInstantiateMethodContextByteSize(byteSizeOf(receiver));
 			if (cloned != 0) {
 				for (i = 0; i <= StackPointerIndex; i += 1) {
 					/* begin storePointerUnchecked:ofObject:withValue: */
@@ -29317,6 +29468,10 @@
 
 
 /*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
 	cache that
 	refer to this method, presumably because it has been redefined, overridden
 	or removed.
@@ -29340,22 +29495,17 @@
 		}
 		probe += MethodCacheEntrySize;
 	}
-	if (((oldMethod & 1) == 0)
-	 && (((((usqInt) (longAt(oldMethod))) >> 8) & 15) >= 12)) {
-		/* begin primitiveIndexOf: */
-		primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
-		primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
-		if (primIdx == PrimitiveExternalCallIndex) {
-			flushExternalPrimitiveOf(oldMethod);
-		}
-		if (methodHasCogMethod(oldMethod)) {
-			unlinkSendsTo(cogMethodOf(oldMethod));
-		}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
 	}
 	/* begin flushAtCache */
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
+	unlinkSendsTo(longAt(GIV(stackPointer)));
 }
 
 
@@ -29386,7 +29536,7 @@
 			GIV(atCache)[i1] = 0;
 		}
 	}
-	unlinkSendsOf(selector);
+	unlinkSendsOfisMNUSelector(selector, selector == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord))));
 }
 
 
@@ -38046,6 +38196,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38073,6 +38225,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38750,7 +38904,49 @@
 	printf("\n");
 }
 
+void
+printMethodDictionaryOf(sqInt behavior)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
 
+	/* begin printMethodDictionary: */
+	VM_LABEL(0printMethodDictionary);
+	methodArray = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)))) - 1); index += 1) {
+		selector = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+void
+printMethodDictionary(sqInt dictionary)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
+
+	methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(dictionary)) - 1); index += 1) {
+		selector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+
 /*	Scan the heap printing the oops of any and all objects that refer to anOop */
 
 void
@@ -38929,8 +39125,6 @@
 
 	/* begin printOopShortInner: */
 	VM_LABEL(0printOopShortInner);
-	/* begin printChar: */
-	putchar('=');
 	if ((oop & 1)) {
 		printNum((oop >> 1));
 		/* begin printChar: */
@@ -38999,10 +39193,10 @@
 	if (nameLen == 10) {
 		if (!(strncmp(name, "ByteString", 10))) {
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			printStringOf(oop);
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			goto l2;
 		}
 		if (!(strncmp(name, "ByteSymbol", 10))) {

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 
@@ -72,6 +72,7 @@
 sqInt falseObject(void);
 sqInt fetchByteofObject(sqInt byteIndex, sqInt oop);
 void findString(char *aCString);
+void flushExternalPrimitiveOf(sqInt methodObj);
 sqInt formatOfClass(sqInt classPointer);
 usqInt framePointerAddress(void);
 usqInt freeStartAddress(void);
@@ -144,6 +145,8 @@
 void printCogMethod(CogMethod *cogMethod);
 void printHex(sqInt n);
 void printInstancesOf(sqInt aClassOop);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 void printObjectsFromto(sqInt startAddress, sqInt endAddress);
 void printProcessStack(sqInt aProcess);

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -474,6 +474,7 @@
 void dumpTraceLog(void);
 static sqInt eeInstantiateAndInitializeClassindexableSize(sqInt classPointer, sqInt size);
 sqInt eeInstantiateClassindexableSize(sqInt classPointer, sqInt size);
+static sqInt eeInstantiateMethodContextByteSize(sqInt sizeInBytes);
 static sqInt eeInstantiateSmallClasssizeInBytes(sqInt classPointer, sqInt sizeInBytes);
 static sqInt encodedNativePCOfcogMethod(sqInt mcpc, CogBlockMethod *cogMethod);
 static sqInt ensureCallerContext(char *theFP);
@@ -521,7 +522,7 @@
 double floatArg(sqInt index);
 sqInt floatObjectOf(double aFloat);
 double floatValueOf(sqInt oop);
-static void flushExternalPrimitiveOf(sqInt methodObj);
+void flushExternalPrimitiveOf(sqInt methodObj);
 static void flushExternalPrimitives(void);
 void forceInterruptCheck(void);
 void forceInterruptCheckFromHeartbeat(void);
@@ -560,7 +561,7 @@
 static sqInt getShortFromFileswap(sqImageFile aFile, sqInt swapFlag);
 sqInt getStackPointer(void);
 sqInt getThisSessionID(void);
-static sqInt handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean);
+static sqInt handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage);
 static void handleStackOverflow(void);
 static sqInt handleStackOverflowOrEventAllowContextSwitch(sqInt mayContextSwitch);
 sqInt headerOf(sqInt methodPointer);
@@ -688,6 +689,7 @@
 static sqInt mframeIsBlockActivation(char *theFP);
 static sqInt mframeReceiver(char *theFP);
 sqInt mMethodClass(void);
+static sqInt mnuMethodOrNilFor(sqInt rcvr);
 EXPORT(void) moduleUnloaded(char *aModuleName);
 static char * moveFramesInthroughtoPage(StackPage *oldPage, char *theFP, StackPage *newPage);
 static sqInt mustMapMachineCodePCcontext(sqInt theIP, sqInt aOnceMarriedContext);
@@ -987,6 +989,8 @@
 void printInstancesOf(sqInt aClassOop);
 static void printLogEntryAt(sqInt i);
 void printMemory(void);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 static void printNameOfClasscount(sqInt classOop, sqInt cnt);
 static void printNum(sqInt n);
@@ -1145,8 +1149,8 @@
 _iss sqInt nilObj;
 _iss usqInt instructionPointer;
 _iss usqInt method;
+_iss sqInt argumentCount;
 _iss usqInt freeStart;
-_iss sqInt argumentCount;
 _iss usqInt newMethod;
 _iss sqInt messageSelector;
 _iss StackPage * pages;
@@ -1888,7 +1892,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.114";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.117";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -10377,7 +10381,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(GIV(lkupClass)))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, GIV(lkupClass), 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, GIV(lkupClass));
 			assert(0);
 		}
 	}
@@ -10472,13 +10476,45 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     CogMethod *cPIC;
+    sqInt primBits;
+    sqInt primitiveIndex;
+    char *sp;
+    sqInt top;
 
 	assert(((rcvr & 1))
 	 || (addressCouldBeObj(rcvr)));
+	assert((aMethodObj == 0)
+	 || ((addressCouldBeObj(aMethodObj))
+	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
 	assert(((cPIC->cmType)) == CMClosedPIC);
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
+	if (aMethodObj != 0) {
+		/* begin popStack */
+		top = longAt(GIV(stackPointer));
+		GIV(stackPointer) += BytesPerWord;
+		GIV(instructionPointer) = ((sqInt) top);
+		createActualMessageTo(fetchClassOf(rcvr));
+		if (((aMethodObj & 1) == 0)
+		 && ((((((usqInt) (longAt(aMethodObj))) >> 8) & 15) >= 12)
+		 && (isCogMethodReference(longAt((aMethodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+			/* begin push: */
+			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+			GIV(stackPointer) = sp;
+			executeCogMethodFromUnlinkedSendwithReceiver(cogMethodOf(aMethodObj), rcvr);
+			assert(0);
+		}
+		GIV(newMethod) = aMethodObj;
+		/* begin primitiveIndexOf: */
+		primBits = (((usqInt) (headerOf(aMethodObj))) >> 1) & 268435967;
+		primitiveIndex = (primBits & 511) + (((usqInt) primBits) >> 19);
+		/* begin functionPointerFor:inClass: */
+		primitiveFunctionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex
+	? 0
+	: primitiveTable[primitiveIndex])));
+		interpretMethodFromMachineCode(); return;
+	}
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
 		GIV(lkupClass) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
@@ -10493,7 +10529,8 @@
 		goto l1;
 	}
 l1:	/* end fetchClassOf: */;
-	handleMNUInMachineCodeToclassForMessagemayLink(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass), 0);
+	handleMNUInMachineCodeToclassForMessage(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass));
+	assert(0);
 }
 
 sqInt
@@ -10903,7 +10940,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10992,7 +11029,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -11122,7 +11159,14 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, canLinkCacheTag);
+			if (canLinkCacheTag
+			 && ((errSelIdx == SelectorDoesNotUnderstand)
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
+				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
+					? entryOffset()
+					: noCheckEntryOffset()), rcvr);
+			}
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -12417,8 +12461,8 @@
 
 	assert((!(isOopCompiledMethod(obj)))
 	 || (!(methodHasCogMethod(obj))));
-	assert((!(isContext(oop)))
-	 || (!(isMarriedOrWidowedContext(oop))));
+	assert((!(isContext(obj)))
+	 || (!(isMarriedOrWidowedContext(obj))));
 	assert(isNonIntegerObject(obj));
 	extraHdrBytes = headerTypeBytes[(longAt(obj)) & TypeMask];
 	/* begin sizeBitsOf: */
@@ -14199,6 +14243,91 @@
 }
 
 
+/*	This version of instantiateClass assumes that the total object 
+	size is under 256 bytes, the limit for objects with only one or 
+	two header words. Note that the size is specified in bytes 
+	and should include four bytes for the base header word.
+	Will *not* cause a GC. */
+
+static sqInt
+eeInstantiateMethodContextByteSize(sqInt sizeInBytes)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt hash;
+    sqInt header1;
+    usqInt newChunk;
+    usqInt newFreeStart;
+    sqInt newObj;
+
+	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
+	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
+	assert(sizeInBytes <= SizeMask);
+	assert((header1 & CompactClassMask) > 0);
+	header1 += sizeInBytes - (header1 & SizeMask);
+	flag("Dan");
+	/* begin eeAllocate:headerSize:h1:h2:h3: */
+	/* begin allocateInterpreterChunk: */
+	newChunk = GIV(freeStart);
+	newFreeStart = GIV(freeStart) + (sizeInBytes + ((1 - 1) * BytesPerWord));
+	if (newFreeStart < GIV(scavengeThreshold)) {
+		if ((AllocationCheckFiller != 0)
+		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
+	? newChunk
+	: AllocationCheckFiller)))) {
+			error("last object overwritten");
+		}
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	if (GIV(freeStart) < GIV(scavengeThreshold)) {
+		/* begin scheduleIncrementalGC */
+		GIV(needGCFlag) = 1;
+		forceInterruptCheck();
+	}
+	if (newFreeStart < GIV(reserveStart)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	/* begin scheduleIncrementalGC */
+	GIV(needGCFlag) = 1;
+	forceInterruptCheck();
+	if (GIV(freeStart) <= GIV(endOfMemory)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	error("out of memory");
+	newObj = null;
+l1:	/* end allocateInterpreterChunk: */;
+	if (newObj == 0) {
+		return newObj;
+	}
+	if (1 == 3) {
+		longAtput(newObj, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
+		newObj += BytesPerWord * 2;
+	}
+	if (1 == 2) {
+		longAtput(newObj, null | HeaderTypeClass);
+		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
+		newObj += BytesPerWord;
+	}
+	if (1 == 1) {
+		longAtput(newObj, header1 | HeaderTypeShort);
+	}
+	if (DoExpensiveAssertionChecks) {
+		okayOop(newObj);
+		oopHasOkayClass(newObj);
+		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
+			error("allocate bug: did not set header of new oop correctly");
+		}
+	}
+	return newObj;
+}
+
+
 /*	This version of instantiateClass assumes that the total object
 	size is under 256 bytes, the limit for objects with only one or
 	two header words. Note that the size is specified in bytes
@@ -16110,6 +16239,10 @@
 			 && (((lengthOf(obj)) == cssz)
 			 && ((strncmp(aCString, pointerForOop(obj + BaseHeaderSize), cssz)) == 0))) {
 				printHex(obj);
+				/* begin space */
+				/* begin printChar: */
+				putchar(' ');
+				printOopShort(obj);
 				/* begin cr */
 				printf("\n");
 			}
@@ -16302,11 +16435,14 @@
 }
 
 
+/*	methodObj is a CompiledMethod containing an external primitive. Flush the
+	function address and session ID of the CM
+ */
 /*	methodObj is a CompiledMethod containing an external primitive.
 	Flush the function address and session ID of the CM. Override
 	to also flush the machine code call if one exists. */
 
-static void
+void
 flushExternalPrimitiveOf(sqInt methodObj)
 {
     sqInt lit;
@@ -17072,14 +17208,11 @@
 }
 
 
-/*	A message send from either an open PIC or an unlinked send has not
-	been understood. Load newMethod with the MNU method. If linking
-	is allowed and the target MNU method is in the cache then create a
-	closed PIC with an mnu-entry and link the send to it. messageSelector,
-	argumentCount and lkupClass have already been set by the caller. */
+/*	A message send from either an open PIC or an unlinked send has
+	not been understood. Execute the relevant resulting MNU method. */
 
 static sqInt
-handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean)
+handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt class;
     sqInt classForThisMessage;
@@ -17143,24 +17276,18 @@
 		errSelIdx = SelectorDoesNotUnderstand;
 	l1:	/* end lookupMethodNoMNUEtcInClass: */;
 		if (errSelIdx != 0) {
-			if (errSelIdx == SelectorDoesNotUnderstand) {
+			if (selectorIndex == SelectorDoesNotUnderstand) {
 				error("Recursive not understood error encountered");
 			}
 			/* begin push: */
 			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 			GIV(stackPointer) = sp;
-			return handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, classForThisMessage, 0);
+			return handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForThisMessage);
 		}
 	}
 	if (((GIV(newMethod) & 1) == 0)
 	 && ((((((usqInt) (longAt(GIV(newMethod)))) >> 8) & 15) >= 12)
 	 && (isCogMethodReference(longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
-		if (mayLinkBoolean) {
-			flag("implement creating an MNU PIC sometime");
-			if (0) {
-				error("shouldBeImplemented");
-			}
-		}
 		/* begin push: */
 		longAtput((sp1 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp1;
@@ -20398,6 +20525,7 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     sqInt class;
+    sqInt erridx;
 
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
@@ -20415,8 +20543,8 @@
 l1:	/* end fetchClassOf: */;
 	if (!(lookupInMethodCacheSelclass(selector, class))) {
 		GIV(messageSelector) = selector;
-		if ((lookupMethodNoMNUEtcInClass(class)) != 0) {
-			return null;
+		if (((erridx = lookupMethodNoMNUEtcInClass(class))) != 0) {
+			return erridx;
 		}
 	}
 	return GIV(newMethod);
@@ -21873,13 +22001,8 @@
     CogMethod *cogMethod;
     sqInt frameNumArgs;
     sqInt frameNumArgs1;
-    sqInt hash;
-    sqInt header1;
-    usqInt i;
+    sqInt i;
     sqInt methodFieldOrObj;
-    usqInt newChunk;
-    usqInt newFreeStart;
-    sqInt newObj;
     sqInt numArgs;
     sqInt numStack;
     sqInt rcvr;
@@ -21922,77 +22045,7 @@
 		rcvr = longAt(theFP + FoxIFReceiver);
 		numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs;
 	}
-	/* begin eeInstantiateMethodContextByteSize: */
-	VM_LABEL(0eeInstantiateMethodContextByteSize);
-	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
-	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
-	assert(byteSize <= SizeMask);
-	assert((header1 & CompactClassMask) > 0);
-	header1 += byteSize - (header1 & SizeMask);
-	flag("Dan");
-	/* begin eeAllocate:headerSize:h1:h2:h3: */
-	/* begin allocateInterpreterChunk: */
-	newChunk = GIV(freeStart);
-	newFreeStart = GIV(freeStart) + (byteSize + ((1 - 1) * BytesPerWord));
-	if (newFreeStart < GIV(scavengeThreshold)) {
-		if ((AllocationCheckFiller != 0)
-		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
-	? newChunk
-	: AllocationCheckFiller)))) {
-			error("last object overwritten");
-		}
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	if (GIV(freeStart) < GIV(scavengeThreshold)) {
-		/* begin scheduleIncrementalGC */
-		GIV(needGCFlag) = 1;
-		forceInterruptCheck();
-	}
-	if (newFreeStart < GIV(reserveStart)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	/* begin scheduleIncrementalGC */
-	GIV(needGCFlag) = 1;
-	forceInterruptCheck();
-	if (GIV(freeStart) <= GIV(endOfMemory)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	error("out of memory");
-	newObj = null;
-l1:	/* end allocateInterpreterChunk: */;
-	if (newObj == 0) {
-		theContext = newObj;
-		goto l2;
-	}
-	if (1 == 3) {
-		longAtput(newObj, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
-		newObj += BytesPerWord * 2;
-	}
-	if (1 == 2) {
-		longAtput(newObj, null | HeaderTypeClass);
-		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
-		newObj += BytesPerWord;
-	}
-	if (1 == 1) {
-		longAtput(newObj, header1 | HeaderTypeShort);
-	}
-	if (DoExpensiveAssertionChecks) {
-		okayOop(newObj);
-		oopHasOkayClass(newObj);
-		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
-			error("allocate bug: did not set header of new oop correctly");
-		}
-	}
-	theContext = newObj;
-l2:	/* end eeInstantiateMethodContextByteSize: */;
+	theContext = eeInstantiateMethodContextByteSize(byteSize);
 	longAtput(theFP + FoxThisContext, theContext);
 	/* begin storePointerUnchecked:ofObject:withValue: */
 	/* begin withSmallIntegerTags: */
@@ -22282,6 +22335,104 @@
 }
 
 
+/*	Lookup the doesNotUnderstand: selector in the class of the argument rcvr.
+	Answer either the matching method (cogged if appropriate), or nil, if not
+	found. 
+ */
+
+static sqInt
+mnuMethodOrNilFor(sqInt rcvr)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt currentClass;
+    sqInt dictionary;
+    sqInt header;
+    sqInt index;
+    sqInt length;
+    sqInt mask;
+    sqInt methodArray;
+    sqInt methodHeader;
+    sqInt mnuMethod;
+    sqInt mnuSelector;
+    sqInt nextSelector;
+    sqInt sz;
+    sqInt wrapAround;
+
+	/* begin fetchClassOf: */
+	if ((rcvr & 1)) {
+		currentClass = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
+		goto l2;
+	}
+	if (((ccIndex = (((usqInt) (longAt(rcvr))) >> 12) & 31)) == 0) {
+		currentClass = (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask;
+		goto l2;
+	}
+	else {
+		currentClass = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord));
+		goto l2;
+	}
+l2:	/* end fetchClassOf: */;
+	mnuSelector = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord));
+	while (currentClass != GIV(nilObj)) {
+		dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord));
+		if (dictionary == GIV(nilObj)) {
+			return null;
+		}
+		/* begin lookupMethodFor:InDictionary: */
+		/* begin fetchWordLengthOf: */
+		/* begin sizeBitsOf: */
+		header = longAt(dictionary);
+		sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+			? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
+			: header & SizeMask);
+		length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
+		mask = (length - SelectorStart) - 1;
+
+		/* It is assumed that there are some nils in this dictionary, and search will 
+	 stop when one is encountered. However, if there are no nils, then wrapAround 
+	 will be detected the second time the loop gets to the end of the table. */
+
+		index = SelectorStart + (mask & (((mnuSelector & 1)
+	? (mnuSelector >> 1)
+	: (((usqInt) (longAt(mnuSelector))) >> HashBitsOffset) & HashMaskUnshifted)));
+		wrapAround = 0;
+		while (1) {
+			nextSelector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+			if (nextSelector == GIV(nilObj)) {
+				mnuMethod = null;
+				goto l1;
+			}
+			if (nextSelector == mnuSelector) {
+				methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+				mnuMethod = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
+				goto l1;
+			}
+			index += 1;
+			if (index == length) {
+				if (wrapAround) {
+					mnuMethod = null;
+					goto l1;
+				}
+				wrapAround = 1;
+				index = SelectorStart;
+			}
+		}
+		mnuMethod = null;
+	l1:	/* end lookupMethodFor:InDictionary: */;
+		if (mnuMethod != null) {
+			methodHeader = longAt((mnuMethod + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+			if ((!(isCogMethodReference(methodHeader)))
+			 && (((((usqInt) methodHeader) >> 10) & 255) <= maxLiteralCountForCompile)) {
+				cogselector(mnuMethod, mnuSelector);
+			}
+			return mnuMethod;
+		}
+		currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex << ShiftForWord));
+	}
+	return null;
+}
+
+
 /*	The module with the given name was just unloaded. 
 	Make sure we have no dangling references. */
 
@@ -25011,7 +25162,7 @@
 		if (((((usqInt) objHeader) >> 12) & 31) == ClassMethodContextCompactIndex) {
 			/* begin cloneContext: */
 			VM_LABEL(0cloneContext);
-			cloned = clone(receiver);
+			cloned = eeInstantiateMethodContextByteSize(byteSizeOf(receiver));
 			if (cloned != 0) {
 				for (i = 0; i <= StackPointerIndex; i += 1) {
 					/* begin storePointerUnchecked:ofObject:withValue: */
@@ -29321,6 +29472,10 @@
 
 
 /*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
 	cache that
 	refer to this method, presumably because it has been redefined, overridden
 	or removed.
@@ -29344,22 +29499,17 @@
 		}
 		probe += MethodCacheEntrySize;
 	}
-	if (((oldMethod & 1) == 0)
-	 && (((((usqInt) (longAt(oldMethod))) >> 8) & 15) >= 12)) {
-		/* begin primitiveIndexOf: */
-		primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
-		primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
-		if (primIdx == PrimitiveExternalCallIndex) {
-			flushExternalPrimitiveOf(oldMethod);
-		}
-		if (methodHasCogMethod(oldMethod)) {
-			unlinkSendsTo(cogMethodOf(oldMethod));
-		}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
 	}
 	/* begin flushAtCache */
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
+	unlinkSendsTo(longAt(GIV(stackPointer)));
 }
 
 
@@ -29390,7 +29540,7 @@
 			GIV(atCache)[i1] = 0;
 		}
 	}
-	unlinkSendsOf(selector);
+	unlinkSendsOfisMNUSelector(selector, selector == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord))));
 }
 
 
@@ -38050,6 +38200,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38077,6 +38229,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38754,7 +38908,49 @@
 	printf("\n");
 }
 
+void
+printMethodDictionaryOf(sqInt behavior)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
 
+	/* begin printMethodDictionary: */
+	VM_LABEL(0printMethodDictionary);
+	methodArray = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)))) - 1); index += 1) {
+		selector = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+void
+printMethodDictionary(sqInt dictionary)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
+
+	methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(dictionary)) - 1); index += 1) {
+		selector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+
 /*	Scan the heap printing the oops of any and all objects that refer to anOop */
 
 void
@@ -38933,8 +39129,6 @@
 
 	/* begin printOopShortInner: */
 	VM_LABEL(0printOopShortInner);
-	/* begin printChar: */
-	putchar('=');
 	if ((oop & 1)) {
 		printNum((oop >> 1));
 		/* begin printChar: */
@@ -39003,10 +39197,10 @@
 	if (nameLen == 10) {
 		if (!(strncmp(name, "ByteString", 10))) {
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			printStringOf(oop);
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			goto l2;
 		}
 		if (!(strncmp(name, "ByteSymbol", 10))) {

Modified: branches/Cog/nscogsrc/vm/interp.h
===================================================================
--- branches/Cog/nscogsrc/vm/interp.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/interp.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nscogsrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nscogsrc/vm/vmCallback.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/nscogsrc/vm/vmCallback.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 #define VM_CALLBACK_INC 1


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Mon Aug  8 12:00:18 PDT 2011
   + Tue Aug 16 15:27:50 PDT 2011

Modified: branches/Cog/scripts/mkvmarchives
===================================================================
--- branches/Cog/scripts/mkvmarchives	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/scripts/mkvmarchives	2011-08-16 22:28:12 UTC (rev 2487)
@@ -61,7 +61,7 @@
 	test -d Cog.app || mkdir Cog.app
 	rm -rf Cog.app/* Cog.app.tgz
 	(cd macbuild/Fast.app>/dev/null;tar cf - *)|(cd Cog.app;tar xvf -)
-	ex "+g/[ >][0-9][0-9]*\.[0-9][0-9]*\.0/s/0\([< ]\)/$REV\1/" +w +q Cog.app/Contents/Info.plist
+	ex "+g/<.--version-->/s/0\([< ]\)/$REV\1/" +w +q Cog.app/Contents/Info.plist
 	tar czf Cog.app.tgz Cog.app
 	EXES="$EXES	Cog.app/Contents/MacOS/Croquet"
 fi
@@ -69,7 +69,7 @@
 	test -d CogMT.app || mkdir CogMT.app
 	rm -rf CogMT.app/* CogMT.app.tgz
 	(cd macbuild/FastMT.app>/dev/null;tar cf - *)|(cd CogMT.app;tar xvf -)
-	ex "+g/[ >][0-9][0-9]*\.[0-9][0-9]*\.0/s/0\([< ]\)/$REV\1/" +w +q CogMT.app/Contents/Info.plist
+	ex "+g/<.--version-->/s/0\([< ]\)/$REV\1/" +w +q CogMT.app/Contents/Info.plist
 	tar czf CogMT.app.tgz CogMT.app
 	EXES="$EXES	CogMT.app/Contents/MacOS/Croquet"
 fi
@@ -110,7 +110,7 @@
 	test -d Newspeak\ Virtual\ Machine.app || mkdir Newspeak\ Virtual\ Machine.app
 	rm -rf Newspeak\ Virtual\ Machine.app/* Newspeak\ Virtual\ Machine.app.tgz
 	(cd $NSB/macbuild/Fast.app>/dev/null;tar cf - *)|(cd Newspeak\ Virtual\ Machine.app;tar xvf -)
-	ex "+g/[ >][0-9][0-9]*\.[0-9][0-9]*\.0/s/0\([< ]\)/$REV\1/" +w +q Newspeak\ Virtual\ Machine.app/Contents/Info.plist
+	ex "+g/<.--version-->/s/0\([< ]\)/$REV\1/" +w +q Newspeak\ Virtual\ Machine.app/Contents/Info.plist
 	tar czf Newspeak\ Virtual\ Machine.app.tgz Newspeak\ Virtual\ Machine.app
 	EXES="$EXES	Newspeak Virtual Machine.app/Contents/MacOS/Newspeak Virtual Machine"
 fi

Modified: branches/Cog/src/examplePlugins.ext
===================================================================
--- branches/Cog/src/examplePlugins.ext	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/examplePlugins.ext	2011-08-16 22:28:12 UTC (rev 2487)
@@ -34,7 +34,6 @@
 Mpeg3Plugin \
 QuicktimePlugin \
 RePlugin \
-SqueakFFIPrims \
 SecurityPlugin \
 SerialPlugin \
 SocketPlugin \
@@ -42,6 +41,7 @@
 SoundGenerationPlugin \
 SoundPlugin \
 StarSqueakPlugin \
+SqueakFFIPrims \
 UUIDPlugin \
 UnixOSProcessPlugin \
 VMProfileMacSupportPlugin \

Modified: branches/Cog/src/vm/cogit.c
===================================================================
--- branches/Cog/src/vm/cogit.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cogit.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGenerator VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	StackToRegisterMappingCogit VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -314,6 +314,7 @@
 #define RetN 10
 #define RootBit 0x40000000
 #define RootBitDigitLength 4
+#define SelectorDoesNotUnderstand 20
 #define SenderIndex 0
 #define SendNumArgsReg -6
 #define SFENCE 109
@@ -410,11 +411,12 @@
 char * codeEntryNameFor(char *address);
 sqInt cogCodeBase(void);
 sqInt cogCodeConstituents(void);
-static sqInt cogExtendPICCaseNMethodtag(CogMethod *cPIC, sqInt caseNMethodOrNil, sqInt caseNTag);
+static sqInt cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase);
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
+CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
 static CogMethod * cogOpenPICSelectornumArgs(sqInt selector, sqInt numArgs);
-static CogMethod * cogPICSelectornumArgsCase0MethodCase1Methodtag(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag);
+static CogMethod * cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase);
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
 static void compactCompiledCode(sqInt objectHeaderValue);
@@ -428,13 +430,14 @@
 static sqInt compileClosedPICPrototype(void);
 static CogMethod * compileCogMethod(sqInt selector);
 static AbstractInstruction * compileCPICEntry(void);
-static sqInt compileCPICCase0Case1MethodtagnumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt numArgs);
+static sqInt compileCPICCase0Case1MethodtagisMNUCasenumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs);
 static sqInt compileEntireMethod(void);
 static void compileEntry(void);
 static void compileFrameBuild(void);
 static void compileGetErrorCode(void);
 static sqInt compileInterpreterPrimitive(void (*primitiveRoutine)(void));
 static sqInt compileMethodBody(void);
+static sqInt compileMNUCPICmethodOperandnumArgs(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs);
 static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs);
 static sqInt compilePICProlog(sqInt numArgs);
 static sqInt compilePrimitive(void);
@@ -538,7 +541,7 @@
 static sqInt extendedStoreAndPopBytecode(void);
 static sqInt extendedStoreBytecode(void);
 static void fillInBlockHeadersAt(sqInt startAddress);
-static CogMethod * fillInCPICHeadersizenumArgsnumCasesselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt selector);
+static CogMethod * fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt hasMNUCase, sqInt selector);
 static CogMethod * fillInMethodHeadersizeselector(CogMethod *method, sqInt size, sqInt selector);
 static CogMethod * fillInOPICHeadersizenumArgsselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt selector);
 static usqInt findBlockMethodWithEntrystartBcpc(sqInt blockEntryMcpc, sqInt startBcpc);
@@ -816,7 +819,6 @@
 static sqInt loadLiteralByteSize(AbstractInstruction * self_in_loadLiteralByteSize);
 static sqInt longBranchDistance(unsigned char byteZero, unsigned char byteOne);
 static sqInt longForwardBranchDistance(unsigned char byteZero, unsigned char byteOne);
-static sqInt lookupAndCogfor(sqInt selector, sqInt receiver);
 static AbstractInstruction * gMoveAwR(sqInt address, sqInt reg);
 static AbstractInstruction * gMoveCwR(sqInt wordConstant, sqInt reg);
 static AbstractInstruction * gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg);
@@ -972,9 +974,9 @@
 static sqInt unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity);
 static sqInt unlinkIfLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector);
 static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod);
-void unlinkSendsOf(sqInt selector);
+void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(CogMethod *targetMethod);
+void unlinkSendsTo(sqInt targetMethodObject);
 static sqInt unsignedShortAt(AbstractInstruction * self_in_unsignedShortAt, sqInt byteAddress);
 static void updateLabel(AbstractInstruction * self_in_updateLabel, AbstractInstruction *labelInstruction);
 static sqInt updateMaybeObjRefAt(sqInt mcpc);
@@ -2180,27 +2182,65 @@
 ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver)
 {
     sqInt cacheTag;
+    sqInt errorSelectorOrNil;
+    sqInt errsel;
+    sqInt method;
+    sqInt methodOrSelectorIndex;
     sqInt newTargetMethodOrNil;
     sqInt outerReturn;
     sqInt result;
+    sqInt selector;
 
 	;
 	outerReturn = stackTop();
+	if (((cPIC->cPICNumCases)) < numPICCases) {
+		/* begin lookup:for:methodAndErrorSelectorInto: */
+		VM_LABEL(0lookupformethodAndErrorSelectorInto);
+		selector = (cPIC->selector);
+		methodOrSelectorIndex = lookupreceiver(selector, receiver);
+		if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+			assert(isOopCompiledMethod(methodOrSelectorIndex));
+			if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+			 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+				cogselector(methodOrSelectorIndex, selector);
+			}
+						newTargetMethodOrNil = methodOrSelectorIndex;
+			errorSelectorOrNil = 0;
 
-	/* We assume lookupAndCog:for: will *not* reclaim the method zone */
+			goto l1;
+		}
+		if (methodOrSelectorIndex == SelectorDoesNotUnderstand) {
+			methodOrSelectorIndex = lookupreceiver(splObj(SelectorDoesNotUnderstand), receiver);
+			if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+				assert(isOopCompiledMethod(methodOrSelectorIndex));
+				if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+				 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+					cogselector(methodOrSelectorIndex, selector);
+				}
+								newTargetMethodOrNil = methodOrSelectorIndex;
+				errorSelectorOrNil = SelectorDoesNotUnderstand;
 
-	newTargetMethodOrNil = lookupAndCogfor((cPIC->selector), receiver);
+				goto l1;
+			}
+		}
+				newTargetMethodOrNil = methodOrSelectorIndex;
+		errorSelectorOrNil = null;
+
+	l1:	/* end lookup:for:methodAndErrorSelectorInto: */;
+	}
 	assert(outerReturn == (stackTop()));
 	cacheTag = inlineCacheTagForInstance(receiver);
 	if ((((cPIC->cPICNumCases)) >= numPICCases)
+	 || (((errorSelectorOrNil != null)
+ && (errorSelectorOrNil != SelectorDoesNotUnderstand))
 	 || ((inlineCacheTagIsYoung(cacheTag))
-	 || ((newTargetMethodOrNil != null)
-	 && (isYoung(newTargetMethodOrNil))))) {
+	 || ((newTargetMethodOrNil == null)
+	 || (isYoung(newTargetMethodOrNil)))))) {
 		result = patchToOpenPICFornumArgsreceiver((cPIC->selector), (cPIC->cmNumArgs), receiver);
 		assert(!result);
 		return ceSendFromInLineCacheMiss(cPIC);
 	}
-	cogExtendPICCaseNMethodtag(cPIC, newTargetMethodOrNil, cacheTag);
+	cogExtendPICCaseNMethodtagisMNUCase(cPIC, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand);
 	executeCogMethodFromLinkedSendwithReceiverandCacheTag(cPIC, receiver, inlineCacheTagAt(backEnd, outerReturn));
 	return null;
 }
@@ -2224,12 +2264,17 @@
 {
     sqInt cacheTag;
     sqInt entryPoint;
+    sqInt errorSelectorOrNil;
+    sqInt errsel;
     sqInt extent;
     sqInt innerReturn;
+    sqInt method;
+    sqInt methodOrSelectorIndex;
     sqInt newTargetMethodOrNil;
     sqInt outerReturn;
     CogMethod *pic;
     sqInt result;
+    sqInt selector;
     CogMethod *targetMethod;
 
 
@@ -2252,15 +2297,46 @@
 #  endif /* NewspeakVM */
 
 	assert(((((sqInt)targetMethod)) + cmEntryOffset) == entryPoint);
+	/* begin lookup:for:methodAndErrorSelectorInto: */
+	VM_LABEL(1lookupformethodAndErrorSelectorInto);
+	selector = (targetMethod->selector);
+	methodOrSelectorIndex = lookupreceiver(selector, receiver);
+	if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+		assert(isOopCompiledMethod(methodOrSelectorIndex));
+		if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+		 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+			cogselector(methodOrSelectorIndex, selector);
+		}
+				newTargetMethodOrNil = methodOrSelectorIndex;
+		errorSelectorOrNil = 0;
 
-	/* We assume lookupAndCog:for: will *not* reclaim the method zone */
+		goto l1;
+	}
+	if (methodOrSelectorIndex == SelectorDoesNotUnderstand) {
+		methodOrSelectorIndex = lookupreceiver(splObj(SelectorDoesNotUnderstand), receiver);
+		if ((((usqInt)methodOrSelectorIndex)) > (startOfMemory())) {
+			assert(isOopCompiledMethod(methodOrSelectorIndex));
+			if ((!(methodHasCogMethod(methodOrSelectorIndex)))
+			 && (methodShouldBeCogged(methodOrSelectorIndex))) {
+				cogselector(methodOrSelectorIndex, selector);
+			}
+						newTargetMethodOrNil = methodOrSelectorIndex;
+			errorSelectorOrNil = SelectorDoesNotUnderstand;
 
-	newTargetMethodOrNil = lookupAndCogfor((targetMethod->selector), receiver);
+			goto l1;
+		}
+	}
+		newTargetMethodOrNil = methodOrSelectorIndex;
+	errorSelectorOrNil = null;
+
+l1:	/* end lookup:for:methodAndErrorSelectorInto: */;
 	assert(outerReturn == (stackTop()));
 	cacheTag = inlineCacheTagForInstance(receiver);
-	if ((inlineCacheTagIsYoung(cacheTag))
-	 || ((newTargetMethodOrNil != null)
-	 && (isYoung(newTargetMethodOrNil)))) {
+	if (((errorSelectorOrNil != null)
+ && (errorSelectorOrNil != SelectorDoesNotUnderstand))
+	 || ((inlineCacheTagIsYoung(cacheTag))
+	 || ((newTargetMethodOrNil == null)
+	 || (isYoung(newTargetMethodOrNil))))) {
 		result = patchToOpenPICFornumArgsreceiver((targetMethod->selector), (targetMethod->cmNumArgs), receiver);
 		assert(!result);
 		return ceSendFromInLineCacheMiss(targetMethod);
@@ -2270,8 +2346,9 @@
 
 		/* otherwise attempt to create a closed PIC for the two cases. */
 
-		pic = cogPICSelectornumArgsCase0MethodCase1Methodtag((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag);
-		if ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1))) {
+		pic = cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase((targetMethod->selector), (targetMethod->cmNumArgs), targetMethod, newTargetMethodOrNil, cacheTag, errorSelectorOrNil == SelectorDoesNotUnderstand);
+		if ((errorSelectorOrNil != null)
+		 || ((((((sqInt)pic)) >= MaxNegativeErrorCode) && ((((sqInt)pic)) <= -1)))) {
 			if ((((sqInt)pic)) == InsufficientCodeSpace) {
 				callForCogCompiledCodeCompaction();
 			}
@@ -2756,11 +2833,17 @@
 }
 
 
+/*	Extend the cPIC with the supplied case. If caseNMethod is cogged dispatch
+	direct to
+	its unchecked entry-point. If caseNMethod is not cogged, jump to the fast
+	interpreter dispatch, and if isMNUCase then dispatch to fast MNU
+	invocation and mark the cPIC as
+	having the MNU case for cache flushing. */
 /*	stack allocate the various collections so that they
 	are effectively garbage collected on return. */
 
 static sqInt
-cogExtendPICCaseNMethodtag(CogMethod *cPIC, sqInt caseNMethodOrNil, sqInt caseNTag)
+cogExtendPICCaseNMethodtagisMNUCase(CogMethod *cPIC, sqInt caseNMethod, sqInt caseNTag, sqInt isMNUCase)
 {
     sqInt address;
     sqInt end;
@@ -2772,16 +2855,19 @@
 	compilationBreakpoint((cPIC->selector), lengthOf((cPIC->selector)));
 	allocateOpcodesbytecodes(5, 0);
 	assert(!(inlineCacheTagIsYoung(caseNTag)));
-	if ((caseNMethodOrNil != null)
-	 && (methodHasCogMethod(caseNMethodOrNil))) {
+	assert((caseNMethod != null)
+	 && (!(isYoung(caseNMethod))));
+	if ((!isMNUCase)
+	 && (methodHasCogMethod(caseNMethod))) {
 		operand = 0;
-		target = (((sqInt)(cogMethodOf(caseNMethodOrNil)))) + cmNoCheckEntryOffset;
+		target = (((sqInt)(cogMethodOf(caseNMethod)))) + cmNoCheckEntryOffset;
 	}
 	else {
-		assert((caseNMethodOrNil == null)
-		 || (!(isYoung(caseNMethodOrNil))));
-		operand = caseNMethodOrNil;
-		target = (((sqInt)cPIC)) + ((caseNMethodOrNil == null
+		if (isMNUCase) {
+			(cPIC->cpicHasMNUCase = 1);
+		}
+		operand = caseNMethod;
+		target = (((sqInt)cPIC)) + ((isMNUCase
 	? sizeof(CogMethod)
 	: (interpretOffset()) - (callInstructionByteSize(backEnd))));
 	}
@@ -2794,8 +2880,8 @@
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, ((sqInt)cPIC), ClassReg);
 	/* begin JumpLong: */
-	jumpTarget = ((void *) (cPICMissTrampolineFor((cPIC->cmNumArgs))));
-	genoperand(JumpLong, ((sqInt)jumpTarget));
+	jumpTarget = cPICMissTrampolineFor((cPIC->cmNumArgs));
+	genoperand(JumpLong, jumpTarget);
 	computeMaximumSizes();
 	address = addressOfEndOfCaseinCPIC(((cPIC->cPICNumCases)) - 1, cPIC);
 	size = generateInstructionsAt(address);
@@ -2884,6 +2970,44 @@
 }
 
 
+/*	Attempt to create a one-case PIC for an MNU.
+	The tag for the case is at the send site and so doesn't need to be
+	generated. 
+ */
+
+CogMethod *
+cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs)
+{
+    sqInt end;
+    sqInt headerSize;
+    sqInt size;
+    sqInt startAddress;
+
+	compilationBreakpoint(selector, lengthOf(selector));
+	if (endCPICCase0 == null) {
+		return NotFullyInitialized;
+	}
+	startAddress = allocate(closedPICSize);
+	if (startAddress == 0) {
+		return ((CogMethod *) InsufficientCodeSpace);
+	}
+	(methodLabel->address = startAddress);
+	(methodLabel->dependent = null);
+	allocateOpcodesbytecodes(numPICCases * 7, 0);
+	compileMNUCPICmethodOperandnumArgs(((CogMethod *) startAddress), methodOperand, numArgs);
+	computeMaximumSizes();
+	headerSize = sizeof(CogMethod);
+	size = generateInstructionsAt(startAddress + headerSize);
+
+	/* The missOffset is th same as the interpretOffset. */
+
+	end = outputInstructionsAt(startAddress + headerSize);
+	assert(missOffset == ((((interpretCall->address)) + ((interpretCall->machineCodeSize))) - startAddress));
+	assert((startAddress + cmEntryOffset) == ((entry->address)));
+	return fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(((CogMethod *) startAddress), closedPICSize, numArgs, 1, 1, selector);
+}
+
+
 /*	Create an Open PIC. Temporarily create a direct call of
 	ceSendFromOpenPIC:. Should become a probe of the first-level method lookup
 	cache followed by a
@@ -2920,15 +3044,15 @@
 
 
 /*	Attempt to create a two-case PIC for case0CogMethod and
-	case1MethodOrNil,case1Tag. The tag for case0CogMethod is at the send site
-	and so doesn't need to be generated.
-	case1MethodOrNil may be any of
+	case1Method,case1Tag. The tag for case0CogMethod is at the send site and
+	so doesn't need to be generated.
+	case1Method may be any of
 	- a Cog method; link to its unchecked entry-point
 	- a CompiledMethod; link to ceInterpretMethodFromPIC:
-	- nil; link to ceMNUFromPICMNUMethod:receiver: */
+	- a CompiledMethod; link to ceMNUFromPICMNUMethod:receiver: */
 
 static CogMethod *
-cogPICSelectornumArgsCase0MethodCase1Methodtag(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag)
+cogPICSelectornumArgsCase0MethodCase1MethodtagisMNUCase(sqInt selector, sqInt numArgs, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt isMNUCase)
 {
     sqInt end;
     sqInt headerSize;
@@ -2943,7 +3067,7 @@
 	(methodLabel->address = startAddress);
 	(methodLabel->dependent = null);
 	allocateOpcodesbytecodes(numPICCases * 7, 0);
-	compileCPICCase0Case1MethodtagnumArgs(((CogMethod *) startAddress), case0CogMethod, case1MethodOrNil, case1Tag, numArgs);
+	compileCPICCase0Case1MethodtagisMNUCasenumArgs(((CogMethod *) startAddress), case0CogMethod, case1MethodOrNil, case1Tag, isMNUCase, numArgs);
 	computeMaximumSizes();
 	headerSize = sizeof(CogMethod);
 	size = generateInstructionsAt(startAddress + headerSize);
@@ -2955,7 +3079,7 @@
 	assert((startAddress + cmEntryOffset) == ((entry->address)));
 	assert(((endCPICCase0->address)) == (startAddress + firstCPICCaseOffset));
 	assert(((endCPICCase1->address)) == ((startAddress + firstCPICCaseOffset) + cPICCaseSize));
-	return fillInCPICHeadersizenumArgsnumCasesselector(((CogMethod *) startAddress), closedPICSize, numArgs, 2, selector);
+	return fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(((CogMethod *) startAddress), closedPICSize, numArgs, 2, isMNUCase, selector);
 }
 
 
@@ -3435,15 +3559,15 @@
 	compilePICProlog(numArgs);
 	jumpNext = compileCPICEntry();
 	/* begin MoveCw:R: */
-	genoperandoperand(MoveCwR, 99282957, ClassReg);
+	genoperandoperand(MoveCwR, 99282957, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, ((sqInt)(((void *) 1592642142))));
+	genoperand(JumpLong, 1592642142);
 	jmpTarget(jumpNext, (endCPICCase0 = gLabel()));
 	for (h = 1; h <= (numPICCases - 1); h += 1) {
 		/* begin CmpCw:R: */
 		genoperandoperand(CmpCwR, 3133021973UL + h, TempReg);
 		/* begin MoveCw:R: */
-		genoperandoperand(MoveCwR, 195929424 + h, ClassReg);
+		genoperandoperand(MoveCwR, 195929424 + h, SendNumArgsReg);
 		/* begin JumpLongZero: */
 		genoperand(JumpLongZero, ((sqInt)(((void *) (3202131424UL + h)))));
 		if (h == 1) {
@@ -3455,7 +3579,7 @@
 	genoperandoperand(MoveCwR, 179686997, ClassReg);
 	/* begin JumpLong: */
 	jumpTarget = ((void *) (cPICMissTrampolineFor(numArgs)));
-	genoperand(JumpLong, ((sqInt)jumpTarget));
+	genoperand(JumpLong, jumpTarget);
 	return 0;
 }
 
@@ -3521,33 +3645,35 @@
 
 
 /*	Compile the code for a two-case PIC for case0CogMethod and
-	case1MethodOrNil,case1Tag. The tag for case0CogMethod is at the send site
-	and so doesn't need to be generated.
-	case1MethodOrNil may be any of
+	case1Method,case1Tag. The tag for case0CogMethod is at the send site and
+	so doesn't need to be generated.
+	case1Method may be any of
 	- a Cog method; jump to its unchecked entry-point
 	- a CompiledMethod; jump to the ceInterpretFromPIC trampoline
 	- nil; call ceMNUFromPIC */
 
 static sqInt
-compileCPICCase0Case1MethodtagnumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1MethodOrNil, sqInt case1Tag, sqInt numArgs)
+compileCPICCase0Case1MethodtagisMNUCasenumArgs(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs)
 {
     AbstractInstruction *jumpNext;
     void *jumpTarget;
+    sqInt jumpTarget1;
     sqInt operand;
     void *targetEntry;
 
-	compilePICProlog((case0CogMethod->cmNumArgs));
+	assert(case1Method != null);
+	compilePICProlog(numArgs);
 	assert(!(inlineCacheTagIsYoung(case1Tag)));
-	if ((case1MethodOrNil != null)
-	 && (methodHasCogMethod(case1MethodOrNil))) {
+	if ((!isMNUCase)
+	 && (methodHasCogMethod(case1Method))) {
 		operand = 0;
-		targetEntry = ((void *) ((((sqInt)(cogMethodOf(case1MethodOrNil)))) + cmNoCheckEntryOffset));
+		targetEntry = ((void *) ((((sqInt)(cogMethodOf(case1Method)))) + cmNoCheckEntryOffset));
 	}
 	else {
-		assert((case1MethodOrNil == null)
-		 || (!(isYoung(case1MethodOrNil))));
-		operand = case1MethodOrNil;
-		targetEntry = (case1MethodOrNil == null
+		assert((case1Method == null)
+		 || (!(isYoung(case1Method))));
+		operand = case1Method;
+		targetEntry = (case1Method == null
 			? mnuCall
 			: interpretCall);
 	}
@@ -3555,19 +3681,22 @@
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, 0, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, ((sqInt)(((void *) ((((sqInt)case0CogMethod)) + cmNoCheckEntryOffset)))));
+	genoperand(JumpLong, (((sqInt)case0CogMethod)) + cmNoCheckEntryOffset);
 	/* begin CmpCw:R: */
 	endCPICCase0 = genoperandoperand(CmpCwR, case1Tag, TempReg);
 	jmpTarget(jumpNext, endCPICCase0);
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, operand, SendNumArgsReg);
 	/* begin JumpLongZero: */
-	genoperand(JumpLongZero, ((sqInt)targetEntry));
+	jumpTarget = (isMNUCase
+		? mnuCall
+		: targetEntry);
+	genoperand(JumpLongZero, ((sqInt)jumpTarget));
 	/* begin MoveCw:R: */
 	endCPICCase1 = genoperandoperand(MoveCwR, ((sqInt)cPIC), ClassReg);
 	/* begin JumpLong: */
-	jumpTarget = ((void *) (cPICMissTrampolineFor(numArgs)));
-	genoperand(JumpLong, ((sqInt)jumpTarget));
+	jumpTarget1 = ((void *) (cPICMissTrampolineFor(numArgs)));
+	genoperand(JumpLong, jumpTarget1);
 	return 0;
 }
 
@@ -3955,6 +4084,31 @@
 }
 
 
+/*	Compile the code for a one-case MNU PIC that calls ceMNUFromPIC for
+	case0Tag The tag for case0 is at the send site and so doesn't need to be
+	generated. 
+ */
+
+static sqInt
+compileMNUCPICmethodOperandnumArgs(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs)
+{
+    AbstractInstruction *jumpNext;
+    sqInt jumpTarget;
+
+	compilePICProlog(numArgs);
+	jumpNext = compileCPICEntry();
+	/* begin MoveCw:R: */
+	genoperandoperand(MoveCwR, methodOperand, SendNumArgsReg);
+	/* begin JumpLong: */
+	genoperand(JumpLong, ((sqInt)mnuCall));
+	jmpTarget(jumpNext, gMoveCwR(((sqInt)cPIC), ClassReg));
+	/* begin JumpLong: */
+	jumpTarget = cPICMissTrampolineFor(numArgs);
+	genoperand(JumpLong, jumpTarget);
+	return 0;
+}
+
+
 /*	Compile the code for an open PIC. Perform a probe of the first-level
 	method lookup cache followed by a call of ceSendFromOpenPIC: if the probe
 	fails. Override to push the register args when calling ceSendFromOpenPIC: */
@@ -7102,7 +7256,7 @@
 }
 
 static CogMethod *
-fillInCPICHeadersizenumArgsnumCasesselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt selector)
+fillInCPICHeadersizenumArgsnumCaseshasMNUCaseselector(CogMethod *pic, sqInt size, sqInt numArgs, sqInt numCases, sqInt hasMNUCase, sqInt selector)
 {
 	assert(!(isYoung(selector)));
 	(pic->cmType = CMClosedPIC);
@@ -7114,7 +7268,7 @@
 	(pic->cmNumArgs = numArgs);
 	(pic->cmRefersToYoung = 0);
 	(pic->cmUsageCount = initialClosedPICUsageCount());
-	(pic->cmIsUnlinked = 0);
+	(pic->cpicHasMNUCase = hasMNUCase);
 	(pic->cPICNumCases = numCases);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMClosedPIC);
@@ -7156,7 +7310,7 @@
 		addToYoungReferrers(method);
 	}
 	(method->cmUsageCount = initialMethodUsageCount());
-	(method->cmIsUnlinked = 0);
+	(method->cpicHasMNUCase = 0);
 	(method->blockEntryOffset = (blockEntryLabel != null
 		? ((blockEntryLabel->address)) - (((sqInt)method))
 		: 0));
@@ -7182,7 +7336,7 @@
 		addToYoungReferrers(pic);
 	}
 	(pic->cmUsageCount = initialOpenPICUsageCount());
-	(pic->cmIsUnlinked = 0);
+	(pic->cpicHasMNUCase = 0);
 	(pic->cPICNumCases = 0);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMOpenPIC);
@@ -12714,7 +12868,7 @@
 
 	/* begin annotateCall: */
 	/* begin JumpLong: */
-	abstractInstruction = genoperand(JumpLong, ((sqInt)(((void *) callTarget))));
+	abstractInstruction = genoperand(JumpLong, callTarget);
 	return annotatewith(abstractInstruction, IsRelativeCall);
 }
 
@@ -12961,28 +13115,6 @@
 	return ((byteZero & 3) * 256) + byteOne;
 }
 
-
-/*	Lookup selector in the class of receiver. If not found answer nil.
-	If not a method (objectAsMethod) answer nil. Otherwise try to
-	compile it to machine code if appropriate. Answer the method. */
-
-static sqInt
-lookupAndCogfor(sqInt selector, sqInt receiver)
-{
-    sqInt newTargetMethodOrNil;
-
-	newTargetMethodOrNil = lookupreceiver(selector, receiver);
-	if (!((newTargetMethodOrNil != null)
-		 && (isOopCompiledMethod(newTargetMethodOrNil)))) {
-		return null;
-	}
-	if ((!(methodHasCogMethod(newTargetMethodOrNil)))
-	 && (methodShouldBeCogged(newTargetMethodOrNil))) {
-		cogselector(newTargetMethodOrNil, selector);
-	}
-	return newTargetMethodOrNil;
-}
-
 static AbstractInstruction *
 gMoveAwR(sqInt address, sqInt reg)
 {
@@ -16389,7 +16521,7 @@
 /*	Unlink all sends in cog methods. */
 
 void
-unlinkSendsOf(sqInt selector)
+unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector)
 {
     CogMethod *cogMethod;
 
@@ -16416,7 +16548,9 @@
 		}
 		else {
 			if ((((cogMethod->cmType)) != CMFree)
-			 && (((cogMethod->selector)) == selector)) {
+			 && ((isMNUSelector
+ && ((cogMethod->cpicHasMNUCase)))
+			 || (((cogMethod->selector)) == selector))) {
 				freeMethod(cogMethod);
 			}
 		}
@@ -16457,14 +16591,23 @@
 }
 
 
-/*	Unlink all sends in cog methods to a particular target method. */
+/*	Unlink all sends in cog methods to a particular target method.
+	If targetMethodObject isn't actually a method (perhaps being
+	used via invokeAsMethod) then flush all sends since anything
+	could be affected. */
 
 void
-unlinkSendsTo(CogMethod *targetMethod)
+unlinkSendsTo(sqInt targetMethodObject)
 {
     CogMethod *cogMethod;
     sqInt freedPIC;
+    CogMethod *targetMethod;
 
+	if (!((isOopCompiledMethod(targetMethodObject))
+		 && (methodHasCogMethod(targetMethodObject)))) {
+		return;
+	}
+	targetMethod = cogMethodOf(targetMethodObject);
 	if (methodZoneBase == null) {
 		return;
 	}

Modified: branches/Cog/src/vm/cogit.h
===================================================================
--- branches/Cog/src/vm/cogit.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cogit.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGenerator VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 
@@ -26,6 +26,7 @@
 sqInt cogCodeConstituents(void);
 void cogitPostGCAction(sqInt gcMode);
 sqInt cogMethodDoesntLookKosher(CogMethod *cogMethod);
+CogMethod * cogMNUPICSelectormethodOperandnumArgs(sqInt selector, sqInt methodOperand, sqInt numArgs);
 CogMethod * cogselector(sqInt aMethodObj, sqInt aSelectorOop);
 void compactCogCompiledCode(void);
 void enterCogCodePopReceiver(void);
@@ -68,9 +69,9 @@
 sqInt stackPageHeadroomBytes(void);
 sqInt traceLinkedSendOffset(void);
 void unlinkAllSends(void);
-void unlinkSendsOf(sqInt selector);
+void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector);
 void unlinkSendsToFree(void);
-void unlinkSendsTo(CogMethod *targetMethod);
+void unlinkSendsTo(sqInt targetMethodObject);
 void voidCogCompiledCode(void);
 
 

Modified: branches/Cog/src/vm/cogmethod.h
===================================================================
--- branches/Cog/src/vm/cogmethod.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cogmethod.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGenerator VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 typedef struct {
@@ -8,7 +8,7 @@
 	unsigned		cmNumArgs : 8;
 	unsigned		cmType : 3;
 	unsigned		cmRefersToYoung : 1;
-	unsigned		cmIsUnlinked : 1;
+	unsigned		cpicHasMNUCase : 1;
 	unsigned		cmUsageCount : 3;
 	unsigned		stackCheckOffset : 16;
  } CogBlockMethod;
@@ -18,7 +18,7 @@
 	unsigned		cmNumArgs : 8;
 	unsigned		cmType : 3;
 	unsigned		cmRefersToYoung : 1;
-	unsigned		cmIsUnlinked : 1;
+	unsigned		cpicHasMNUCase : 1;
 	unsigned		cmUsageCount : 3;
 	unsigned		stackCheckOffset : 16;
 	unsigned short	blockSize;

Modified: branches/Cog/src/vm/cointerp.c
===================================================================
--- branches/Cog/src/vm/cointerp.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cointerp.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -466,6 +466,7 @@
 void dumpTraceLog(void);
 static sqInt eeInstantiateAndInitializeClassindexableSize(sqInt classPointer, sqInt size);
 sqInt eeInstantiateClassindexableSize(sqInt classPointer, sqInt size);
+static sqInt eeInstantiateMethodContextByteSize(sqInt sizeInBytes);
 static sqInt eeInstantiateSmallClasssizeInBytes(sqInt classPointer, sqInt sizeInBytes);
 static sqInt encodedNativePCOfcogMethod(sqInt mcpc, CogBlockMethod *cogMethod);
 static sqInt ensureCallerContext(char *theFP);
@@ -511,7 +512,7 @@
 double floatArg(sqInt index);
 sqInt floatObjectOf(double aFloat);
 double floatValueOf(sqInt oop);
-static void flushExternalPrimitiveOf(sqInt methodObj);
+void flushExternalPrimitiveOf(sqInt methodObj);
 static void flushExternalPrimitives(void);
 void forceInterruptCheck(void);
 void forceInterruptCheckFromHeartbeat(void);
@@ -550,7 +551,7 @@
 static sqInt getShortFromFileswap(sqImageFile aFile, sqInt swapFlag);
 sqInt getStackPointer(void);
 sqInt getThisSessionID(void);
-static sqInt handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean);
+static sqInt handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage);
 static void handleStackOverflow(void);
 static sqInt handleStackOverflowOrEventAllowContextSwitch(sqInt mayContextSwitch);
 sqInt headerOf(sqInt methodPointer);
@@ -676,6 +677,7 @@
 static sqInt mframeIsBlockActivation(char *theFP);
 static sqInt mframeReceiver(char *theFP);
 sqInt mMethodClass(void);
+static sqInt mnuMethodOrNilFor(sqInt rcvr);
 EXPORT(void) moduleUnloaded(char *aModuleName);
 static char * moveFramesInthroughtoPage(StackPage *oldPage, char *theFP, StackPage *newPage);
 static sqInt mustMapMachineCodePCcontext(sqInt theIP, sqInt aOnceMarriedContext);
@@ -975,6 +977,8 @@
 void printInstancesOf(sqInt aClassOop);
 static void printLogEntryAt(sqInt i);
 void printMemory(void);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 static void printNameOfClasscount(sqInt classOop, sqInt cnt);
 static void printNum(sqInt n);
@@ -1876,7 +1880,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.114]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.117]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -10089,13 +10093,45 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     CogMethod *cPIC;
+    sqInt primBits;
+    sqInt primitiveIndex;
+    char *sp;
+    sqInt top;
 
 	assert(((rcvr & 1))
 	 || (addressCouldBeObj(rcvr)));
+	assert((aMethodObj == 0)
+	 || ((addressCouldBeObj(aMethodObj))
+	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
 	assert(((cPIC->cmType)) == CMClosedPIC);
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
+	if (aMethodObj != 0) {
+		/* begin popStack */
+		top = longAt(GIV(stackPointer));
+		GIV(stackPointer) += BytesPerWord;
+		GIV(instructionPointer) = ((sqInt) top);
+		createActualMessageTo(fetchClassOf(rcvr));
+		if (((aMethodObj & 1) == 0)
+		 && ((((((usqInt) (longAt(aMethodObj))) >> 8) & 15) >= 12)
+		 && (isCogMethodReference(longAt((aMethodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+			/* begin push: */
+			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+			GIV(stackPointer) = sp;
+			executeCogMethodFromUnlinkedSendwithReceiver(cogMethodOf(aMethodObj), rcvr);
+			assert(0);
+		}
+		GIV(newMethod) = aMethodObj;
+		/* begin primitiveIndexOf: */
+		primBits = (((usqInt) (headerOf(aMethodObj))) >> 1) & 268435967;
+		primitiveIndex = (primBits & 511) + (((usqInt) primBits) >> 19);
+		/* begin functionPointerFor:inClass: */
+		primitiveFunctionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex
+	? 0
+	: primitiveTable[primitiveIndex])));
+		interpretMethodFromMachineCode(); return;
+	}
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
 		GIV(lkupClass) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
@@ -10110,7 +10146,8 @@
 		goto l1;
 	}
 l1:	/* end fetchClassOf: */;
-	handleMNUInMachineCodeToclassForMessagemayLink(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass), 0);
+	handleMNUInMachineCodeToclassForMessage(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass));
+	assert(0);
 }
 
 sqInt
@@ -10520,7 +10557,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10609,7 +10646,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10739,7 +10776,14 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, canLinkCacheTag);
+			if (canLinkCacheTag
+			 && ((errSelIdx == SelectorDoesNotUnderstand)
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
+				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
+					? entryOffset()
+					: noCheckEntryOffset()), rcvr);
+			}
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -12034,8 +12078,8 @@
 
 	assert((!(isOopCompiledMethod(obj)))
 	 || (!(methodHasCogMethod(obj))));
-	assert((!(isContext(oop)))
-	 || (!(isMarriedOrWidowedContext(oop))));
+	assert((!(isContext(obj)))
+	 || (!(isMarriedOrWidowedContext(obj))));
 	assert(isNonIntegerObject(obj));
 	extraHdrBytes = headerTypeBytes[(longAt(obj)) & TypeMask];
 	/* begin sizeBitsOf: */
@@ -13816,6 +13860,91 @@
 }
 
 
+/*	This version of instantiateClass assumes that the total object 
+	size is under 256 bytes, the limit for objects with only one or 
+	two header words. Note that the size is specified in bytes 
+	and should include four bytes for the base header word.
+	Will *not* cause a GC. */
+
+static sqInt
+eeInstantiateMethodContextByteSize(sqInt sizeInBytes)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt hash;
+    sqInt header1;
+    usqInt newChunk;
+    usqInt newFreeStart;
+    sqInt newObj;
+
+	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
+	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
+	assert(sizeInBytes <= SizeMask);
+	assert((header1 & CompactClassMask) > 0);
+	header1 += sizeInBytes - (header1 & SizeMask);
+	flag("Dan");
+	/* begin eeAllocate:headerSize:h1:h2:h3: */
+	/* begin allocateInterpreterChunk: */
+	newChunk = GIV(freeStart);
+	newFreeStart = GIV(freeStart) + (sizeInBytes + ((1 - 1) * BytesPerWord));
+	if (newFreeStart < GIV(scavengeThreshold)) {
+		if ((AllocationCheckFiller != 0)
+		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
+	? newChunk
+	: AllocationCheckFiller)))) {
+			error("last object overwritten");
+		}
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	if (GIV(freeStart) < GIV(scavengeThreshold)) {
+		/* begin scheduleIncrementalGC */
+		GIV(needGCFlag) = 1;
+		forceInterruptCheck();
+	}
+	if (newFreeStart < GIV(reserveStart)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	/* begin scheduleIncrementalGC */
+	GIV(needGCFlag) = 1;
+	forceInterruptCheck();
+	if (GIV(freeStart) <= GIV(endOfMemory)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	error("out of memory");
+	newObj = null;
+l1:	/* end allocateInterpreterChunk: */;
+	if (newObj == 0) {
+		return newObj;
+	}
+	if (1 == 3) {
+		longAtput(newObj, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
+		newObj += BytesPerWord * 2;
+	}
+	if (1 == 2) {
+		longAtput(newObj, null | HeaderTypeClass);
+		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
+		newObj += BytesPerWord;
+	}
+	if (1 == 1) {
+		longAtput(newObj, header1 | HeaderTypeShort);
+	}
+	if (DoExpensiveAssertionChecks) {
+		okayOop(newObj);
+		oopHasOkayClass(newObj);
+		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
+			error("allocate bug: did not set header of new oop correctly");
+		}
+	}
+	return newObj;
+}
+
+
 /*	This version of instantiateClass assumes that the total object
 	size is under 256 bytes, the limit for objects with only one or
 	two header words. Note that the size is specified in bytes
@@ -15645,6 +15774,10 @@
 			 && (((lengthOf(obj)) == cssz)
 			 && ((strncmp(aCString, pointerForOop(obj + BaseHeaderSize), cssz)) == 0))) {
 				printHex(obj);
+				/* begin space */
+				/* begin printChar: */
+				putchar(' ');
+				printOopShort(obj);
 				/* begin cr */
 				printf("\n");
 			}
@@ -15837,11 +15970,14 @@
 }
 
 
+/*	methodObj is a CompiledMethod containing an external primitive. Flush the
+	function address and session ID of the CM
+ */
 /*	methodObj is a CompiledMethod containing an external primitive.
 	Flush the function address and session ID of the CM. Override
 	to also flush the machine code call if one exists. */
 
-static void
+void
 flushExternalPrimitiveOf(sqInt methodObj)
 {
     sqInt lit;
@@ -16607,14 +16743,11 @@
 }
 
 
-/*	A message send from either an open PIC or an unlinked send has not
-	been understood. Load newMethod with the MNU method. If linking
-	is allowed and the target MNU method is in the cache then create a
-	closed PIC with an mnu-entry and link the send to it. messageSelector,
-	argumentCount and lkupClass have already been set by the caller. */
+/*	A message send from either an open PIC or an unlinked send has
+	not been understood. Execute the relevant resulting MNU method. */
 
 static sqInt
-handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean)
+handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt class;
     sqInt classForThisMessage;
@@ -16678,24 +16811,18 @@
 		errSelIdx = SelectorDoesNotUnderstand;
 	l1:	/* end lookupMethodNoMNUEtcInClass: */;
 		if (errSelIdx != 0) {
-			if (errSelIdx == SelectorDoesNotUnderstand) {
+			if (selectorIndex == SelectorDoesNotUnderstand) {
 				error("Recursive not understood error encountered");
 			}
 			/* begin push: */
 			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 			GIV(stackPointer) = sp;
-			return handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, classForThisMessage, 0);
+			return handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForThisMessage);
 		}
 	}
 	if (((GIV(newMethod) & 1) == 0)
 	 && ((((((usqInt) (longAt(GIV(newMethod)))) >> 8) & 15) >= 12)
 	 && (isCogMethodReference(longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
-		if (mayLinkBoolean) {
-			flag("implement creating an MNU PIC sometime");
-			if (0) {
-				error("shouldBeImplemented");
-			}
-		}
 		/* begin push: */
 		longAtput((sp1 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp1;
@@ -19725,6 +19852,7 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     sqInt class;
+    sqInt erridx;
 
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
@@ -19742,8 +19870,8 @@
 l1:	/* end fetchClassOf: */;
 	if (!(lookupInMethodCacheSelclass(selector, class))) {
 		GIV(messageSelector) = selector;
-		if ((lookupMethodNoMNUEtcInClass(class)) != 0) {
-			return null;
+		if (((erridx = lookupMethodNoMNUEtcInClass(class))) != 0) {
+			return erridx;
 		}
 	}
 	return GIV(newMethod);
@@ -21200,13 +21328,8 @@
     CogMethod *cogMethod;
     sqInt frameNumArgs;
     sqInt frameNumArgs1;
-    sqInt hash;
-    sqInt header1;
-    usqInt i;
+    sqInt i;
     sqInt methodFieldOrObj;
-    usqInt newChunk;
-    usqInt newFreeStart;
-    sqInt newObj;
     sqInt numArgs;
     sqInt numStack;
     sqInt rcvr;
@@ -21249,77 +21372,7 @@
 		rcvr = longAt(theFP + FoxIFReceiver);
 		numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs;
 	}
-	/* begin eeInstantiateMethodContextByteSize: */
-	VM_LABEL(0eeInstantiateMethodContextByteSize);
-	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
-	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
-	assert(byteSize <= SizeMask);
-	assert((header1 & CompactClassMask) > 0);
-	header1 += byteSize - (header1 & SizeMask);
-	flag("Dan");
-	/* begin eeAllocate:headerSize:h1:h2:h3: */
-	/* begin allocateInterpreterChunk: */
-	newChunk = GIV(freeStart);
-	newFreeStart = GIV(freeStart) + (byteSize + ((1 - 1) * BytesPerWord));
-	if (newFreeStart < GIV(scavengeThreshold)) {
-		if ((AllocationCheckFiller != 0)
-		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
-	? newChunk
-	: AllocationCheckFiller)))) {
-			error("last object overwritten");
-		}
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	if (GIV(freeStart) < GIV(scavengeThreshold)) {
-		/* begin scheduleIncrementalGC */
-		GIV(needGCFlag) = 1;
-		forceInterruptCheck();
-	}
-	if (newFreeStart < GIV(reserveStart)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	/* begin scheduleIncrementalGC */
-	GIV(needGCFlag) = 1;
-	forceInterruptCheck();
-	if (GIV(freeStart) <= GIV(endOfMemory)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	error("out of memory");
-	newObj = null;
-l1:	/* end allocateInterpreterChunk: */;
-	if (newObj == 0) {
-		theContext = newObj;
-		goto l2;
-	}
-	if (1 == 3) {
-		longAtput(newObj, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
-		newObj += BytesPerWord * 2;
-	}
-	if (1 == 2) {
-		longAtput(newObj, null | HeaderTypeClass);
-		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
-		newObj += BytesPerWord;
-	}
-	if (1 == 1) {
-		longAtput(newObj, header1 | HeaderTypeShort);
-	}
-	if (DoExpensiveAssertionChecks) {
-		okayOop(newObj);
-		oopHasOkayClass(newObj);
-		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
-			error("allocate bug: did not set header of new oop correctly");
-		}
-	}
-	theContext = newObj;
-l2:	/* end eeInstantiateMethodContextByteSize: */;
+	theContext = eeInstantiateMethodContextByteSize(byteSize);
 	longAtput(theFP + FoxThisContext, theContext);
 	/* begin storePointerUnchecked:ofObject:withValue: */
 	/* begin withSmallIntegerTags: */
@@ -21596,6 +21649,104 @@
 }
 
 
+/*	Lookup the doesNotUnderstand: selector in the class of the argument rcvr.
+	Answer either the matching method (cogged if appropriate), or nil, if not
+	found. 
+ */
+
+static sqInt
+mnuMethodOrNilFor(sqInt rcvr)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt currentClass;
+    sqInt dictionary;
+    sqInt header;
+    sqInt index;
+    sqInt length;
+    sqInt mask;
+    sqInt methodArray;
+    sqInt methodHeader;
+    sqInt mnuMethod;
+    sqInt mnuSelector;
+    sqInt nextSelector;
+    sqInt sz;
+    sqInt wrapAround;
+
+	/* begin fetchClassOf: */
+	if ((rcvr & 1)) {
+		currentClass = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
+		goto l2;
+	}
+	if (((ccIndex = (((usqInt) (longAt(rcvr))) >> 12) & 31)) == 0) {
+		currentClass = (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask;
+		goto l2;
+	}
+	else {
+		currentClass = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord));
+		goto l2;
+	}
+l2:	/* end fetchClassOf: */;
+	mnuSelector = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord));
+	while (currentClass != GIV(nilObj)) {
+		dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord));
+		if (dictionary == GIV(nilObj)) {
+			return null;
+		}
+		/* begin lookupMethodFor:InDictionary: */
+		/* begin fetchWordLengthOf: */
+		/* begin sizeBitsOf: */
+		header = longAt(dictionary);
+		sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+			? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
+			: header & SizeMask);
+		length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
+		mask = (length - SelectorStart) - 1;
+
+		/* It is assumed that there are some nils in this dictionary, and search will 
+	 stop when one is encountered. However, if there are no nils, then wrapAround 
+	 will be detected the second time the loop gets to the end of the table. */
+
+		index = SelectorStart + (mask & (((mnuSelector & 1)
+	? (mnuSelector >> 1)
+	: (((usqInt) (longAt(mnuSelector))) >> HashBitsOffset) & HashMaskUnshifted)));
+		wrapAround = 0;
+		while (1) {
+			nextSelector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+			if (nextSelector == GIV(nilObj)) {
+				mnuMethod = null;
+				goto l1;
+			}
+			if (nextSelector == mnuSelector) {
+				methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+				mnuMethod = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
+				goto l1;
+			}
+			index += 1;
+			if (index == length) {
+				if (wrapAround) {
+					mnuMethod = null;
+					goto l1;
+				}
+				wrapAround = 1;
+				index = SelectorStart;
+			}
+		}
+		mnuMethod = null;
+	l1:	/* end lookupMethodFor:InDictionary: */;
+		if (mnuMethod != null) {
+			methodHeader = longAt((mnuMethod + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+			if ((!(isCogMethodReference(methodHeader)))
+			 && (((((usqInt) methodHeader) >> 10) & 255) <= maxLiteralCountForCompile)) {
+				cogselector(mnuMethod, mnuSelector);
+			}
+			return mnuMethod;
+		}
+		currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex << ShiftForWord));
+	}
+	return null;
+}
+
+
 /*	The module with the given name was just unloaded. 
 	Make sure we have no dangling references. */
 
@@ -24325,7 +24476,7 @@
 		if (((((usqInt) objHeader) >> 12) & 31) == ClassMethodContextCompactIndex) {
 			/* begin cloneContext: */
 			VM_LABEL(0cloneContext);
-			cloned = clone(receiver);
+			cloned = eeInstantiateMethodContextByteSize(byteSizeOf(receiver));
 			if (cloned != 0) {
 				for (i = 0; i <= StackPointerIndex; i += 1) {
 					/* begin storePointerUnchecked:ofObject:withValue: */
@@ -28635,6 +28786,10 @@
 
 
 /*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
 	cache that
 	refer to this method, presumably because it has been redefined, overridden
 	or removed.
@@ -28658,22 +28813,17 @@
 		}
 		probe += MethodCacheEntrySize;
 	}
-	if (((oldMethod & 1) == 0)
-	 && (((((usqInt) (longAt(oldMethod))) >> 8) & 15) >= 12)) {
-		/* begin primitiveIndexOf: */
-		primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
-		primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
-		if (primIdx == PrimitiveExternalCallIndex) {
-			flushExternalPrimitiveOf(oldMethod);
-		}
-		if (methodHasCogMethod(oldMethod)) {
-			unlinkSendsTo(cogMethodOf(oldMethod));
-		}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
 	}
 	/* begin flushAtCache */
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
+	unlinkSendsTo(longAt(GIV(stackPointer)));
 }
 
 
@@ -28704,7 +28854,7 @@
 			GIV(atCache)[i1] = 0;
 		}
 	}
-	unlinkSendsOf(selector);
+	unlinkSendsOfisMNUSelector(selector, selector == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord))));
 }
 
 
@@ -37364,6 +37514,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -37391,6 +37543,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38068,7 +38222,49 @@
 	printf("\n");
 }
 
+void
+printMethodDictionaryOf(sqInt behavior)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
 
+	/* begin printMethodDictionary: */
+	VM_LABEL(0printMethodDictionary);
+	methodArray = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)))) - 1); index += 1) {
+		selector = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+void
+printMethodDictionary(sqInt dictionary)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
+
+	methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(dictionary)) - 1); index += 1) {
+		selector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+
 /*	Scan the heap printing the oops of any and all objects that refer to anOop */
 
 void
@@ -38247,8 +38443,6 @@
 
 	/* begin printOopShortInner: */
 	VM_LABEL(0printOopShortInner);
-	/* begin printChar: */
-	putchar('=');
 	if ((oop & 1)) {
 		printNum((oop >> 1));
 		/* begin printChar: */
@@ -38317,10 +38511,10 @@
 	if (nameLen == 10) {
 		if (!(strncmp(name, "ByteString", 10))) {
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			printStringOf(oop);
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			goto l2;
 		}
 		if (!(strncmp(name, "ByteSymbol", 10))) {

Modified: branches/Cog/src/vm/cointerp.h
===================================================================
--- branches/Cog/src/vm/cointerp.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cointerp.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 
@@ -72,6 +72,7 @@
 sqInt falseObject(void);
 sqInt fetchByteofObject(sqInt byteIndex, sqInt oop);
 void findString(char *aCString);
+void flushExternalPrimitiveOf(sqInt methodObj);
 sqInt formatOfClass(sqInt classPointer);
 usqInt framePointerAddress(void);
 usqInt freeStartAddress(void);
@@ -144,6 +145,8 @@
 void printCogMethod(CogMethod *cogMethod);
 void printHex(sqInt n);
 void printInstancesOf(sqInt aClassOop);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 void printObjectsFromto(sqInt startAddress, sqInt endAddress);
 void printProcessStack(sqInt aProcess);

Modified: branches/Cog/src/vm/cointerpmt.c
===================================================================
--- branches/Cog/src/vm/cointerpmt.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cointerpmt.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	CoInterpreterMT VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CoInterpreterMT VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -515,6 +515,7 @@
 void dumpTraceLog(void);
 static sqInt eeInstantiateAndInitializeClassindexableSize(sqInt classPointer, sqInt size);
 sqInt eeInstantiateClassindexableSize(sqInt classPointer, sqInt size);
+static sqInt eeInstantiateMethodContextByteSize(sqInt sizeInBytes);
 static sqInt eeInstantiateSmallClasssizeInBytes(sqInt classPointer, sqInt sizeInBytes);
 static sqInt encodedNativePCOfcogMethod(sqInt mcpc, CogBlockMethod *cogMethod);
 static sqInt ensureCallerContext(char *theFP);
@@ -561,7 +562,7 @@
 double floatArg(sqInt index);
 sqInt floatObjectOf(double aFloat);
 double floatValueOf(sqInt oop);
-static void flushExternalPrimitiveOf(sqInt methodObj);
+void flushExternalPrimitiveOf(sqInt methodObj);
 static void flushExternalPrimitives(void);
 void forceInterruptCheck(void);
 void forceInterruptCheckFromHeartbeat(void);
@@ -603,7 +604,7 @@
 sqOSThread getVMOSThread(void);
 static sqInt getVMOwner(void);
 static sqInt growThreadInfosToAtLeast(sqInt index);
-static sqInt handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean);
+static sqInt handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage);
 static void handleStackOverflow(void);
 static sqInt handleStackOverflowOrEventAllowContextSwitch(sqInt mayContextSwitch);
 sqInt headerOf(sqInt methodPointer);
@@ -733,6 +734,7 @@
 static sqInt mframeIsBlockActivation(char *theFP);
 static sqInt mframeReceiver(char *theFP);
 sqInt mMethodClass(void);
+static sqInt mnuMethodOrNilFor(sqInt rcvr);
 EXPORT(void) moduleUnloaded(char *aModuleName);
 static char * moveFramesInthroughtoPage(StackPage *oldPage, char *theFP, StackPage *newPage);
 static sqInt mustMapMachineCodePCcontext(sqInt theIP, sqInt aOnceMarriedContext);
@@ -1041,6 +1043,8 @@
 void printInstancesOf(sqInt aClassOop);
 static void printLogEntryAt(sqInt i);
 void printMemory(void);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 static void printNameOfClasscount(sqInt classOop, sqInt cnt);
 static void printNum(sqInt n);
@@ -1976,7 +1980,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.114]";
+const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.117]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 sqInt willNotThreadWarnCount;
@@ -10436,13 +10440,45 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     CogMethod *cPIC;
+    sqInt primBits;
+    sqInt primitiveIndex;
+    char *sp;
+    sqInt top;
 
 	assert(((rcvr & 1))
 	 || (addressCouldBeObj(rcvr)));
+	assert((aMethodObj == 0)
+	 || ((addressCouldBeObj(aMethodObj))
+	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
 	assert(((cPIC->cmType)) == CMClosedPIC);
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
+	if (aMethodObj != 0) {
+		/* begin popStack */
+		top = longAt(GIV(stackPointer));
+		GIV(stackPointer) += BytesPerWord;
+		GIV(instructionPointer) = ((sqInt) top);
+		createActualMessageTo(fetchClassOf(rcvr));
+		if (((aMethodObj & 1) == 0)
+		 && ((((((usqInt) (longAt(aMethodObj))) >> 8) & 15) >= 12)
+		 && (isCogMethodReference(longAt((aMethodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+			/* begin push: */
+			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+			GIV(stackPointer) = sp;
+			executeCogMethodFromUnlinkedSendwithReceiver(cogMethodOf(aMethodObj), rcvr);
+			assert(0);
+		}
+		GIV(newMethod) = aMethodObj;
+		/* begin primitiveIndexOf: */
+		primBits = (((usqInt) (headerOf(aMethodObj))) >> 1) & 268435967;
+		primitiveIndex = (primBits & 511) + (((usqInt) primBits) >> 19);
+		/* begin functionPointerFor:inClass: */
+		primitiveFunctionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex
+	? 0
+	: primitiveTable[primitiveIndex])));
+		interpretMethodFromMachineCode(); return;
+	}
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
 		GIV(lkupClass) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
@@ -10457,7 +10493,8 @@
 		goto l1;
 	}
 l1:	/* end fetchClassOf: */;
-	handleMNUInMachineCodeToclassForMessagemayLink(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass), 0);
+	handleMNUInMachineCodeToclassForMessage(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass));
+	assert(0);
 }
 
 sqInt
@@ -10867,7 +10904,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10956,7 +10993,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -11086,7 +11123,14 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, canLinkCacheTag);
+			if (canLinkCacheTag
+			 && ((errSelIdx == SelectorDoesNotUnderstand)
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
+				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
+					? entryOffset()
+					: noCheckEntryOffset()), rcvr);
+			}
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -12450,8 +12494,8 @@
 
 	assert((!(isOopCompiledMethod(obj)))
 	 || (!(methodHasCogMethod(obj))));
-	assert((!(isContext(oop)))
-	 || (!(isMarriedOrWidowedContext(oop))));
+	assert((!(isContext(obj)))
+	 || (!(isMarriedOrWidowedContext(obj))));
 	assert(isNonIntegerObject(obj));
 	extraHdrBytes = headerTypeBytes[(longAt(obj)) & TypeMask];
 	/* begin sizeBitsOf: */
@@ -14365,6 +14409,91 @@
 }
 
 
+/*	This version of instantiateClass assumes that the total object 
+	size is under 256 bytes, the limit for objects with only one or 
+	two header words. Note that the size is specified in bytes 
+	and should include four bytes for the base header word.
+	Will *not* cause a GC. */
+
+static sqInt
+eeInstantiateMethodContextByteSize(sqInt sizeInBytes)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt hash;
+    sqInt header1;
+    usqInt newChunk;
+    usqInt newFreeStart;
+    sqInt newObj;
+
+	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
+	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
+	assert(sizeInBytes <= SizeMask);
+	assert((header1 & CompactClassMask) > 0);
+	header1 += sizeInBytes - (header1 & SizeMask);
+	flag("Dan");
+	/* begin eeAllocate:headerSize:h1:h2:h3: */
+	/* begin allocateInterpreterChunk: */
+	newChunk = GIV(freeStart);
+	newFreeStart = GIV(freeStart) + (sizeInBytes + ((1 - 1) * BytesPerWord));
+	if (newFreeStart < GIV(scavengeThreshold)) {
+		if ((AllocationCheckFiller != 0)
+		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
+	? newChunk
+	: AllocationCheckFiller)))) {
+			error("last object overwritten");
+		}
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	if (GIV(freeStart) < GIV(scavengeThreshold)) {
+		/* begin scheduleIncrementalGC */
+		GIV(needGCFlag) = 1;
+		forceInterruptCheck();
+	}
+	if (newFreeStart < GIV(reserveStart)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	/* begin scheduleIncrementalGC */
+	GIV(needGCFlag) = 1;
+	forceInterruptCheck();
+	if (GIV(freeStart) <= GIV(endOfMemory)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	error("out of memory");
+	newObj = null;
+l1:	/* end allocateInterpreterChunk: */;
+	if (newObj == 0) {
+		return newObj;
+	}
+	if (1 == 3) {
+		longAtput(newObj, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
+		newObj += BytesPerWord * 2;
+	}
+	if (1 == 2) {
+		longAtput(newObj, null | HeaderTypeClass);
+		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
+		newObj += BytesPerWord;
+	}
+	if (1 == 1) {
+		longAtput(newObj, header1 | HeaderTypeShort);
+	}
+	if (DoExpensiveAssertionChecks) {
+		okayOop(newObj);
+		oopHasOkayClass(newObj);
+		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
+			error("allocate bug: did not set header of new oop correctly");
+		}
+	}
+	return newObj;
+}
+
+
 /*	This version of instantiateClass assumes that the total object
 	size is under 256 bytes, the limit for objects with only one or
 	two header words. Note that the size is specified in bytes
@@ -16262,6 +16391,10 @@
 			 && (((lengthOf(obj)) == cssz)
 			 && ((strncmp(aCString, pointerForOop(obj + BaseHeaderSize), cssz)) == 0))) {
 				printHex(obj);
+				/* begin space */
+				/* begin printChar: */
+				putchar(' ');
+				printOopShort(obj);
 				/* begin cr */
 				printf("\n");
 			}
@@ -16454,11 +16587,14 @@
 }
 
 
+/*	methodObj is a CompiledMethod containing an external primitive. Flush the
+	function address and session ID of the CM
+ */
 /*	methodObj is a CompiledMethod containing an external primitive.
 	Flush the function address and session ID of the CM. Override
 	to also flush the machine code call if one exists. */
 
-static void
+void
 flushExternalPrimitiveOf(sqInt methodObj)
 {
     sqInt lit;
@@ -17271,14 +17407,11 @@
 }
 
 
-/*	A message send from either an open PIC or an unlinked send has not
-	been understood. Load newMethod with the MNU method. If linking
-	is allowed and the target MNU method is in the cache then create a
-	closed PIC with an mnu-entry and link the send to it. messageSelector,
-	argumentCount and lkupClass have already been set by the caller. */
+/*	A message send from either an open PIC or an unlinked send has
+	not been understood. Execute the relevant resulting MNU method. */
 
 static sqInt
-handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean)
+handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt class;
     sqInt classForThisMessage;
@@ -17342,24 +17475,18 @@
 		errSelIdx = SelectorDoesNotUnderstand;
 	l1:	/* end lookupMethodNoMNUEtcInClass: */;
 		if (errSelIdx != 0) {
-			if (errSelIdx == SelectorDoesNotUnderstand) {
+			if (selectorIndex == SelectorDoesNotUnderstand) {
 				error("Recursive not understood error encountered");
 			}
 			/* begin push: */
 			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 			GIV(stackPointer) = sp;
-			return handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, classForThisMessage, 0);
+			return handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForThisMessage);
 		}
 	}
 	if (((GIV(newMethod) & 1) == 0)
 	 && ((((((usqInt) (longAt(GIV(newMethod)))) >> 8) & 15) >= 12)
 	 && (isCogMethodReference(longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
-		if (mayLinkBoolean) {
-			flag("implement creating an MNU PIC sometime");
-			if (0) {
-				error("shouldBeImplemented");
-			}
-		}
 		/* begin push: */
 		longAtput((sp1 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp1;
@@ -20454,6 +20581,7 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     sqInt class;
+    sqInt erridx;
 
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
@@ -20471,8 +20599,8 @@
 l1:	/* end fetchClassOf: */;
 	if (!(lookupInMethodCacheSelclass(selector, class))) {
 		GIV(messageSelector) = selector;
-		if ((lookupMethodNoMNUEtcInClass(class)) != 0) {
-			return null;
+		if (((erridx = lookupMethodNoMNUEtcInClass(class))) != 0) {
+			return erridx;
 		}
 	}
 	return GIV(newMethod);
@@ -21957,13 +22085,8 @@
     CogMethod *cogMethod;
     sqInt frameNumArgs;
     sqInt frameNumArgs1;
-    sqInt hash;
-    sqInt header1;
-    usqInt i;
+    sqInt i;
     sqInt methodFieldOrObj;
-    usqInt newChunk;
-    usqInt newFreeStart;
-    sqInt newObj;
     sqInt numArgs;
     sqInt numStack;
     sqInt rcvr;
@@ -22006,77 +22129,7 @@
 		rcvr = longAt(theFP + FoxIFReceiver);
 		numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs;
 	}
-	/* begin eeInstantiateMethodContextByteSize: */
-	VM_LABEL(0eeInstantiateMethodContextByteSize);
-	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
-	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
-	assert(byteSize <= SizeMask);
-	assert((header1 & CompactClassMask) > 0);
-	header1 += byteSize - (header1 & SizeMask);
-	flag("Dan");
-	/* begin eeAllocate:headerSize:h1:h2:h3: */
-	/* begin allocateInterpreterChunk: */
-	newChunk = GIV(freeStart);
-	newFreeStart = GIV(freeStart) + (byteSize + ((1 - 1) * BytesPerWord));
-	if (newFreeStart < GIV(scavengeThreshold)) {
-		if ((AllocationCheckFiller != 0)
-		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
-	? newChunk
-	: AllocationCheckFiller)))) {
-			error("last object overwritten");
-		}
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	if (GIV(freeStart) < GIV(scavengeThreshold)) {
-		/* begin scheduleIncrementalGC */
-		GIV(needGCFlag) = 1;
-		forceInterruptCheck();
-	}
-	if (newFreeStart < GIV(reserveStart)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	/* begin scheduleIncrementalGC */
-	GIV(needGCFlag) = 1;
-	forceInterruptCheck();
-	if (GIV(freeStart) <= GIV(endOfMemory)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	error("out of memory");
-	newObj = null;
-l1:	/* end allocateInterpreterChunk: */;
-	if (newObj == 0) {
-		theContext = newObj;
-		goto l2;
-	}
-	if (1 == 3) {
-		longAtput(newObj, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
-		newObj += BytesPerWord * 2;
-	}
-	if (1 == 2) {
-		longAtput(newObj, null | HeaderTypeClass);
-		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
-		newObj += BytesPerWord;
-	}
-	if (1 == 1) {
-		longAtput(newObj, header1 | HeaderTypeShort);
-	}
-	if (DoExpensiveAssertionChecks) {
-		okayOop(newObj);
-		oopHasOkayClass(newObj);
-		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
-			error("allocate bug: did not set header of new oop correctly");
-		}
-	}
-	theContext = newObj;
-l2:	/* end eeInstantiateMethodContextByteSize: */;
+	theContext = eeInstantiateMethodContextByteSize(byteSize);
 	longAtput(theFP + FoxThisContext, theContext);
 	/* begin storePointerUnchecked:ofObject:withValue: */
 	/* begin withSmallIntegerTags: */
@@ -22353,6 +22406,104 @@
 }
 
 
+/*	Lookup the doesNotUnderstand: selector in the class of the argument rcvr.
+	Answer either the matching method (cogged if appropriate), or nil, if not
+	found. 
+ */
+
+static sqInt
+mnuMethodOrNilFor(sqInt rcvr)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt currentClass;
+    sqInt dictionary;
+    sqInt header;
+    sqInt index;
+    sqInt length;
+    sqInt mask;
+    sqInt methodArray;
+    sqInt methodHeader;
+    sqInt mnuMethod;
+    sqInt mnuSelector;
+    sqInt nextSelector;
+    sqInt sz;
+    sqInt wrapAround;
+
+	/* begin fetchClassOf: */
+	if ((rcvr & 1)) {
+		currentClass = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
+		goto l2;
+	}
+	if (((ccIndex = (((usqInt) (longAt(rcvr))) >> 12) & 31)) == 0) {
+		currentClass = (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask;
+		goto l2;
+	}
+	else {
+		currentClass = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord));
+		goto l2;
+	}
+l2:	/* end fetchClassOf: */;
+	mnuSelector = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord));
+	while (currentClass != GIV(nilObj)) {
+		dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord));
+		if (dictionary == GIV(nilObj)) {
+			return null;
+		}
+		/* begin lookupMethodFor:InDictionary: */
+		/* begin fetchWordLengthOf: */
+		/* begin sizeBitsOf: */
+		header = longAt(dictionary);
+		sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+			? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
+			: header & SizeMask);
+		length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
+		mask = (length - SelectorStart) - 1;
+
+		/* It is assumed that there are some nils in this dictionary, and search will 
+	 stop when one is encountered. However, if there are no nils, then wrapAround 
+	 will be detected the second time the loop gets to the end of the table. */
+
+		index = SelectorStart + (mask & (((mnuSelector & 1)
+	? (mnuSelector >> 1)
+	: (((usqInt) (longAt(mnuSelector))) >> HashBitsOffset) & HashMaskUnshifted)));
+		wrapAround = 0;
+		while (1) {
+			nextSelector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+			if (nextSelector == GIV(nilObj)) {
+				mnuMethod = null;
+				goto l1;
+			}
+			if (nextSelector == mnuSelector) {
+				methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+				mnuMethod = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
+				goto l1;
+			}
+			index += 1;
+			if (index == length) {
+				if (wrapAround) {
+					mnuMethod = null;
+					goto l1;
+				}
+				wrapAround = 1;
+				index = SelectorStart;
+			}
+		}
+		mnuMethod = null;
+	l1:	/* end lookupMethodFor:InDictionary: */;
+		if (mnuMethod != null) {
+			methodHeader = longAt((mnuMethod + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+			if ((!(isCogMethodReference(methodHeader)))
+			 && (((((usqInt) methodHeader) >> 10) & 255) <= maxLiteralCountForCompile)) {
+				cogselector(mnuMethod, mnuSelector);
+			}
+			return mnuMethod;
+		}
+		currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex << ShiftForWord));
+	}
+	return null;
+}
+
+
 /*	The module with the given name was just unloaded. 
 	Make sure we have no dangling references. */
 
@@ -25530,7 +25681,7 @@
 		if (((((usqInt) objHeader) >> 12) & 31) == ClassMethodContextCompactIndex) {
 			/* begin cloneContext: */
 			VM_LABEL(0cloneContext);
-			cloned = clone(receiver);
+			cloned = eeInstantiateMethodContextByteSize(byteSizeOf(receiver));
 			if (cloned != 0) {
 				for (i = 0; i <= StackPointerIndex; i += 1) {
 					/* begin storePointerUnchecked:ofObject:withValue: */
@@ -29840,6 +29991,10 @@
 
 
 /*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
 	cache that
 	refer to this method, presumably because it has been redefined, overridden
 	or removed.
@@ -29863,22 +30018,17 @@
 		}
 		probe += MethodCacheEntrySize;
 	}
-	if (((oldMethod & 1) == 0)
-	 && (((((usqInt) (longAt(oldMethod))) >> 8) & 15) >= 12)) {
-		/* begin primitiveIndexOf: */
-		primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
-		primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
-		if (primIdx == PrimitiveExternalCallIndex) {
-			flushExternalPrimitiveOf(oldMethod);
-		}
-		if (methodHasCogMethod(oldMethod)) {
-			unlinkSendsTo(cogMethodOf(oldMethod));
-		}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
 	}
 	/* begin flushAtCache */
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
+	unlinkSendsTo(longAt(GIV(stackPointer)));
 }
 
 
@@ -29909,7 +30059,7 @@
 			GIV(atCache)[i1] = 0;
 		}
 	}
-	unlinkSendsOf(selector);
+	unlinkSendsOfisMNUSelector(selector, selector == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord))));
 }
 
 
@@ -38687,6 +38837,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38714,6 +38866,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -39415,7 +39569,49 @@
 	printf("\n");
 }
 
+void
+printMethodDictionaryOf(sqInt behavior)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
 
+	/* begin printMethodDictionary: */
+	VM_LABEL(0printMethodDictionary);
+	methodArray = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)))) - 1); index += 1) {
+		selector = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+void
+printMethodDictionary(sqInt dictionary)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
+
+	methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(dictionary)) - 1); index += 1) {
+		selector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+
 /*	Scan the heap printing the oops of any and all objects that refer to anOop */
 
 void
@@ -39594,8 +39790,6 @@
 
 	/* begin printOopShortInner: */
 	VM_LABEL(0printOopShortInner);
-	/* begin printChar: */
-	putchar('=');
 	if ((oop & 1)) {
 		printNum((oop >> 1));
 		/* begin printChar: */
@@ -39664,10 +39858,10 @@
 	if (nameLen == 10) {
 		if (!(strncmp(name, "ByteString", 10))) {
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			printStringOf(oop);
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			goto l2;
 		}
 		if (!(strncmp(name, "ByteSymbol", 10))) {

Modified: branches/Cog/src/vm/cointerpmt.h
===================================================================
--- branches/Cog/src/vm/cointerpmt.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/cointerpmt.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 
@@ -73,6 +73,7 @@
 sqInt falseObject(void);
 sqInt fetchByteofObject(sqInt byteIndex, sqInt oop);
 void findString(char *aCString);
+void flushExternalPrimitiveOf(sqInt methodObj);
 sqInt formatOfClass(sqInt classPointer);
 usqInt framePointerAddress(void);
 usqInt freeStartAddress(void);
@@ -147,6 +148,8 @@
 void printCogMethod(CogMethod *cogMethod);
 void printHex(sqInt n);
 void printInstancesOf(sqInt aClassOop);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 void printObjectsFromto(sqInt startAddress, sqInt endAddress);
 void printProcessStack(sqInt aProcess);

Modified: branches/Cog/src/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/src/vm/gcc3x-cointerp.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/gcc3x-cointerp.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -469,6 +469,7 @@
 void dumpTraceLog(void);
 static sqInt eeInstantiateAndInitializeClassindexableSize(sqInt classPointer, sqInt size);
 sqInt eeInstantiateClassindexableSize(sqInt classPointer, sqInt size);
+static sqInt eeInstantiateMethodContextByteSize(sqInt sizeInBytes);
 static sqInt eeInstantiateSmallClasssizeInBytes(sqInt classPointer, sqInt sizeInBytes);
 static sqInt encodedNativePCOfcogMethod(sqInt mcpc, CogBlockMethod *cogMethod);
 static sqInt ensureCallerContext(char *theFP);
@@ -514,7 +515,7 @@
 double floatArg(sqInt index);
 sqInt floatObjectOf(double aFloat);
 double floatValueOf(sqInt oop);
-static void flushExternalPrimitiveOf(sqInt methodObj);
+void flushExternalPrimitiveOf(sqInt methodObj);
 static void flushExternalPrimitives(void);
 void forceInterruptCheck(void);
 void forceInterruptCheckFromHeartbeat(void);
@@ -553,7 +554,7 @@
 static sqInt getShortFromFileswap(sqImageFile aFile, sqInt swapFlag);
 sqInt getStackPointer(void);
 sqInt getThisSessionID(void);
-static sqInt handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean);
+static sqInt handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage);
 static void handleStackOverflow(void);
 static sqInt handleStackOverflowOrEventAllowContextSwitch(sqInt mayContextSwitch);
 sqInt headerOf(sqInt methodPointer);
@@ -679,6 +680,7 @@
 static sqInt mframeIsBlockActivation(char *theFP);
 static sqInt mframeReceiver(char *theFP);
 sqInt mMethodClass(void);
+static sqInt mnuMethodOrNilFor(sqInt rcvr);
 EXPORT(void) moduleUnloaded(char *aModuleName);
 static char * moveFramesInthroughtoPage(StackPage *oldPage, char *theFP, StackPage *newPage);
 static sqInt mustMapMachineCodePCcontext(sqInt theIP, sqInt aOnceMarriedContext);
@@ -978,6 +980,8 @@
 void printInstancesOf(sqInt aClassOop);
 static void printLogEntryAt(sqInt i);
 void printMemory(void);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 static void printNameOfClasscount(sqInt classOop, sqInt cnt);
 static void printNum(sqInt n);
@@ -1879,7 +1883,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.114]";
+const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.117]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -10093,13 +10097,45 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     CogMethod *cPIC;
+    sqInt primBits;
+    sqInt primitiveIndex;
+    char *sp;
+    sqInt top;
 
 	assert(((rcvr & 1))
 	 || (addressCouldBeObj(rcvr)));
+	assert((aMethodObj == 0)
+	 || ((addressCouldBeObj(aMethodObj))
+	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
 	assert(((cPIC->cmType)) == CMClosedPIC);
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
+	if (aMethodObj != 0) {
+		/* begin popStack */
+		top = longAt(GIV(stackPointer));
+		GIV(stackPointer) += BytesPerWord;
+		GIV(instructionPointer) = ((sqInt) top);
+		createActualMessageTo(fetchClassOf(rcvr));
+		if (((aMethodObj & 1) == 0)
+		 && ((((((usqInt) (longAt(aMethodObj))) >> 8) & 15) >= 12)
+		 && (isCogMethodReference(longAt((aMethodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+			/* begin push: */
+			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+			GIV(stackPointer) = sp;
+			executeCogMethodFromUnlinkedSendwithReceiver(cogMethodOf(aMethodObj), rcvr);
+			assert(0);
+		}
+		GIV(newMethod) = aMethodObj;
+		/* begin primitiveIndexOf: */
+		primBits = (((usqInt) (headerOf(aMethodObj))) >> 1) & 268435967;
+		primitiveIndex = (primBits & 511) + (((usqInt) primBits) >> 19);
+		/* begin functionPointerFor:inClass: */
+		primitiveFunctionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex
+	? 0
+	: primitiveTable[primitiveIndex])));
+		interpretMethodFromMachineCode(); return;
+	}
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
 		GIV(lkupClass) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
@@ -10114,7 +10150,8 @@
 		goto l1;
 	}
 l1:	/* end fetchClassOf: */;
-	handleMNUInMachineCodeToclassForMessagemayLink(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass), 0);
+	handleMNUInMachineCodeToclassForMessage(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass));
+	assert(0);
 }
 
 sqInt
@@ -10524,7 +10561,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10613,7 +10650,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10743,7 +10780,14 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, canLinkCacheTag);
+			if (canLinkCacheTag
+			 && ((errSelIdx == SelectorDoesNotUnderstand)
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
+				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
+					? entryOffset()
+					: noCheckEntryOffset()), rcvr);
+			}
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -12038,8 +12082,8 @@
 
 	assert((!(isOopCompiledMethod(obj)))
 	 || (!(methodHasCogMethod(obj))));
-	assert((!(isContext(oop)))
-	 || (!(isMarriedOrWidowedContext(oop))));
+	assert((!(isContext(obj)))
+	 || (!(isMarriedOrWidowedContext(obj))));
 	assert(isNonIntegerObject(obj));
 	extraHdrBytes = headerTypeBytes[(longAt(obj)) & TypeMask];
 	/* begin sizeBitsOf: */
@@ -13820,6 +13864,91 @@
 }
 
 
+/*	This version of instantiateClass assumes that the total object 
+	size is under 256 bytes, the limit for objects with only one or 
+	two header words. Note that the size is specified in bytes 
+	and should include four bytes for the base header word.
+	Will *not* cause a GC. */
+
+static sqInt
+eeInstantiateMethodContextByteSize(sqInt sizeInBytes)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt hash;
+    sqInt header1;
+    usqInt newChunk;
+    usqInt newFreeStart;
+    sqInt newObj;
+
+	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
+	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
+	assert(sizeInBytes <= SizeMask);
+	assert((header1 & CompactClassMask) > 0);
+	header1 += sizeInBytes - (header1 & SizeMask);
+	flag("Dan");
+	/* begin eeAllocate:headerSize:h1:h2:h3: */
+	/* begin allocateInterpreterChunk: */
+	newChunk = GIV(freeStart);
+	newFreeStart = GIV(freeStart) + (sizeInBytes + ((1 - 1) * BytesPerWord));
+	if (newFreeStart < GIV(scavengeThreshold)) {
+		if ((AllocationCheckFiller != 0)
+		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
+	? newChunk
+	: AllocationCheckFiller)))) {
+			error("last object overwritten");
+		}
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	if (GIV(freeStart) < GIV(scavengeThreshold)) {
+		/* begin scheduleIncrementalGC */
+		GIV(needGCFlag) = 1;
+		forceInterruptCheck();
+	}
+	if (newFreeStart < GIV(reserveStart)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	/* begin scheduleIncrementalGC */
+	GIV(needGCFlag) = 1;
+	forceInterruptCheck();
+	if (GIV(freeStart) <= GIV(endOfMemory)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	error("out of memory");
+	newObj = null;
+l1:	/* end allocateInterpreterChunk: */;
+	if (newObj == 0) {
+		return newObj;
+	}
+	if (1 == 3) {
+		longAtput(newObj, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
+		newObj += BytesPerWord * 2;
+	}
+	if (1 == 2) {
+		longAtput(newObj, null | HeaderTypeClass);
+		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
+		newObj += BytesPerWord;
+	}
+	if (1 == 1) {
+		longAtput(newObj, header1 | HeaderTypeShort);
+	}
+	if (DoExpensiveAssertionChecks) {
+		okayOop(newObj);
+		oopHasOkayClass(newObj);
+		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
+			error("allocate bug: did not set header of new oop correctly");
+		}
+	}
+	return newObj;
+}
+
+
 /*	This version of instantiateClass assumes that the total object
 	size is under 256 bytes, the limit for objects with only one or
 	two header words. Note that the size is specified in bytes
@@ -15649,6 +15778,10 @@
 			 && (((lengthOf(obj)) == cssz)
 			 && ((strncmp(aCString, pointerForOop(obj + BaseHeaderSize), cssz)) == 0))) {
 				printHex(obj);
+				/* begin space */
+				/* begin printChar: */
+				putchar(' ');
+				printOopShort(obj);
 				/* begin cr */
 				printf("\n");
 			}
@@ -15841,11 +15974,14 @@
 }
 
 
+/*	methodObj is a CompiledMethod containing an external primitive. Flush the
+	function address and session ID of the CM
+ */
 /*	methodObj is a CompiledMethod containing an external primitive.
 	Flush the function address and session ID of the CM. Override
 	to also flush the machine code call if one exists. */
 
-static void
+void
 flushExternalPrimitiveOf(sqInt methodObj)
 {
     sqInt lit;
@@ -16611,14 +16747,11 @@
 }
 
 
-/*	A message send from either an open PIC or an unlinked send has not
-	been understood. Load newMethod with the MNU method. If linking
-	is allowed and the target MNU method is in the cache then create a
-	closed PIC with an mnu-entry and link the send to it. messageSelector,
-	argumentCount and lkupClass have already been set by the caller. */
+/*	A message send from either an open PIC or an unlinked send has
+	not been understood. Execute the relevant resulting MNU method. */
 
 static sqInt
-handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean)
+handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt class;
     sqInt classForThisMessage;
@@ -16682,24 +16815,18 @@
 		errSelIdx = SelectorDoesNotUnderstand;
 	l1:	/* end lookupMethodNoMNUEtcInClass: */;
 		if (errSelIdx != 0) {
-			if (errSelIdx == SelectorDoesNotUnderstand) {
+			if (selectorIndex == SelectorDoesNotUnderstand) {
 				error("Recursive not understood error encountered");
 			}
 			/* begin push: */
 			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 			GIV(stackPointer) = sp;
-			return handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, classForThisMessage, 0);
+			return handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForThisMessage);
 		}
 	}
 	if (((GIV(newMethod) & 1) == 0)
 	 && ((((((usqInt) (longAt(GIV(newMethod)))) >> 8) & 15) >= 12)
 	 && (isCogMethodReference(longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
-		if (mayLinkBoolean) {
-			flag("implement creating an MNU PIC sometime");
-			if (0) {
-				error("shouldBeImplemented");
-			}
-		}
 		/* begin push: */
 		longAtput((sp1 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp1;
@@ -19729,6 +19856,7 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     sqInt class;
+    sqInt erridx;
 
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
@@ -19746,8 +19874,8 @@
 l1:	/* end fetchClassOf: */;
 	if (!(lookupInMethodCacheSelclass(selector, class))) {
 		GIV(messageSelector) = selector;
-		if ((lookupMethodNoMNUEtcInClass(class)) != 0) {
-			return null;
+		if (((erridx = lookupMethodNoMNUEtcInClass(class))) != 0) {
+			return erridx;
 		}
 	}
 	return GIV(newMethod);
@@ -21204,13 +21332,8 @@
     CogMethod *cogMethod;
     sqInt frameNumArgs;
     sqInt frameNumArgs1;
-    sqInt hash;
-    sqInt header1;
-    usqInt i;
+    sqInt i;
     sqInt methodFieldOrObj;
-    usqInt newChunk;
-    usqInt newFreeStart;
-    sqInt newObj;
     sqInt numArgs;
     sqInt numStack;
     sqInt rcvr;
@@ -21253,77 +21376,7 @@
 		rcvr = longAt(theFP + FoxIFReceiver);
 		numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs;
 	}
-	/* begin eeInstantiateMethodContextByteSize: */
-	VM_LABEL(0eeInstantiateMethodContextByteSize);
-	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
-	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
-	assert(byteSize <= SizeMask);
-	assert((header1 & CompactClassMask) > 0);
-	header1 += byteSize - (header1 & SizeMask);
-	flag("Dan");
-	/* begin eeAllocate:headerSize:h1:h2:h3: */
-	/* begin allocateInterpreterChunk: */
-	newChunk = GIV(freeStart);
-	newFreeStart = GIV(freeStart) + (byteSize + ((1 - 1) * BytesPerWord));
-	if (newFreeStart < GIV(scavengeThreshold)) {
-		if ((AllocationCheckFiller != 0)
-		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
-	? newChunk
-	: AllocationCheckFiller)))) {
-			error("last object overwritten");
-		}
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	if (GIV(freeStart) < GIV(scavengeThreshold)) {
-		/* begin scheduleIncrementalGC */
-		GIV(needGCFlag) = 1;
-		forceInterruptCheck();
-	}
-	if (newFreeStart < GIV(reserveStart)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	/* begin scheduleIncrementalGC */
-	GIV(needGCFlag) = 1;
-	forceInterruptCheck();
-	if (GIV(freeStart) <= GIV(endOfMemory)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	error("out of memory");
-	newObj = null;
-l1:	/* end allocateInterpreterChunk: */;
-	if (newObj == 0) {
-		theContext = newObj;
-		goto l2;
-	}
-	if (1 == 3) {
-		longAtput(newObj, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
-		newObj += BytesPerWord * 2;
-	}
-	if (1 == 2) {
-		longAtput(newObj, null | HeaderTypeClass);
-		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
-		newObj += BytesPerWord;
-	}
-	if (1 == 1) {
-		longAtput(newObj, header1 | HeaderTypeShort);
-	}
-	if (DoExpensiveAssertionChecks) {
-		okayOop(newObj);
-		oopHasOkayClass(newObj);
-		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
-			error("allocate bug: did not set header of new oop correctly");
-		}
-	}
-	theContext = newObj;
-l2:	/* end eeInstantiateMethodContextByteSize: */;
+	theContext = eeInstantiateMethodContextByteSize(byteSize);
 	longAtput(theFP + FoxThisContext, theContext);
 	/* begin storePointerUnchecked:ofObject:withValue: */
 	/* begin withSmallIntegerTags: */
@@ -21600,6 +21653,104 @@
 }
 
 
+/*	Lookup the doesNotUnderstand: selector in the class of the argument rcvr.
+	Answer either the matching method (cogged if appropriate), or nil, if not
+	found. 
+ */
+
+static sqInt
+mnuMethodOrNilFor(sqInt rcvr)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt currentClass;
+    sqInt dictionary;
+    sqInt header;
+    sqInt index;
+    sqInt length;
+    sqInt mask;
+    sqInt methodArray;
+    sqInt methodHeader;
+    sqInt mnuMethod;
+    sqInt mnuSelector;
+    sqInt nextSelector;
+    sqInt sz;
+    sqInt wrapAround;
+
+	/* begin fetchClassOf: */
+	if ((rcvr & 1)) {
+		currentClass = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
+		goto l2;
+	}
+	if (((ccIndex = (((usqInt) (longAt(rcvr))) >> 12) & 31)) == 0) {
+		currentClass = (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask;
+		goto l2;
+	}
+	else {
+		currentClass = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord));
+		goto l2;
+	}
+l2:	/* end fetchClassOf: */;
+	mnuSelector = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord));
+	while (currentClass != GIV(nilObj)) {
+		dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord));
+		if (dictionary == GIV(nilObj)) {
+			return null;
+		}
+		/* begin lookupMethodFor:InDictionary: */
+		/* begin fetchWordLengthOf: */
+		/* begin sizeBitsOf: */
+		header = longAt(dictionary);
+		sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+			? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
+			: header & SizeMask);
+		length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
+		mask = (length - SelectorStart) - 1;
+
+		/* It is assumed that there are some nils in this dictionary, and search will 
+	 stop when one is encountered. However, if there are no nils, then wrapAround 
+	 will be detected the second time the loop gets to the end of the table. */
+
+		index = SelectorStart + (mask & (((mnuSelector & 1)
+	? (mnuSelector >> 1)
+	: (((usqInt) (longAt(mnuSelector))) >> HashBitsOffset) & HashMaskUnshifted)));
+		wrapAround = 0;
+		while (1) {
+			nextSelector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+			if (nextSelector == GIV(nilObj)) {
+				mnuMethod = null;
+				goto l1;
+			}
+			if (nextSelector == mnuSelector) {
+				methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+				mnuMethod = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
+				goto l1;
+			}
+			index += 1;
+			if (index == length) {
+				if (wrapAround) {
+					mnuMethod = null;
+					goto l1;
+				}
+				wrapAround = 1;
+				index = SelectorStart;
+			}
+		}
+		mnuMethod = null;
+	l1:	/* end lookupMethodFor:InDictionary: */;
+		if (mnuMethod != null) {
+			methodHeader = longAt((mnuMethod + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+			if ((!(isCogMethodReference(methodHeader)))
+			 && (((((usqInt) methodHeader) >> 10) & 255) <= maxLiteralCountForCompile)) {
+				cogselector(mnuMethod, mnuSelector);
+			}
+			return mnuMethod;
+		}
+		currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex << ShiftForWord));
+	}
+	return null;
+}
+
+
 /*	The module with the given name was just unloaded. 
 	Make sure we have no dangling references. */
 
@@ -24329,7 +24480,7 @@
 		if (((((usqInt) objHeader) >> 12) & 31) == ClassMethodContextCompactIndex) {
 			/* begin cloneContext: */
 			VM_LABEL(0cloneContext);
-			cloned = clone(receiver);
+			cloned = eeInstantiateMethodContextByteSize(byteSizeOf(receiver));
 			if (cloned != 0) {
 				for (i = 0; i <= StackPointerIndex; i += 1) {
 					/* begin storePointerUnchecked:ofObject:withValue: */
@@ -28639,6 +28790,10 @@
 
 
 /*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
 	cache that
 	refer to this method, presumably because it has been redefined, overridden
 	or removed.
@@ -28662,22 +28817,17 @@
 		}
 		probe += MethodCacheEntrySize;
 	}
-	if (((oldMethod & 1) == 0)
-	 && (((((usqInt) (longAt(oldMethod))) >> 8) & 15) >= 12)) {
-		/* begin primitiveIndexOf: */
-		primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
-		primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
-		if (primIdx == PrimitiveExternalCallIndex) {
-			flushExternalPrimitiveOf(oldMethod);
-		}
-		if (methodHasCogMethod(oldMethod)) {
-			unlinkSendsTo(cogMethodOf(oldMethod));
-		}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
 	}
 	/* begin flushAtCache */
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
+	unlinkSendsTo(longAt(GIV(stackPointer)));
 }
 
 
@@ -28708,7 +28858,7 @@
 			GIV(atCache)[i1] = 0;
 		}
 	}
-	unlinkSendsOf(selector);
+	unlinkSendsOfisMNUSelector(selector, selector == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord))));
 }
 
 
@@ -37368,6 +37518,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -37395,6 +37547,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38072,7 +38226,49 @@
 	printf("\n");
 }
 
+void
+printMethodDictionaryOf(sqInt behavior)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
 
+	/* begin printMethodDictionary: */
+	VM_LABEL(0printMethodDictionary);
+	methodArray = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)))) - 1); index += 1) {
+		selector = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+void
+printMethodDictionary(sqInt dictionary)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
+
+	methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(dictionary)) - 1); index += 1) {
+		selector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+
 /*	Scan the heap printing the oops of any and all objects that refer to anOop */
 
 void
@@ -38251,8 +38447,6 @@
 
 	/* begin printOopShortInner: */
 	VM_LABEL(0printOopShortInner);
-	/* begin printChar: */
-	putchar('=');
 	if ((oop & 1)) {
 		printNum((oop >> 1));
 		/* begin printChar: */
@@ -38321,10 +38515,10 @@
 	if (nameLen == 10) {
 		if (!(strncmp(name, "ByteString", 10))) {
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			printStringOf(oop);
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			goto l2;
 		}
 		if (!(strncmp(name, "ByteSymbol", 10))) {

Modified: branches/Cog/src/vm/gcc3x-cointerpmt.c
===================================================================
--- branches/Cog/src/vm/gcc3x-cointerpmt.c	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/gcc3x-cointerpmt.c	2011-08-16 22:28:12 UTC (rev 2487)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
    from
-	CoInterpreterMT VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CoInterpreterMT VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
-static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -518,6 +518,7 @@
 void dumpTraceLog(void);
 static sqInt eeInstantiateAndInitializeClassindexableSize(sqInt classPointer, sqInt size);
 sqInt eeInstantiateClassindexableSize(sqInt classPointer, sqInt size);
+static sqInt eeInstantiateMethodContextByteSize(sqInt sizeInBytes);
 static sqInt eeInstantiateSmallClasssizeInBytes(sqInt classPointer, sqInt sizeInBytes);
 static sqInt encodedNativePCOfcogMethod(sqInt mcpc, CogBlockMethod *cogMethod);
 static sqInt ensureCallerContext(char *theFP);
@@ -564,7 +565,7 @@
 double floatArg(sqInt index);
 sqInt floatObjectOf(double aFloat);
 double floatValueOf(sqInt oop);
-static void flushExternalPrimitiveOf(sqInt methodObj);
+void flushExternalPrimitiveOf(sqInt methodObj);
 static void flushExternalPrimitives(void);
 void forceInterruptCheck(void);
 void forceInterruptCheckFromHeartbeat(void);
@@ -606,7 +607,7 @@
 sqOSThread getVMOSThread(void);
 static sqInt getVMOwner(void);
 static sqInt growThreadInfosToAtLeast(sqInt index);
-static sqInt handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean);
+static sqInt handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage);
 static void handleStackOverflow(void);
 static sqInt handleStackOverflowOrEventAllowContextSwitch(sqInt mayContextSwitch);
 sqInt headerOf(sqInt methodPointer);
@@ -736,6 +737,7 @@
 static sqInt mframeIsBlockActivation(char *theFP);
 static sqInt mframeReceiver(char *theFP);
 sqInt mMethodClass(void);
+static sqInt mnuMethodOrNilFor(sqInt rcvr);
 EXPORT(void) moduleUnloaded(char *aModuleName);
 static char * moveFramesInthroughtoPage(StackPage *oldPage, char *theFP, StackPage *newPage);
 static sqInt mustMapMachineCodePCcontext(sqInt theIP, sqInt aOnceMarriedContext);
@@ -1044,6 +1046,8 @@
 void printInstancesOf(sqInt aClassOop);
 static void printLogEntryAt(sqInt i);
 void printMemory(void);
+void printMethodDictionaryOf(sqInt behavior);
+void printMethodDictionary(sqInt dictionary);
 void printMethodReferencesTo(sqInt anOop);
 static void printNameOfClasscount(sqInt classOop, sqInt cnt);
 static void printNum(sqInt n);
@@ -1979,7 +1983,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.114]";
+const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.117]";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 sqInt willNotThreadWarnCount;
@@ -10440,13 +10444,45 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     CogMethod *cPIC;
+    sqInt primBits;
+    sqInt primitiveIndex;
+    char *sp;
+    sqInt top;
 
 	assert(((rcvr & 1))
 	 || (addressCouldBeObj(rcvr)));
+	assert((aMethodObj == 0)
+	 || ((addressCouldBeObj(aMethodObj))
+	 && (isOopCompiledMethod(aMethodObj))));
 	cPIC = ((CogMethod *) ((popStack()) - (mnuOffset())));
 	assert(((cPIC->cmType)) == CMClosedPIC);
 	GIV(argumentCount) = (cPIC->cmNumArgs);
 	GIV(messageSelector) = (cPIC->selector);
+	if (aMethodObj != 0) {
+		/* begin popStack */
+		top = longAt(GIV(stackPointer));
+		GIV(stackPointer) += BytesPerWord;
+		GIV(instructionPointer) = ((sqInt) top);
+		createActualMessageTo(fetchClassOf(rcvr));
+		if (((aMethodObj & 1) == 0)
+		 && ((((((usqInt) (longAt(aMethodObj))) >> 8) & 15) >= 12)
+		 && (isCogMethodReference(longAt((aMethodObj + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
+			/* begin push: */
+			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
+			GIV(stackPointer) = sp;
+			executeCogMethodFromUnlinkedSendwithReceiver(cogMethodOf(aMethodObj), rcvr);
+			assert(0);
+		}
+		GIV(newMethod) = aMethodObj;
+		/* begin primitiveIndexOf: */
+		primBits = (((usqInt) (headerOf(aMethodObj))) >> 1) & 268435967;
+		primitiveIndex = (primBits & 511) + (((usqInt) primBits) >> 19);
+		/* begin functionPointerFor:inClass: */
+		primitiveFunctionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex
+	? 0
+	: primitiveTable[primitiveIndex])));
+		interpretMethodFromMachineCode(); return;
+	}
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
 		GIV(lkupClass) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
@@ -10461,7 +10497,8 @@
 		goto l1;
 	}
 l1:	/* end fetchClassOf: */;
-	handleMNUInMachineCodeToclassForMessagemayLink(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass), 0);
+	handleMNUInMachineCodeToclassForMessage(SelectorDoesNotUnderstand, rcvr, GIV(lkupClass));
+	assert(0);
 }
 
 sqInt
@@ -10871,7 +10908,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -10960,7 +10997,7 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, 0);
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -11090,7 +11127,14 @@
 	}
 	else {
 		if (((errSelIdx = lookupMethodNoMNUEtcInClass(class))) != 0) {
-			handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, class, canLinkCacheTag);
+			if (canLinkCacheTag
+			 && ((errSelIdx == SelectorDoesNotUnderstand)
+			 && ((((usqInt)((cogMethod = cogMNUPICSelectormethodOperandnumArgs(GIV(messageSelector), mnuMethodOrNilFor(rcvr), GIV(argumentCount)))))) > (minCogMethodAddress())))) {
+				linkSendAtintooffsetreceiver(longAt(GIV(stackPointer)), mframeHomeMethod(GIV(framePointer)), cogMethod, (superNormalBar == 0
+					? entryOffset()
+					: noCheckEntryOffset()), rcvr);
+			}
+			handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, class);
 			assert(0);
 		}
 	}
@@ -12454,8 +12498,8 @@
 
 	assert((!(isOopCompiledMethod(obj)))
 	 || (!(methodHasCogMethod(obj))));
-	assert((!(isContext(oop)))
-	 || (!(isMarriedOrWidowedContext(oop))));
+	assert((!(isContext(obj)))
+	 || (!(isMarriedOrWidowedContext(obj))));
 	assert(isNonIntegerObject(obj));
 	extraHdrBytes = headerTypeBytes[(longAt(obj)) & TypeMask];
 	/* begin sizeBitsOf: */
@@ -14369,6 +14413,91 @@
 }
 
 
+/*	This version of instantiateClass assumes that the total object 
+	size is under 256 bytes, the limit for objects with only one or 
+	two header words. Note that the size is specified in bytes 
+	and should include four bytes for the base header word.
+	Will *not* cause a GC. */
+
+static sqInt
+eeInstantiateMethodContextByteSize(sqInt sizeInBytes)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt hash;
+    sqInt header1;
+    usqInt newChunk;
+    usqInt newFreeStart;
+    sqInt newObj;
+
+	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
+	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
+	assert(sizeInBytes <= SizeMask);
+	assert((header1 & CompactClassMask) > 0);
+	header1 += sizeInBytes - (header1 & SizeMask);
+	flag("Dan");
+	/* begin eeAllocate:headerSize:h1:h2:h3: */
+	/* begin allocateInterpreterChunk: */
+	newChunk = GIV(freeStart);
+	newFreeStart = GIV(freeStart) + (sizeInBytes + ((1 - 1) * BytesPerWord));
+	if (newFreeStart < GIV(scavengeThreshold)) {
+		if ((AllocationCheckFiller != 0)
+		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
+	? newChunk
+	: AllocationCheckFiller)))) {
+			error("last object overwritten");
+		}
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	if (GIV(freeStart) < GIV(scavengeThreshold)) {
+		/* begin scheduleIncrementalGC */
+		GIV(needGCFlag) = 1;
+		forceInterruptCheck();
+	}
+	if (newFreeStart < GIV(reserveStart)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	/* begin scheduleIncrementalGC */
+	GIV(needGCFlag) = 1;
+	forceInterruptCheck();
+	if (GIV(freeStart) <= GIV(endOfMemory)) {
+		GIV(freeStart) = newFreeStart;
+		newObj = oopForPointer(newChunk);
+		goto l1;
+	}
+	error("out of memory");
+	newObj = null;
+l1:	/* end allocateInterpreterChunk: */;
+	if (newObj == 0) {
+		return newObj;
+	}
+	if (1 == 3) {
+		longAtput(newObj, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
+		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
+		newObj += BytesPerWord * 2;
+	}
+	if (1 == 2) {
+		longAtput(newObj, null | HeaderTypeClass);
+		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
+		newObj += BytesPerWord;
+	}
+	if (1 == 1) {
+		longAtput(newObj, header1 | HeaderTypeShort);
+	}
+	if (DoExpensiveAssertionChecks) {
+		okayOop(newObj);
+		oopHasOkayClass(newObj);
+		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
+			error("allocate bug: did not set header of new oop correctly");
+		}
+	}
+	return newObj;
+}
+
+
 /*	This version of instantiateClass assumes that the total object
 	size is under 256 bytes, the limit for objects with only one or
 	two header words. Note that the size is specified in bytes
@@ -16266,6 +16395,10 @@
 			 && (((lengthOf(obj)) == cssz)
 			 && ((strncmp(aCString, pointerForOop(obj + BaseHeaderSize), cssz)) == 0))) {
 				printHex(obj);
+				/* begin space */
+				/* begin printChar: */
+				putchar(' ');
+				printOopShort(obj);
 				/* begin cr */
 				printf("\n");
 			}
@@ -16458,11 +16591,14 @@
 }
 
 
+/*	methodObj is a CompiledMethod containing an external primitive. Flush the
+	function address and session ID of the CM
+ */
 /*	methodObj is a CompiledMethod containing an external primitive.
 	Flush the function address and session ID of the CM. Override
 	to also flush the machine code call if one exists. */
 
-static void
+void
 flushExternalPrimitiveOf(sqInt methodObj)
 {
     sqInt lit;
@@ -17275,14 +17411,11 @@
 }
 
 
-/*	A message send from either an open PIC or an unlinked send has not
-	been understood. Load newMethod with the MNU method. If linking
-	is allowed and the target MNU method is in the cache then create a
-	closed PIC with an mnu-entry and link the send to it. messageSelector,
-	argumentCount and lkupClass have already been set by the caller. */
+/*	A message send from either an open PIC or an unlinked send has
+	not been understood. Execute the relevant resulting MNU method. */
 
 static sqInt
-handleMNUInMachineCodeToclassForMessagemayLink(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage, sqInt mayLinkBoolean)
+handleMNUInMachineCodeToclassForMessage(sqInt selectorIndex, sqInt rcvr, sqInt classForMessage)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt class;
     sqInt classForThisMessage;
@@ -17346,24 +17479,18 @@
 		errSelIdx = SelectorDoesNotUnderstand;
 	l1:	/* end lookupMethodNoMNUEtcInClass: */;
 		if (errSelIdx != 0) {
-			if (errSelIdx == SelectorDoesNotUnderstand) {
+			if (selectorIndex == SelectorDoesNotUnderstand) {
 				error("Recursive not understood error encountered");
 			}
 			/* begin push: */
 			longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 			GIV(stackPointer) = sp;
-			return handleMNUInMachineCodeToclassForMessagemayLink(errSelIdx, rcvr, classForThisMessage, 0);
+			return handleMNUInMachineCodeToclassForMessage(errSelIdx, rcvr, classForThisMessage);
 		}
 	}
 	if (((GIV(newMethod) & 1) == 0)
 	 && ((((((usqInt) (longAt(GIV(newMethod)))) >> 8) & 15) >= 12)
 	 && (isCogMethodReference(longAt((GIV(newMethod) + BaseHeaderSize) + (HeaderIndex << ShiftForWord)))))) {
-		if (mayLinkBoolean) {
-			flag("implement creating an MNU PIC sometime");
-			if (0) {
-				error("shouldBeImplemented");
-			}
-		}
 		/* begin push: */
 		longAtput((sp1 = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer));
 		GIV(stackPointer) = sp1;
@@ -20458,6 +20585,7 @@
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
     sqInt ccIndex;
     sqInt class;
+    sqInt erridx;
 
 	/* begin fetchClassOf: */
 	if ((rcvr & 1)) {
@@ -20475,8 +20603,8 @@
 l1:	/* end fetchClassOf: */;
 	if (!(lookupInMethodCacheSelclass(selector, class))) {
 		GIV(messageSelector) = selector;
-		if ((lookupMethodNoMNUEtcInClass(class)) != 0) {
-			return null;
+		if (((erridx = lookupMethodNoMNUEtcInClass(class))) != 0) {
+			return erridx;
 		}
 	}
 	return GIV(newMethod);
@@ -21961,13 +22089,8 @@
     CogMethod *cogMethod;
     sqInt frameNumArgs;
     sqInt frameNumArgs1;
-    sqInt hash;
-    sqInt header1;
-    usqInt i;
+    sqInt i;
     sqInt methodFieldOrObj;
-    usqInt newChunk;
-    usqInt newFreeStart;
-    sqInt newObj;
     sqInt numArgs;
     sqInt numStack;
     sqInt rcvr;
@@ -22010,77 +22133,7 @@
 		rcvr = longAt(theFP + FoxIFReceiver);
 		numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs;
 	}
-	/* begin eeInstantiateMethodContextByteSize: */
-	VM_LABEL(0eeInstantiateMethodContextByteSize);
-	hash = ((usqInt) GIV(freeStart)) >> BytesPerWord;
-	header1 = ((hash & HashMaskUnshifted) << HashBitsOffset) | (((ClassMethodContextCompactIndex << 12) + (3 << 8)) + ((CtxtTempFrameStart + (((sqInt) BaseHeaderSize >> 2))) << 2));
-	assert(byteSize <= SizeMask);
-	assert((header1 & CompactClassMask) > 0);
-	header1 += byteSize - (header1 & SizeMask);
-	flag("Dan");
-	/* begin eeAllocate:headerSize:h1:h2:h3: */
-	/* begin allocateInterpreterChunk: */
-	newChunk = GIV(freeStart);
-	newFreeStart = GIV(freeStart) + (byteSize + ((1 - 1) * BytesPerWord));
-	if (newFreeStart < GIV(scavengeThreshold)) {
-		if ((AllocationCheckFiller != 0)
-		 && ((longAt(newChunk)) != ((AllocationCheckFiller == 182275669
-	? newChunk
-	: AllocationCheckFiller)))) {
-			error("last object overwritten");
-		}
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	if (GIV(freeStart) < GIV(scavengeThreshold)) {
-		/* begin scheduleIncrementalGC */
-		GIV(needGCFlag) = 1;
-		forceInterruptCheck();
-	}
-	if (newFreeStart < GIV(reserveStart)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	/* begin scheduleIncrementalGC */
-	GIV(needGCFlag) = 1;
-	forceInterruptCheck();
-	if (GIV(freeStart) <= GIV(endOfMemory)) {
-		GIV(freeStart) = newFreeStart;
-		newObj = oopForPointer(newChunk);
-		goto l1;
-	}
-	error("out of memory");
-	newObj = null;
-l1:	/* end allocateInterpreterChunk: */;
-	if (newObj == 0) {
-		theContext = newObj;
-		goto l2;
-	}
-	if (1 == 3) {
-		longAtput(newObj, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + BytesPerWord, null | HeaderTypeSizeAndClass);
-		longAtput(newObj + (BytesPerWord * 2), header1 | HeaderTypeSizeAndClass);
-		newObj += BytesPerWord * 2;
-	}
-	if (1 == 2) {
-		longAtput(newObj, null | HeaderTypeClass);
-		longAtput(newObj + BytesPerWord, header1 | HeaderTypeClass);
-		newObj += BytesPerWord;
-	}
-	if (1 == 1) {
-		longAtput(newObj, header1 | HeaderTypeShort);
-	}
-	if (DoExpensiveAssertionChecks) {
-		okayOop(newObj);
-		oopHasOkayClass(newObj);
-		if (!((safeObjectAfter(newObj)) == GIV(freeStart))) {
-			error("allocate bug: did not set header of new oop correctly");
-		}
-	}
-	theContext = newObj;
-l2:	/* end eeInstantiateMethodContextByteSize: */;
+	theContext = eeInstantiateMethodContextByteSize(byteSize);
 	longAtput(theFP + FoxThisContext, theContext);
 	/* begin storePointerUnchecked:ofObject:withValue: */
 	/* begin withSmallIntegerTags: */
@@ -22357,6 +22410,104 @@
 }
 
 
+/*	Lookup the doesNotUnderstand: selector in the class of the argument rcvr.
+	Answer either the matching method (cogged if appropriate), or nil, if not
+	found. 
+ */
+
+static sqInt
+mnuMethodOrNilFor(sqInt rcvr)
+{   DECL_MAYBE_SQ_GLOBAL_STRUCT
+    sqInt ccIndex;
+    sqInt currentClass;
+    sqInt dictionary;
+    sqInt header;
+    sqInt index;
+    sqInt length;
+    sqInt mask;
+    sqInt methodArray;
+    sqInt methodHeader;
+    sqInt mnuMethod;
+    sqInt mnuSelector;
+    sqInt nextSelector;
+    sqInt sz;
+    sqInt wrapAround;
+
+	/* begin fetchClassOf: */
+	if ((rcvr & 1)) {
+		currentClass = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (ClassInteger << ShiftForWord));
+		goto l2;
+	}
+	if (((ccIndex = (((usqInt) (longAt(rcvr))) >> 12) & 31)) == 0) {
+		currentClass = (longAt(rcvr - BaseHeaderSize)) & AllButTypeMask;
+		goto l2;
+	}
+	else {
+		currentClass = longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (CompactClasses << ShiftForWord))) + BaseHeaderSize) + ((ccIndex - 1) << ShiftForWord));
+		goto l2;
+	}
+l2:	/* end fetchClassOf: */;
+	mnuSelector = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord));
+	while (currentClass != GIV(nilObj)) {
+		dictionary = longAt((currentClass + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord));
+		if (dictionary == GIV(nilObj)) {
+			return null;
+		}
+		/* begin lookupMethodFor:InDictionary: */
+		/* begin fetchWordLengthOf: */
+		/* begin sizeBitsOf: */
+		header = longAt(dictionary);
+		sz = ((header & TypeMask) == HeaderTypeSizeAndClass
+			? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
+			: header & SizeMask);
+		length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
+		mask = (length - SelectorStart) - 1;
+
+		/* It is assumed that there are some nils in this dictionary, and search will 
+	 stop when one is encountered. However, if there are no nils, then wrapAround 
+	 will be detected the second time the loop gets to the end of the table. */
+
+		index = SelectorStart + (mask & (((mnuSelector & 1)
+	? (mnuSelector >> 1)
+	: (((usqInt) (longAt(mnuSelector))) >> HashBitsOffset) & HashMaskUnshifted)));
+		wrapAround = 0;
+		while (1) {
+			nextSelector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+			if (nextSelector == GIV(nilObj)) {
+				mnuMethod = null;
+				goto l1;
+			}
+			if (nextSelector == mnuSelector) {
+				methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+				mnuMethod = longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord));
+				goto l1;
+			}
+			index += 1;
+			if (index == length) {
+				if (wrapAround) {
+					mnuMethod = null;
+					goto l1;
+				}
+				wrapAround = 1;
+				index = SelectorStart;
+			}
+		}
+		mnuMethod = null;
+	l1:	/* end lookupMethodFor:InDictionary: */;
+		if (mnuMethod != null) {
+			methodHeader = longAt((mnuMethod + BaseHeaderSize) + (HeaderIndex << ShiftForWord));
+			if ((!(isCogMethodReference(methodHeader)))
+			 && (((((usqInt) methodHeader) >> 10) & 255) <= maxLiteralCountForCompile)) {
+				cogselector(mnuMethod, mnuSelector);
+			}
+			return mnuMethod;
+		}
+		currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex << ShiftForWord));
+	}
+	return null;
+}
+
+
 /*	The module with the given name was just unloaded. 
 	Make sure we have no dangling references. */
 
@@ -25534,7 +25685,7 @@
 		if (((((usqInt) objHeader) >> 12) & 31) == ClassMethodContextCompactIndex) {
 			/* begin cloneContext: */
 			VM_LABEL(0cloneContext);
-			cloned = clone(receiver);
+			cloned = eeInstantiateMethodContextByteSize(byteSizeOf(receiver));
 			if (cloned != 0) {
 				for (i = 0; i <= StackPointerIndex; i += 1) {
 					/* begin storePointerUnchecked:ofObject:withValue: */
@@ -29844,6 +29995,10 @@
 
 
 /*	The receiver is a compiledMethod. Clear all entries in the method lookup
+	cache that refer to this method, presumably because it has been redefined,
+	overridden or removed.
+ */
+/*	The receiver is a compiledMethod. Clear all entries in the method lookup
 	cache that
 	refer to this method, presumably because it has been redefined, overridden
 	or removed.
@@ -29867,22 +30022,17 @@
 		}
 		probe += MethodCacheEntrySize;
 	}
-	if (((oldMethod & 1) == 0)
-	 && (((((usqInt) (longAt(oldMethod))) >> 8) & 15) >= 12)) {
-		/* begin primitiveIndexOf: */
-		primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
-		primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
-		if (primIdx == PrimitiveExternalCallIndex) {
-			flushExternalPrimitiveOf(oldMethod);
-		}
-		if (methodHasCogMethod(oldMethod)) {
-			unlinkSendsTo(cogMethodOf(oldMethod));
-		}
+	/* begin primitiveIndexOf: */
+	primBits = (((usqInt) (headerOf(oldMethod))) >> 1) & 268435967;
+	primIdx = (primBits & 511) + (((usqInt) primBits) >> 19);
+	if (primIdx == PrimitiveExternalCallIndex) {
+		flushExternalPrimitiveOf(oldMethod);
 	}
 	/* begin flushAtCache */
 	for (i1 = 1; i1 <= AtCacheTotalSize; i1 += 1) {
 		GIV(atCache)[i1] = 0;
 	}
+	unlinkSendsTo(longAt(GIV(stackPointer)));
 }
 
 
@@ -29913,7 +30063,7 @@
 			GIV(atCache)[i1] = 0;
 		}
 	}
-	unlinkSendsOf(selector);
+	unlinkSendsOfisMNUSelector(selector, selector == (longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord))));
 }
 
 
@@ -38691,6 +38841,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -38718,6 +38870,8 @@
 	/* begin tab */
 	/* begin printChar: */
 	putchar('	');
+	/* begin printChar: */
+	putchar('=');
 	printOopShort(it);
 	/* begin cr */
 	printf("\n");
@@ -39419,7 +39573,49 @@
 	printf("\n");
 }
 
+void
+printMethodDictionaryOf(sqInt behavior)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
 
+	/* begin printMethodDictionary: */
+	VM_LABEL(0printMethodDictionary);
+	methodArray = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)))) - 1); index += 1) {
+		selector = longAt(((longAt((behavior + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord))) + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+void
+printMethodDictionary(sqInt dictionary)
+{
+    sqInt index;
+    sqInt methodArray;
+    sqInt selector;
+
+	methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex << ShiftForWord));
+	for (index = SelectorStart; index <= ((fetchWordLengthOf(dictionary)) - 1); index += 1) {
+		selector = longAt((dictionary + BaseHeaderSize) + (index << ShiftForWord));
+		if (selector != GIV(nilObj)) {
+			printOopShort(selector);
+			print(" => ");
+			printOopShort(longAt((methodArray + BaseHeaderSize) + ((index - SelectorStart) << ShiftForWord)));
+			/* begin cr */
+			printf("\n");
+		}
+	}
+}
+
+
 /*	Scan the heap printing the oops of any and all objects that refer to anOop */
 
 void
@@ -39598,8 +39794,6 @@
 
 	/* begin printOopShortInner: */
 	VM_LABEL(0printOopShortInner);
-	/* begin printChar: */
-	putchar('=');
 	if ((oop & 1)) {
 		printNum((oop >> 1));
 		/* begin printChar: */
@@ -39668,10 +39862,10 @@
 	if (nameLen == 10) {
 		if (!(strncmp(name, "ByteString", 10))) {
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			printStringOf(oop);
 			/* begin printChar: */
-			putchar('"');
+			putchar('\'');
 			goto l2;
 		}
 		if (!(strncmp(name, "ByteSymbol", 10))) {

Modified: branches/Cog/src/vm/interp.h
===================================================================
--- branches/Cog/src/vm/interp.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/interp.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/src/vm/vmCallback.h
===================================================================
--- branches/Cog/src/vm/vmCallback.h	2011-08-08 19:01:31 UTC (rev 2486)
+++ branches/Cog/src/vm/vmCallback.h	2011-08-16 22:28:12 UTC (rev 2487)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.114 uuid: c9755705-e606-4e32-92f1-228c68774f30
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.117 uuid: a21465f6-8cd9-4284-8638-c30d5de21ce9
  */
 
 #define VM_CALLBACK_INC 1



More information about the Vm-dev mailing list