[Vm-dev] [commit][3362] CogVm source as per VMMaker.oscog-eem.1331

commits at squeakvm.org commits at squeakvm.org
Sat May 30 19:26:35 UTC 2015


Revision: 3362
Author:   eliot
Date:     2015-05-30 12:26:33 -0700 (Sat, 30 May 2015)
Log Message:
-----------
CogVm source as per VMMaker.oscog-eem.1331

Cogit:
Test the outerContext and method for sanity in the machine code closure value
primitive(s).  Spur must check to fail in the presence of forwarders.

To support the primitive provide TstCqR support on x86 (already exists on ARM),
and use it to implement genJumpImmediate: et al.

Also refactor genGetFormatOf:into:baseHeaderIntoScratch:
to genGetFormatOf:into: and implement it for SqueakV3.

Use the new genJumpImmediate: et al in various basic access primitives.  Good
for a 5%-10% increase in 0 tinyBenchmarks on Spur.

Spur:
Spur must follow forwarders in machine code before it follows forwarders in stack pages (since stack page parsing examines methods).

Further, closed PICs that refer to unmarked objects must be discarded in
freeUnmarkedMachineCode.  And closedPICRefersToUnmarkedObject: should guard
against an immediate selector.

Modified Paths:
--------------
    branches/Cog/nsspursrc/vm/cogit.h
    branches/Cog/nsspursrc/vm/cogitARMv5.c
    branches/Cog/nsspursrc/vm/cogitIA32.c
    branches/Cog/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspurstack64src/vm/gcc3x-interp.c
    branches/Cog/nsspurstack64src/vm/interp.c
    branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
    branches/Cog/nsspurstacksrc/vm/interp.c
    branches/Cog/spursistasrc/vm/cogit.h
    branches/Cog/spursistasrc/vm/cogitARMv5.c
    branches/Cog/spursistasrc/vm/cogitIA32.c
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cogit.h
    branches/Cog/spursrc/vm/cogitARMv5.c
    branches/Cog/spursrc/vm/cogitIA32.c
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spurstack64src/vm/gcc3x-interp.c
    branches/Cog/spurstack64src/vm/interp.c
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    branches/Cog/src/vm/cogit.h
    branches/Cog/src/vm/cogitARMv5.c
    branches/Cog/src/vm/cogitIA32.c
    branches/Cog/src/vm/cointerp.c
    branches/Cog/src/vm/cointerp.h
    branches/Cog/src/vm/cointerpmt.c
    branches/Cog/src/vm/cointerpmt.h
    branches/Cog/src/vm/gcc3x-cointerp.c
    branches/Cog/src/vm/gcc3x-cointerpmt.c
    branches/Cog/stacksrc/vm/gcc3x-interp.c
    branches/Cog/stacksrc/vm/interp.c

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

Modified: branches/Cog/nsspursrc/vm/cogit.h
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.h	2015-05-27 21:12:31 UTC (rev 3361)
+++ branches/Cog/nsspursrc/vm/cogit.h	2015-05-30 19:26:33 UTC (rev 3362)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5
+	CCodeGenerator VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e
  */
 
 

Modified: branches/Cog/nsspursrc/vm/cogitARMv5.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogitARMv5.c	2015-05-27 21:12:31 UTC (rev 3361)
+++ branches/Cog/nsspursrc/vm/cogitARMv5.c	2015-05-30 19:26:33 UTC (rev 3362)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5
+	CCodeGenerator VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -367,7 +367,7 @@
 #define SubRR 89
 #define TempReg -4
 #define TstCqR 114
-#define UnfailingPrimitive 2
+#define UnfailingPrimitive 3
 #define UnimplementedPrimitive -7
 #define ValueIndex 1
 #define VarBaseReg -20
@@ -584,6 +584,7 @@
 sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes);
 static sqInt checkMaybeObjRefAt(sqInt mcpc) NoDbgRegParms;
 static sqInt checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) NoDbgRegParms;
+static sqInt closedPICRefersToUnmarkedObject(CogMethod *cPIC) NoDbgRegParms;
 char * codeEntryFor(char *address);
 char * codeEntryNameFor(char *address);
 sqInt cogCodeBase(void);
@@ -703,6 +704,8 @@
 void mapObjectReferencesInMachineCode(sqInt gcMode);
 void markAndTraceMachineCodeOfMarkedMethods(void);
 static void markAndTraceObjectReferencesInGeneratedRuntime(void);
+static sqInt markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) NoDbgRegParms;
+static sqInt markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) NoDbgRegParms;
 static sqInt markLiteralspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) NoDbgRegParms;
 void markMethodAndReferents(CogBlockMethod *aCogMethod);
 usqInt maxCogMethodAddress(void);
@@ -806,6 +809,7 @@
 char * whereIsMaybeCodeThing(sqInt anOop);
 static sqInt checkValidObjectReference(sqInt anOop) NoDbgRegParms;
 static AbstractInstruction * genCmpClassFloatCompactIndexR(sqInt reg) NoDbgRegParms;
+static AbstractInstruction * genCmpClassMethodContextCompactIndexR(sqInt reg) NoDbgRegParms;
 static sqInt genInnerPrimitiveNewMethod(sqInt retNoffset) NoDbgRegParms;
 static sqInt isUnannotatableConstant(CogSimStackEntry *simStackEntry) NoDbgRegParms;
 static sqInt genAddSmallIntegerTagsTo(sqInt aRegister) NoDbgRegParms;
@@ -833,7 +837,9 @@
 static sqInt genInnerPrimitiveStringAtPut(sqInt retNoffset) NoDbgRegParms;
 static sqInt genInnerPrimitiveStringAt(sqInt retNoffset) NoDbgRegParms;
 static AbstractInstruction * genJumpNotSmallIntegerInScratchReg(sqInt aRegister) NoDbgRegParms;
+static AbstractInstruction * genJumpNotSmallInteger(sqInt aRegister) NoDbgRegParms;
 static AbstractInstruction * genJumpSmallIntegerInScratchReg(sqInt aRegister) NoDbgRegParms;
+static AbstractInstruction * genJumpSmallInteger(sqInt aRegister) NoDbgRegParms;
 static sqInt genNewArrayOfSizeinitialized(sqInt size, sqInt initialized) NoDbgRegParms;
 static sqInt genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) NoDbgRegParms;
 static sqInt genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) NoDbgRegParms;
@@ -847,6 +853,7 @@
 static sqInt numSmallIntegerTagBits(void);
 static sqInt validInlineCacheTag(usqInt classIndexOrTagPattern) NoDbgRegParms;
 static sqInt allYoungObjectsAgeInFullGC(void);
+static sqInt cacheTagIsMarked(sqInt cacheTag) NoDbgRegParms;
 static sqInt checkValidOopReference(sqInt anOop) NoDbgRegParms;
 static sqInt couldBeObject(sqInt literal) NoDbgRegParms;
 static sqInt createsClosuresInline(void);
@@ -866,6 +873,7 @@
 static sqInt genGetClassObjectOfintoscratchReginstRegIsReceiver(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt instRegIsReceiver) NoDbgRegParms;
 static sqInt genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) NoDbgRegParms;
 static sqInt genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) NoDbgRegParms;
+static sqInt genGetFormatOfinto(sqInt srcReg, sqInt destReg) NoDbgRegParms;
 static sqInt genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNil) NoDbgRegParms;
 static sqInt genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg) NoDbgRegParms;
 static sqInt genInnerPrimitiveAsCharacterinReg(sqInt retNOffset, sqInt reg) NoDbgRegParms;
@@ -873,6 +881,7 @@
 static sqInt genInnerPrimitiveIdenticalorNotIf(sqInt retNoffset, sqInt orNot) NoDbgRegParms;
 static sqInt genInnerPrimitiveSize(sqInt retNoffset) NoDbgRegParms;
 static AbstractInstruction * genJumpImmediateInScratchReg(sqInt aRegister) NoDbgRegParms;
+static AbstractInstruction * genJumpImmediate(sqInt aRegister) NoDbgRegParms;
 static AbstractInstruction * genJumpNotCharacterInScratchReg(sqInt reg) NoDbgRegParms;
 static sqInt genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) NoDbgRegParms;
 static sqInt genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) NoDbgRegParms;
@@ -8776,6 +8785,60 @@
 	return ok;
 }
 
+
+/*	Answer if the ClosedPIC refers to any unmarked objects or freed/freeable
+	target methods,
+	applying markAndTraceOrFreeCogMethod:firstVisit: to those targets to
+	determine if freed/freeable.
+ */
+
+	/* Cogit>>#closedPICRefersToUnmarkedObject: */
+static sqInt
+closedPICRefersToUnmarkedObject(CogMethod *cPIC)
+{
+    sqInt entryPoint;
+    sqInt i;
+    sqInt object;
+    sqInt offsetToLiteral;
+    sqInt pc;
+    CogMethod *targetMethod;
+
+	if (!(isImmediate((cPIC->selector)))) {
+		if (!(isMarked((cPIC->selector)))) {
+			return 1;
+		}
+	}
+
+	/* First jump is unconditional; subsequent ones are conditional */
+
+	pc = (((sqInt)cPIC)) + firstCPICCaseOffset;
+	offsetToLiteral = jumpLongByteSize(backEnd);
+	for (i = 1; i <= ((cPIC->cPICNumCases)); i += 1) {
+		;
+		object = literalBeforeFollowingAddress(backEnd, pc - offsetToLiteral);
+		if ((couldBeObject(object))
+		 && (!(isMarked(object)))) {
+			return 1;
+		}
+
+		/* Find target from jump.  Ignore jumps to the interpret and MNU calls within this PIC */
+
+		entryPoint = jumpLongTargetBeforeFollowingAddress(backEnd, pc);
+		if (((((usqInt)entryPoint)) < (((usqInt)cPIC)))
+		 || ((((usqInt)entryPoint)) > (((usqInt)((((usqInt)cPIC)) + ((cPIC->blockSize))))))) {
+			targetMethod = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+			assert((((targetMethod->cmType)) == CMMethod)
+			 || (((targetMethod->cmType)) == CMFree));
+			if (markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)pc)))) {
+				return 1;
+			}
+		}
+		offsetToLiteral = jumpLongConditionalByteSize(backEnd);
+		pc += cPICCaseSize;
+	}
+	return 0;
+}
+
 	/* Cogit>>#codeEntryFor: */
 char *
 codeEntryFor(char *address)
@@ -10336,7 +10399,8 @@
 
 
 /*	Free machine-code methods whose compiled methods are unmarked
-	and open PICs whose selectors are not marked. */
+	and open PICs whose selectors are not marked, and closed PICs that
+	refer to unmarked objects. */
 
 	/* Cogit>>#freeUnmarkedMachineCode */
 void
@@ -10359,6 +10423,11 @@
 			freedMethod = 1;
 			freeMethod(cogMethod);
 		}
+		if ((((cogMethod->cmType)) == CMClosedPIC)
+		 && (closedPICRefersToUnmarkedObject(cogMethod))) {
+			freedMethod = 1;
+			freeMethod(cogMethod);
+		}
 		cogMethod = ((CogMethod *) (roundUpLength((((sqInt)cogMethod)) + ((cogMethod->blockSize)))));
 	}
 	if (freedMethod) {
@@ -12310,6 +12379,260 @@
 }
 
 
+/*	Mark and trace objects in the argument and free if it is appropriate.
+	Answer if the method has been freed. firstVisit is a hint used to avoid
+	scanning methods we've already seen. False positives are fine.
+	For a CMMethod this
+	frees if the bytecode method isnt marked,
+	marks and traces object literals and selectors,
+	unlinks sends to targets that should be freed.
+	For a CMClosedPIC this
+	frees if it refers to anything that should be freed or isn't marked.
+	For a CMOpenPIC this
+	frees if the selector isn't marked. */
+/*	this recurses at most one level down */
+
+	/* Cogit>>#markAndTraceOrFreeCogMethod:firstVisit: */
+static sqInt
+markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit)
+{
+    sqInt annotation;
+    sqInt map;
+    sqInt mapByte;
+    sqInt mcpc;
+    sqInt result;
+    sqInt val;
+
+	val = 0;
+	if (((cogMethod->cmType)) == CMFree) {
+		return 1;
+	}
+	assert((cogMethodDoesntLookKosher(cogMethod)) == 0);
+	if (((cogMethod->cmType)) == CMMethod) {
+		if (!(isMarked((cogMethod->methodObject)))) {
+			freeMethod(cogMethod);
+			return 1;
+		}
+		if (firstVisit) {
+			/* begin markLiteralsAndUnlinkUnmarkedSendsIn: */
+			assert(((cogMethod->cmType)) == CMMethod);
+			assert(isMarked((cogMethod->methodObject)));
+			markAndTraceLiteralinat((cogMethod->selector), cogMethod, (&((cogMethod->selector))));
+			maybeMarkCountersIn(cogMethod);
+			/* begin maybeMarkIRCsIn: */
+			
+#      if NewspeakVM
+			markIfIRC((cogMethod->nextMethodOrIRCs));
+
+
+#      endif /* NewspeakVM */
+
+			/* begin mapFor:performUntil:arg: */
+			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
+			while (((mapByte = byteAt(map))) != MapEnd) {
+				if (mapByte >= FirstAnnotation) {
+
+					/* If this is an IsSendCall annotation, peek ahead for an IsAnnotationExtension, and consume it. */
+
+					mcpc += (mapByte & DisplacementMask) * 4;
+					if ((((annotation = ((usqInt) mapByte) >> AnnotationShift)) == IsSendCall)
+					 && ((((usqInt) ((mapByte = byteAt(map - 1)))) >> AnnotationShift) == IsAnnotationExtension)) {
+						annotation += mapByte & DisplacementMask;
+						map -= 1;
+					}
+					result = markLiteralsAndUnlinkIfUnmarkedSendpcmethod(annotation, (((char *) mcpc)), (((sqInt)cogMethod)));
+					if (result != 0) {
+						result;
+						goto l1;
+					}
+				}
+				else {
+					if (mapByte < (IsAnnotationExtension << AnnotationShift)) {
+						mcpc += ((mapByte - DisplacementX2N) << AnnotationShift) * 4;
+					}
+				}
+				map -= 1;
+			}
+			0;
+		l1:	/* end mapFor:performUntil:arg: */;
+		}
+		return 0;
+	}
+	if (((cogMethod->cmType)) == CMClosedPIC) {
+		if (!(closedPICRefersToUnmarkedObject(cogMethod))) {
+			return 0;
+		}
+		freeMethod(cogMethod);
+		return 1;
+	}
+	if (((cogMethod->cmType)) == CMOpenPIC) {
+		if (isMarked((cogMethod->selector))) {
+			return 0;
+		}
+		freeMethod(cogMethod);
+		return 1;
+	}
+	assert((((cogMethod->cmType)) == CMMethod)
+	 || ((((cogMethod->cmType)) == CMClosedPIC)
+	 || (((cogMethod->cmType)) == CMOpenPIC)));
+	return 0;
+}
+
+
+/*	Mark and trace literals. Unlink sends that have unmarked cache tags or
+	targets. 
+ */
+
+	/* Cogit>>#markLiteralsAndUnlinkIfUnmarkedSend:pc:method: */
+static sqInt
+markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod)
+{
+    usqInt cacheAddress;
+    sqInt cacheTag;
+    sqInt cacheTag1;
+    sqInt cacheTagMarked;
+    sqInt entryPoint;
+    sqInt entryPoint1;
+    sqInt entryPoint2;
+    sqInt eo;
+    sqInt literal;
+    char *mcpc1;
+    NSSendCache *nsSendCache;
+    sqInt sel;
+    sqInt sendTable;
+    sqInt *sendTable1;
+    sqInt tagCouldBeObj;
+    sqInt tagCouldBeObj1;
+    sqInt targetMethod;
+    CogMethod *targetMethod1;
+    sqInt unlinkedRoutine;
+    sqInt val;
+
+	literal = 0;
+	val = 0;
+	if (annotation == IsObjectReference) {
+		literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc));
+		if (markAndTraceLiteralinatpc(literal, ((CogMethod *) cogMethod), ((usqInt)mcpc))) {
+			codeModified = 1;
+		}
+	}
+	if (annotation == IsNSSendCall) {
+		/* begin nsSendCacheFromReturnAddress: */
+		mcpc1 = ((char *) (((sqInt)mcpc)));
+		entryPoint1 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc1));
+		assert(entryPoint1 < methodZoneBase);
+		cacheAddress = ((usqInt)(implicitReceiveCacheAt(backEnd, mcpc1)));
+		assert(isInOldSpace(cacheAddress));
+		nsSendCache = ((NSSendCache *) cacheAddress);
+		entryPoint = (nsSendCache->target);
+		if (entryPoint != 0) {
+
+			/* Send is linked */
+
+			targetMethod = entryPoint - cmNoCheckEntryOffset;
+			if (markAndTraceOrFreeCogMethodfirstVisit(targetMethod, (((usqInt)targetMethod)) > (((usqInt)mcpc)))) {
+				/* begin voidNSSendCache: */
+				(nsSendCache->classTag = 2);
+				(nsSendCache->enclosingObject = 0);
+				(nsSendCache->target = 0);
+			}
+		}
+		sel = (nsSendCache->selector);
+		if (isForwarded(sel)) {
+			sel = followForwarded(literal);
+			(nsSendCache->selector = sel);
+			markAndTraceUpdatedLiteralin(sel, ((CogMethod *) cogMethod));
+		}
+		else {
+			markAndTrace(sel);
+		}
+		eo = (nsSendCache->enclosingObject);
+		if (eo != 0) {
+			if (isForwarded(eo)) {
+				eo = followForwarded(literal);
+				(nsSendCache->enclosingObject = eo);
+				markAndTraceUpdatedLiteralin(eo, ((CogMethod *) cogMethod));
+			}
+			else {
+				markAndTrace(eo);
+			}
+		}
+	}
+
+	if (annotation >= IsSendCall) {
+		/* begin offsetCacheTagAndCouldBeObjectAt:annotation:into: */
+		cacheTag1 = inlineCacheTagAt(backEnd, ((sqInt)mcpc));
+
+		/* in-line cache tags are the selectors of sends if sends are unlinked,
+		   the selectors of super sends (entry offset = cmNoCheckEntryOffset),
+		   the selectors of open PIC sends (entry offset = cmEntryOffset, target is an Open PIC)
+		   or in-line cache tags (classes, class indices, immediate bit patterns, etc).
+		   Note that selectors can be immediate so there is no guarantee that they
+		   are markable/remappable objects. */
+
+		entryPoint2 = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc));
+		tagCouldBeObj1 = (entryPoint2 < methodZoneBase)
+		 || (((entryPoint2 & entryPointMask) == uncheckedEntryAlignment)
+		 || (((entryPoint2 & entryPointMask) == checkedEntryAlignment)
+		 && ((((((CogMethod *) (entryPoint2 - cmEntryOffset)))->cmType)) == CMOpenPIC)));
+		cacheTagMarked = tagCouldBeObj1
+		 && (cacheTagIsMarked(cacheTag1));
+		if (entryPoint2 > methodZoneBase) {
+
+			/* It's a linked send. */
+
+			/* begin targetMethodAndSendTableFor:annotation:into: */
+			if (annotation == IsSendCall) {
+				targetMethod1 = ((CogMethod *) (entryPoint2 - cmEntryOffset));
+				sendTable1 = ordinarySendTrampolines;
+			}
+			else {
+				if (annotation == IsNSSelfSend) {
+					targetMethod1 = ((CogMethod *) (entryPoint2 - cmEntryOffset));
+					sendTable1 = selfSendTrampolines;
+				}
+				else {
+					if (annotation == IsNSDynamicSuperSend) {
+						targetMethod1 = ((CogMethod *) (entryPoint2 - cmEntryOffset));
+						sendTable1 = dynamicSuperSendTrampolines;
+					}
+					else {
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint2 - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
+					}
+				}
+
+			}
+			if ((!cacheTagMarked)
+			 || (markAndTraceOrFreeCogMethodfirstVisit(targetMethod1, (((usqInt)targetMethod1)) > (((usqInt)mcpc))))) {
+
+				/* Either the cacheTag is unmarked (e.g. new class) or the target
+				   has been freed (because it is unmarked), so unlink the send. */
+
+				/* begin unlinkSendAt:targetMethod:sendTable: */
+				unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))];
+				rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod1->selector), unlinkedRoutine);
+				codeModified = 1;
+				markAndTraceLiteralinat((targetMethod1->selector), targetMethod1, (&((targetMethod1->selector))));
+			}
+
+		}
+		else {
+
+			/* cacheTag is selector */
+
+			if (markAndTraceCacheTagLiteralinatpc(cacheTag1, cogMethod, ((usqInt)mcpc))) {
+				codeModified = 1;
+			}
+		}
+
+	}
+	return 0;
+}
+
+
 /*	Mark and trace literals.
 	Additionally in Newspeak, void push implicits that have unmarked classes. */
 
@@ -15439,10 +15762,18 @@
 genCmpClassFloatCompactIndexR(sqInt reg)
 {
 	/* begin CmpCq:R: */
-	return genoperandoperand(CmpCqR, ClassFloatCompactIndex, SendNumArgsReg);
+	return genoperandoperand(CmpCqR, ClassFloatCompactIndex, reg);
 }
 
+	/* CogObjectRepresentation>>#genCmpClassMethodContextCompactIndexR: */
+static AbstractInstruction *
+genCmpClassMethodContextCompactIndexR(sqInt reg)
+{
+	/* begin CmpCq:R: */
+	return genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, reg);
+}
 
+
 /*	subclasses override if they can */
 
 	/* CogObjectRepresentation>>#genInnerPrimitiveNewMethod: */
@@ -16036,12 +16367,8 @@
 
 	/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length: */
 
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, ReceiverResultReg, TempReg);
-	jumpImmediate = genJumpImmediateInScratchReg(TempReg);
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, Arg0Reg, TempReg);
-	jumpBadIndex = genJumpNotSmallIntegerInScratchReg(TempReg);
+	jumpImmediate = genJumpImmediate(ReceiverResultReg);
+	jumpBadIndex = genJumpNotSmallInteger(Arg0Reg);
 	genConvertSmallIntegerToIntegerInReg(Arg0Reg);
 	/* begin SubCq:R: */
 	genoperandoperand(SubCqR, 1, Arg0Reg);
@@ -16209,14 +16536,10 @@
 
 	/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length: */
 
+	jumpImmediate = genJumpImmediate(ReceiverResultReg);
 	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, ReceiverResultReg, TempReg);
-	jumpImmediate = genJumpImmediateInScratchReg(TempReg);
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, Arg0Reg, TempReg);
-	/* begin MoveR:R: */
 	genoperandoperand(MoveRR, Arg0Reg, Arg1Reg);
-	jumpBadIndex = genJumpNotSmallIntegerInScratchReg(TempReg);
+	jumpBadIndex = genJumpNotSmallInteger(Arg0Reg);
 	genConvertSmallIntegerToIntegerInReg(Arg1Reg);
 	/* begin SubCq:R: */
 	genoperandoperand(SubCqR, 1, Arg1Reg);
@@ -16351,9 +16674,7 @@
     AbstractInstruction *jumpSI;
     AbstractInstruction * ret;
 
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, ReceiverResultReg, ClassReg);
-	jumpImm = genJumpImmediateInScratchReg(ClassReg);
+	jumpImm = genJumpImmediate(ReceiverResultReg);
 	genGetHashFieldNonImmOfasSmallIntegerInto(ReceiverResultReg, TempReg);
 	/* begin CmpCq:R: */
 	genoperandoperand(CmpCqR, ConstZero, TempReg);
@@ -16363,8 +16684,8 @@
 	genoperandoperand(MoveRR, TempReg, ReceiverResultReg);
 	/* begin RetN: */
 	ret = genoperand(RetN, retNoffset);
-	jmpTarget(jumpImm, gMoveRR(ReceiverResultReg, ClassReg));
-	jumpSI = genJumpSmallIntegerInScratchReg(ClassReg);
+	jmpTarget(jumpImm, gLabel());
+	jumpSI = genJumpSmallInteger(ReceiverResultReg);
 	jmpTarget(jumpSI, ret);
 	genConvertCharacterToSmallIntegerInReg(ReceiverResultReg);
 	/* begin Jump: */
@@ -16841,12 +17162,10 @@
 	genGetHashFieldNonImmOfinto(ReceiverResultReg, halfHeaderReg);
 	/* begin JumpZero: */
 	jumpUnhashed = genoperand(JumpZero, ((sqInt)0));
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, Arg0Reg, TempReg);
 
 	/* get class's format inst var for inst spec (format field) */
 
-	jumpNElementsNonInt = genJumpNotSmallIntegerInScratchReg(TempReg);
+	jumpNElementsNonInt = genJumpNotSmallInteger(Arg0Reg);
 	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, ReceiverResultReg, instSpecReg);
 	/* begin LogicalShiftRightCq:R: */
 	quickConstant = (fixedFieldsFieldWidth()) + (numSmallIntegerTagBits());
@@ -17129,7 +17448,6 @@
     AbstractInstruction *jumpBadIndex;
     AbstractInstruction *jumpBytesOutOfBounds;
     AbstractInstruction * jumpBytesOutOfRange;
-    AbstractInstruction *jumpImmediate;
     AbstractInstruction *jumpIsBytes;
     AbstractInstruction * jumpIsCompiledMethod;
     AbstractInstruction * jumpNotString;
@@ -17144,13 +17462,8 @@
 
 	/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length: */
 
+	jumpBadIndex = genJumpNotSmallInteger(Arg0Reg);
 	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, ReceiverResultReg, TempReg);
-	jumpImmediate = genJumpImmediateInScratchReg(TempReg);
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, Arg0Reg, TempReg);
-	jumpBadIndex = genJumpNotSmallIntegerInScratchReg(TempReg);
-	/* begin MoveR:R: */
 	genoperandoperand(MoveRR, Arg1Reg, TempReg);
 	jumpBadArg = genJumpNotCharacterInScratchReg(TempReg);
 	genConvertSmallIntegerToIntegerInReg(Arg0Reg);
@@ -17220,7 +17533,7 @@
 	/* begin AddCq:R: */
 	genoperandoperand(AddCqR, 1, Arg0Reg);
 	genConvertIntegerToSmallIntegerInReg(Arg0Reg);
-	jmpTarget(jumpBadIndex, jmpTarget(jumpImmediate, gLabel()));
+	jmpTarget(jumpBadIndex, gLabel());
 	return 0;
 }
 
@@ -17250,10 +17563,8 @@
 	/* c.f. StackInterpreter>>stSizeOf: SpurMemoryManager>>lengthOf:format: fixedFieldsOf:format:length: */
 
 	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, Arg0Reg, TempReg);
-	/* begin MoveR:R: */
 	genoperandoperand(MoveRR, Arg0Reg, Arg1Reg);
-	jumpBadIndex = genJumpNotSmallIntegerInScratchReg(TempReg);
+	jumpBadIndex = genJumpNotSmallInteger(Arg0Reg);
 	genConvertSmallIntegerToIntegerInReg(Arg1Reg);
 	/* begin SubCq:R: */
 	genoperandoperand(SubCqR, 1, Arg1Reg);
@@ -17337,6 +17648,16 @@
 	return genoperand(JumpZero, ((sqInt)0));
 }
 
+	/* CogObjectRepresentationFor32BitSpur>>#genJumpNotSmallInteger: */
+static AbstractInstruction *
+genJumpNotSmallInteger(sqInt aRegister)
+{
+	/* begin TstCq:R: */
+	genoperandoperand(TstCqR, 1, aRegister);
+	/* begin JumpZero: */
+	return genoperand(JumpZero, ((sqInt)0));
+}
+
 	/* CogObjectRepresentationFor32BitSpur>>#genJumpSmallIntegerInScratchReg: */
 static AbstractInstruction *
 genJumpSmallIntegerInScratchReg(sqInt aRegister)
@@ -17347,7 +17668,17 @@
 	return genoperand(JumpNonZero, ((sqInt)0));
 }
 
+	/* CogObjectRepresentationFor32BitSpur>>#genJumpSmallInteger: */
+static AbstractInstruction *
+genJumpSmallInteger(sqInt aRegister)
+{
+	/* begin TstCq:R: */
+	genoperandoperand(TstCqR, 1, aRegister);
+	/* begin JumpNonZero: */
+	return genoperand(JumpNonZero, ((sqInt)0));
+}
 
+
 /*	Generate a call to code that allocates a new Array of size.
 	The Array should be initialized with nils iff initialized is true.
 	The size arg is passed in SendNumArgsReg, the result
@@ -17588,6 +17919,19 @@
 	return 0;
 }
 
+
+/*	Answer if the cacheTag is not unmarked, i.e. answer true for compact class
+	indices and immediates; only answer false for unmarked objects. In Spur
+	linked send cache tags are class indices so effectively they're always
+	marked.  */
+
+	/* CogObjectRepresentationForSpur>>#cacheTagIsMarked: */
+static sqInt
+cacheTagIsMarked(sqInt cacheTag)
+{
+	return 1;
+}
+
 	/* CogObjectRepresentationForSpur>>#checkValidOopReference: */
 static sqInt
 checkValidOopReference(sqInt anOop)
@@ -18031,6 +18375,17 @@
 }
 
 
+/*	Get the format field of the object in srcReg into destReg.
+	srcReg may equal destReg. */
+
+	/* CogObjectRepresentationForSpur>>#genGetFormatOf:into: */
+static sqInt
+genGetFormatOfinto(sqInt srcReg, sqInt destReg)
+{
+	return genGetBitsofFormatByteOfintobaseHeaderIntoScratch(formatMask(), srcReg, destReg, null);
+}
+
+
 /*	Get the format of the object in sourceReg into destReg. If scratchRegOrNil
 	is not nil, load at least the least significant 32-bits (64-bits in
 	64-bits) of the
@@ -18084,9 +18439,7 @@
     AbstractInstruction *jumpOutOfRange;
 
 	if (reg != ReceiverResultReg) {
-		/* begin MoveR:R: */
-		genoperandoperand(MoveRR, reg, TempReg);
-		jumpNotInt = genJumpNotSmallIntegerInScratchReg(TempReg);
+		jumpNotInt = genJumpNotSmallInteger(reg);
 	}
 	/* begin MoveR:R: */
 	genoperandoperand(MoveRR, reg, TempReg);
@@ -18127,9 +18480,7 @@
     AbstractInstruction *jumpCmp;
     AbstractInstruction *jumpImmediate;
 
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, Arg0Reg, TempReg);
-	jumpImmediate = genJumpImmediateInScratchReg(TempReg);
+	jumpImmediate = genJumpImmediate(Arg0Reg);
 	genEnsureObjInRegNotForwardedscratchReg(Arg0Reg, TempReg);
 	jmpTarget(jumpImmediate, gCmpRR(Arg0Reg, ReceiverResultReg));
 	if (orNot) {
@@ -18188,9 +18539,7 @@
     sqInt quickConstant4;
     sqInt quickConstant5;
 
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, ReceiverResultReg, TempReg);
-	jumpImm = genJumpImmediateInScratchReg(TempReg);
+	jumpImm = genJumpImmediate(ReceiverResultReg);
 	/* begin genGetSizeOf:into:formatReg:scratchReg:abortJumpsInto: */
 	genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(ReceiverResultReg, SendNumArgsReg, TempReg);
 	genGetNumSlotsOfinto(ReceiverResultReg, ClassReg);
@@ -18283,6 +18632,19 @@
 	return genoperand(JumpNonZero, ((sqInt)0));
 }
 
+	/* CogObjectRepresentationForSpur>>#genJumpImmediate: */
+static AbstractInstruction *
+genJumpImmediate(sqInt aRegister)
+{
+    sqInt quickConstant;
+
+	/* begin TstCq:R: */
+	quickConstant = tagMask();
+	genoperandoperand(TstCqR, quickConstant, aRegister);
+	/* begin JumpNonZero: */
+	return genoperand(JumpNonZero, ((sqInt)0));
+}
+
 	/* CogObjectRepresentationForSpur>>#genJumpNotCharacterInScratchReg: */
 static AbstractInstruction *
 genJumpNotCharacterInScratchReg(sqInt reg)
@@ -23226,9 +23588,14 @@
 genPrimitiveClosureValue(void)
 {
     AbstractInstruction *jumpBCMethod;
-    AbstractInstruction *jumpFail;
+    AbstractInstruction * jumpFail1;
+    AbstractInstruction *jumpFail2;
+    AbstractInstruction *jumpFail3;
+    AbstractInstruction *jumpFail4;
+    AbstractInstruction *jumpFailNArgs;
     sqInt offset;
     void (*primitiveRoutine)();
+    sqInt quickConstant;
     sqInt result;
 
 	genPushRegisterArgs();
@@ -23236,13 +23603,23 @@
 	/* begin CmpCq:R: */
 	genoperandoperand(CmpCqR, ((methodOrBlockNumArgs << 1) | 1), TempReg);
 	/* begin JumpNonZero: */
-	jumpFail = genoperand(JumpNonZero, ((sqInt)0));
+	jumpFailNArgs = genoperand(JumpNonZero, ((sqInt)0));
 	genLoadSlotsourceRegdestReg(ClosureOuterContextIndex, ReceiverResultReg, ClassReg);
+	jumpFail1 = genJumpImmediate(ClassReg);
+	genGetCompactClassIndexNonImmOfinto(ClassReg, TempReg);
+	genCmpClassMethodContextCompactIndexR(TempReg);
+	/* begin JumpNonZero: */
+	jumpFail2 = genoperand(JumpNonZero, ((sqInt)0));
 	genLoadSlotsourceRegdestReg(MethodIndex, ClassReg, SendNumArgsReg);
-	genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, TempReg);
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, TempReg, ClassReg);
-	jumpBCMethod = genJumpSmallIntegerInScratchReg(TempReg);
+	jumpFail3 = genJumpImmediate(SendNumArgsReg);
+	genGetFormatOfinto(SendNumArgsReg, TempReg);
+	/* begin CmpCq:R: */
+	quickConstant = firstCompiledMethodFormat();
+	genoperandoperand(CmpCqR, quickConstant, TempReg);
+	/* begin JumpLess: */
+	jumpFail4 = genoperand(JumpLess, ((sqInt)0));
+	genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg);
+	jumpBCMethod = genJumpSmallInteger(ClassReg);
 	/* begin MoveM16:r:R: */
 	offset = offsetof(CogMethod, blockEntryOffset);
 	genoperandoperandoperand(MoveM16rR, offset, ClassReg, TempReg);
@@ -23258,11 +23635,11 @@
 	}
 	/* begin JumpR: */
 	genoperand(JumpR, TempReg);
-	jmpTarget(jumpBCMethod, gLabel());
+	jmpTarget(jumpBCMethod, jmpTarget(jumpFail1, jmpTarget(jumpFail2, jmpTarget(jumpFail3, jmpTarget(jumpFail4, gLabel())))));
 	if (((result = compileInterpreterPrimitive(primitiveRoutine))) < 0) {
 		return result;
 	}
-	jmpTarget(jumpFail, gLabel());
+	jmpTarget(jumpFailNArgs, gLabel());
 	return 0;
 }
 

Modified: branches/Cog/nsspursrc/vm/cogitIA32.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogitIA32.c	2015-05-27 21:12:31 UTC (rev 3361)
+++ branches/Cog/nsspursrc/vm/cogitIA32.c	2015-05-30 19:26:33 UTC (rev 3362)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5
+	CCodeGenerator VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1329 uuid: d25444c7-af99-40e1-ab8a-a765c046eae5 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1331 uuid: 2da6f9fc-7921-4c8b-8c78-dd47f9ddd76e " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -352,7 +352,8 @@
 #define SubRdRd 111
 #define SubRR 89
 #define TempReg -4
-#define UnfailingPrimitive 2
+#define TstCqR 114
+#define UnfailingPrimitive 3
 #define UnimplementedPrimitive -7
 #define ValueIndex 1
 #define VarBaseReg -20
@@ -527,6 +528,7 @@
 sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes);
 static sqInt checkMaybeObjRefAt(sqInt mcpc) NoDbgRegParms;
 static sqInt checkValidObjectReferencesInClosedPIC(CogMethod *cPIC) NoDbgRegParms;
+static sqInt closedPICRefersToUnmarkedObject(CogMethod *cPIC) NoDbgRegParms;
 char * codeEntryFor(char *address);
 char * codeEntryNameFor(char *address);
 sqInt cogCodeBase(void);
@@ -646,6 +648,8 @@
 void mapObjectReferencesInMachineCode(sqInt gcMode);
 void markAndTraceMachineCodeOfMarkedMethods(void);
 static void markAndTraceObjectReferencesInGeneratedRuntime(void);
+static sqInt markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) NoDbgRegParms;
+static sqInt markLiteralsAndUnlinkIfUnmarkedSendpcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) NoDbgRegParms;
 static sqInt markLiteralspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) NoDbgRegParms;
 void markMethodAndReferents(CogBlockMethod *aCogMethod);
 usqInt maxCogMethodAddress(void);
@@ -750,6 +754,7 @@
 char * whereIsMaybeCodeThing(sqInt anOop);
 static sqInt checkValidObjectReference(sqInt anOop) NoDbgRegParms;
 static AbstractInstruction * genCmpClassFloatCompactIndexR(sqInt reg) NoDbgRegParms;
+static AbstractInstruction * genCmpClassMethodContextCompactIndexR(sqInt reg) NoDbgRegParms;
 static sqInt genInnerPrimitiveNewMethod(sqInt retNoffset) NoDbgRegParms;
 static sqInt isUnannotatableConstant(CogSimStackEntry *simStackEntry) NoDbgRegParms;
 static sqInt genAddSmallIntegerTagsTo(sqInt aRegister) NoDbgRegParms;
@@ -777,7 +782,9 @@
 static sqInt genInnerPrimitiveStringAtPut(sqInt retNoffset) NoDbgRegParms;
 static sqInt genInnerPrimitiveStringAt(sqInt retNoffset) NoDbgRegParms;
 static AbstractInstruction * genJumpNotSmallIntegerInScratchReg(sqInt aRegister) NoDbgRegParms;
+static AbstractInstruction * genJumpNotSmallInteger(sqInt aRegister) NoDbgRegParms;
 static AbstractInstruction * genJumpSmallIntegerInScratchReg(sqInt aRegister) NoDbgRegParms;
+static AbstractInstruction * genJumpSmallInteger(sqInt aRegister) NoDbgRegParms;
 static sqInt genNewArrayOfSizeinitialized(sqInt size, sqInt initialized) NoDbgRegParms;
 static sqInt genNoPopCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) NoDbgRegParms;
 static sqInt genRemoveSmallIntegerTagsInScratchReg(sqInt scratchReg) NoDbgRegParms;
@@ -791,6 +798,7 @@
 static sqInt numSmallIntegerTagBits(void);
 static sqInt validInlineCacheTag(usqInt classIndexOrTagPattern) NoDbgRegParms;
 static sqInt allYoungObjectsAgeInFullGC(void);
+static sqInt cacheTagIsMarked(sqInt cacheTag) NoDbgRegParms;
 static sqInt checkValidOopReference(sqInt anOop) NoDbgRegParms;
 static sqInt couldBeObject(sqInt literal) NoDbgRegParms;
 static sqInt createsClosuresInline(void);
@@ -810,6 +818,7 @@
 static sqInt genGetClassObjectOfintoscratchReginstRegIsReceiver(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt instRegIsReceiver) NoDbgRegParms;
 static sqInt genGetCompactClassIndexNonImmOfinto(sqInt instReg, sqInt destReg) NoDbgRegParms;
 static sqInt genGetDoubleValueOfinto(sqInt srcReg, sqInt destFPReg) NoDbgRegParms;
+static sqInt genGetFormatOfinto(sqInt srcReg, sqInt destReg) NoDbgRegParms;
 static sqInt genGetFormatOfintoleastSignificantHalfOfBaseHeaderIntoScratch(sqInt sourceReg, sqInt destReg, sqInt scratchRegOrNil) NoDbgRegParms;
 static sqInt genGetRawSlotSizeOfNonImminto(sqInt sourceReg, sqInt destReg) NoDbgRegParms;
 static sqInt genInnerPrimitiveAsCharacterinReg(sqInt retNOffset, sqInt reg) NoDbgRegParms;
@@ -817,6 +826,7 @@
 static sqInt genInnerPrimitiveIdenticalorNotIf(sqInt retNoffset, sqInt orNot) NoDbgRegParms;
 static sqInt genInnerPrimitiveSize(sqInt retNoffset) NoDbgRegParms;
 static AbstractInstruction * genJumpImmediateInScratchReg(sqInt aRegister) NoDbgRegParms;
+static AbstractInstruction * genJumpImmediate(sqInt aRegister) NoDbgRegParms;
 static AbstractInstruction * genJumpNotCharacterInScratchReg(sqInt reg) NoDbgRegParms;
 static sqInt genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) NoDbgRegParms;
 static sqInt genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) NoDbgRegParms;
@@ -2353,6 +2363,14 @@
 					? 5
 					: 6)));
 
+	case TstCqR:
+		return ((self_in_computeMaximumSize->maxSize) = ((isQuick(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0]))
+		 && ((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[1])) < 4)
+			? 3
+			: ((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[1])) == EAX
+					? 5
+					: 6)));
+
 	case AddCwR:
 	case AndCwR:
 	case CmpCwR:
@@ -2766,6 +2784,7 @@
     AbstractInstruction *jumpTarget9;
     unsigned long mask;
     unsigned long mask1;
+    unsigned long mask2;
     sqInt mcIdx;
     unsigned long offset;
     unsigned long offset1;
@@ -2832,6 +2851,7 @@
     sqInt reg23;
     sqInt reg24;
     sqInt reg25;
+    sqInt reg26;
     sqInt reg3;
     sqInt reg4;
     sqInt reg5;
@@ -4011,18 +4031,48 @@
 		((self_in_dispatchConcretize->machineCodeSize) = 2);
 		return;
 
+	case TstCqR:
+		/* begin concretizeTstCqR */
+		mask1 = ((self_in_dispatchConcretize->operands))[0];
+		reg9 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		if ((isQuick(self_in_dispatchConcretize, mask1))
+		 && (reg9 < 4)) {
+			((self_in_dispatchConcretize->machineCode))[0] = 246;
+			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg9, 0));
+			((self_in_dispatchConcretize->machineCode))[2] = (mask1 & 0xFF);
+			((self_in_dispatchConcretize->machineCodeSize) = 3);
+			return;
+		}
+		if (reg9 == EAX) {
+			((self_in_dispatchConcretize->machineCode))[0] = 169;
+			((self_in_dispatchConcretize->machineCode))[1] = (mask1 & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) mask1) >> 8) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) mask1) >> 16) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) mask1) >> 24) & 0xFF);
+			((self_in_dispatchConcretize->machineCodeSize) = 5);
+			return;
+		}
+		((self_in_dispatchConcretize->machineCode))[0] = 247;
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg9, 0));
+		((self_in_dispatchConcretize->machineCode))[2] = (mask1 & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) mask1) >> 8) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) mask1) >> 16) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) mask1) >> 24) & 0xFF);
+		((self_in_dispatchConcretize->machineCodeSize) = 6);
+		return;
+
 	case CmpCqR:
 		/* begin concretizeCmpCqR */
 		value3 = ((self_in_dispatchConcretize->operands))[0];
-		reg9 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		reg10 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
 		if (isQuick(self_in_dispatchConcretize, value3)) {
 			((self_in_dispatchConcretize->machineCode))[0] = 131;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg9, 7));
+			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg10, 7));
 			((self_in_dispatchConcretize->machineCode))[2] = (value3 & 0xFF);
 			((self_in_dispatchConcretize->machineCodeSize) = 3);
 			return;
 		}
-		if (reg9 == EAX) {
+		if (reg10 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 61;
 			((self_in_dispatchConcretize->machineCode))[1] = (value3 & 0xFF);
 			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) value3) >> 8) & 0xFF);
@@ -4032,7 +4082,7 @@
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 129;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg9, 7));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg10, 7));
 		((self_in_dispatchConcretize->machineCode))[2] = (value3 & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) value3) >> 8) & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) value3) >> 16) & 0xFF);
@@ -4043,8 +4093,8 @@
 	case CmpCwR:
 		/* begin concretizeCmpCwR */
 		value4 = ((self_in_dispatchConcretize->operands))[0];
-		reg10 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
-		if (reg10 == EAX) {
+		reg12 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		if (reg12 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 61;
 			((self_in_dispatchConcretize->machineCode))[1] = (value4 & 0xFF);
 			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) value4) >> 8) & 0xFF);
@@ -4054,7 +4104,7 @@
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 129;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg10, 7));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg12, 7));
 		((self_in_dispatchConcretize->machineCode))[2] = (value4 & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) value4) >> 8) & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) value4) >> 16) & 0xFF);
@@ -4106,38 +4156,38 @@
 
 	case OrCqR:
 		/* begin concretizeOrCqR */
-		mask1 = ((self_in_dispatchConcretize->operands))[0];
-		reg12 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
-		if (isQuick(self_in_dispatchConcretize, mask1)) {
+		mask2 = ((self_in_dispatchConcretize->operands))[0];
+		reg13 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		if (isQuick(self_in_dispatchConcretize, mask2)) {
 			((self_in_dispatchConcretize->machineCode))[0] = 131;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg12, 1));
-			((self_in_dispatchConcretize->machineCode))[2] = (mask1 & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg13, 1));
+			((self_in_dispatchConcretize->machineCode))[2] = (mask2 & 0xFF);
 			((self_in_dispatchConcretize->machineCodeSize) = 3);
 			return;
 		}
-		if (reg12 == EAX) {
+		if (reg13 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 13;
-			((self_in_dispatchConcretize->machineCode))[1] = (mask1 & 0xFF);
-			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) mask1) >> 8) & 0xFF);
-			((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) mask1) >> 16) & 0xFF);
-			((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) mask1) >> 24) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[1] = (mask2 & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) mask2) >> 8) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) mask2) >> 16) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) mask2) >> 24) & 0xFF);
 			((self_in_dispatchConcretize->machineCodeSize) = 5);
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 129;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg12, 1));
-		((self_in_dispatchConcretize->machineCode))[2] = (mask1 & 0xFF);
-		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) mask1) >> 8) & 0xFF);
-		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) mask1) >> 16) & 0xFF);
-		((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) mask1) >> 24) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg13, 1));
+		((self_in_dispatchConcretize->machineCode))[2] = (mask2 & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) mask2) >> 8) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) mask2) >> 16) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) mask2) >> 24) & 0xFF);
 		((self_in_dispatchConcretize->machineCodeSize) = 6);
 		return;
 
 	case OrCwR:
 		/* begin concretizeOrCwR */
 		value5 = ((self_in_dispatchConcretize->operands))[0];
-		reg13 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
-		if (reg13 == EAX) {
+		reg14 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		if (reg14 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 13;
 			((self_in_dispatchConcretize->machineCode))[1] = (value5 & 0xFF);
 			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) value5) >> 8) & 0xFF);
@@ -4147,7 +4197,7 @@
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 131;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg13, 1));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg14, 1));
 		((self_in_dispatchConcretize->machineCode))[2] = (value5 & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) value5) >> 8) & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) value5) >> 16) & 0xFF);
@@ -4167,15 +4217,15 @@
 	case SubCqR:
 		/* begin concretizeSubCqR */
 		value6 = ((self_in_dispatchConcretize->operands))[0];
-		reg14 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		reg15 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
 		if (isQuick(self_in_dispatchConcretize, value6)) {
 			((self_in_dispatchConcretize->machineCode))[0] = 131;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg14, 5));
+			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg15, 5));
 			((self_in_dispatchConcretize->machineCode))[2] = (value6 & 0xFF);
 			((self_in_dispatchConcretize->machineCodeSize) = 3);
 			return;
 		}
-		if (reg14 == EAX) {
+		if (reg15 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 45;
 			((self_in_dispatchConcretize->machineCode))[1] = (value6 & 0xFF);
 			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) value6) >> 8) & 0xFF);
@@ -4185,7 +4235,7 @@
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 129;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg14, 5));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg15, 5));
 		((self_in_dispatchConcretize->machineCode))[2] = (value6 & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) value6) >> 8) & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) value6) >> 16) & 0xFF);
@@ -4196,8 +4246,8 @@
 	case SubCwR:
 		/* begin concretizeSubCwR */
 		value7 = ((self_in_dispatchConcretize->operands))[0];
-		reg15 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
-		if (reg15 == EAX) {
+		reg16 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		if (reg16 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 45;
 			((self_in_dispatchConcretize->machineCode))[1] = (value7 & 0xFF);
 			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) value7) >> 8) & 0xFF);
@@ -4207,7 +4257,7 @@
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 129;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg15, 5));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg16, 5));
 		((self_in_dispatchConcretize->machineCode))[2] = (value7 & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) value7) >> 8) & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) value7) >> 16) & 0xFF);
@@ -4237,19 +4287,19 @@
 
 	case SqrtRd:
 		/* begin concretizeSqrtRd */
-		reg16 = concreteDPFPRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[0]);
+		reg17 = concreteDPFPRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[0]);
 		((self_in_dispatchConcretize->machineCode))[0] = 242;
 		((self_in_dispatchConcretize->machineCode))[1] = 15;
 		((self_in_dispatchConcretize->machineCode))[2] = 81;
-		((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, reg16, reg16));
+		((self_in_dispatchConcretize->machineCode))[3] = (modRMRO(self_in_dispatchConcretize, ModReg, reg17, reg17));
 		((self_in_dispatchConcretize->machineCodeSize) = 4);
 		return;
 
 	case XorCwR:
 		/* begin concretizeXorCwR */
 		value8 = ((self_in_dispatchConcretize->operands))[0];
-		reg17 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
-		if (reg17 == EAX) {
+		reg18 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		if (reg18 == EAX) {
 			((self_in_dispatchConcretize->machineCode))[0] = 53;
 			((self_in_dispatchConcretize->machineCode))[1] = (value8 & 0xFF);
 			((self_in_dispatchConcretize->machineCode))[2] = ((((usqInt) value8) >> 8) & 0xFF);
@@ -4259,7 +4309,7 @@
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 129;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg17, 6));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg18, 6));
 		((self_in_dispatchConcretize->machineCode))[2] = (value8 & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) value8) >> 8) & 0xFF);
 		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) value8) >> 16) & 0xFF);
@@ -4278,9 +4328,9 @@
 
 	case NegateR:
 		/* begin concretizeNegateR */
-		reg18 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[0]);
+		reg19 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[0]);
 		((self_in_dispatchConcretize->machineCode))[0] = 247;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg18, 3));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg19, 3));
 		((self_in_dispatchConcretize->machineCodeSize) = 2);
 		return;
 
@@ -4327,15 +4377,15 @@
 	case ArithmeticShiftRightCqR:
 		/* begin concretizeArithmeticShiftRightCqR */
 		shiftCount = (((((self_in_dispatchConcretize->operands))[0]) < 0x1F) ? (((self_in_dispatchConcretize->operands))[0]) : 0x1F);
-		reg19 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		reg20 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
 		if (shiftCount == 1) {
 			((self_in_dispatchConcretize->machineCode))[0] = 209;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg19, 7));
+			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg20, 7));
 			((self_in_dispatchConcretize->machineCodeSize) = 2);
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 193;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg19, 7));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg20, 7));
 		((self_in_dispatchConcretize->machineCode))[2] = shiftCount;
 		((self_in_dispatchConcretize->machineCodeSize) = 3);
 		return;
@@ -4343,15 +4393,15 @@
 	case LogicalShiftRightCqR:
 		/* begin concretizeLogicalShiftRightCqR */
 		distance = (((((self_in_dispatchConcretize->operands))[0]) < 0x1F) ? (((self_in_dispatchConcretize->operands))[0]) : 0x1F);
-		reg20 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		reg22 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
 		if (distance == 1) {
 			((self_in_dispatchConcretize->machineCode))[0] = 209;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg20, 5));
+			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg22, 5));
 			((self_in_dispatchConcretize->machineCodeSize) = 2);
 			return;
 		}
 		((self_in_dispatchConcretize->machineCode))[0] = 193;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg20, 5));
+		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModReg, reg22, 5));
 		((self_in_dispatchConcretize->machineCode))[2] = distance;
 		((self_in_dispatchConcretize->machineCodeSize) = 3);
 		return;
@@ -4359,15 +4409,15 @@
 	case LogicalShiftLeftCqR:
 		/* begin concretizeLogicalShiftLeftCqR */
 		distance1 = (((((self_in_dispatchConcretize->operands))[0]) < 0x1F) ? (((self_in_dispatchConcretize->operands))[0]) : 0x1F);
-		reg22 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
+		reg23 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
 		if (distance1 == 1) {

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list