[Vm-dev] [commit][2765] CogVM source as per VMMaker.oscog-eem.321

commits at squeakvm.org commits at squeakvm.org
Thu Aug 15 00:03:30 UTC 2013


Revision: 2765
Author:   eliot
Date:     2013-08-14 17:03:27 -0700 (Wed, 14 Aug 2013)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.321

Make primitiveObjectAtPut fail if changing the header word and the
new header has a different literal count.  Avoids crashing the VM
when inadvertently changing the header, as a Newspeak bootstrap
did recently.

Implement frameless inst var store from arguments, so e.g.
Point>>setX:Y: is frameless.

Add Cogit support for clean blocks by scanning literals looking for
BlockClosures on the current method.

Add a prevBCDescriptor to the StackToRegisterMappingCogit
scanners.  This enables needsFrameIfFollowsSend:.

Avoid spilling in frameless methods (now that pushTempVar can be frameless and
hence inst var setters such at setX:Y: are now frameless) by adding
needsFrameIfFollowsSend: used for special selectors #class & #==.

Modified Paths:
--------------
    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/Mac OS/vm/sqMacMain.c
    branches/Cog/platforms/Mac OS/vm/sqMacMemory.c
    branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c
    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

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

Modified: branches/Cog/nscogsrc/vm/cogit.c
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/cogit.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb
+	CCodeGenerator VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb
+	StackToRegisterMappingCogit VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -360,6 +360,7 @@
 static sqInt abstractInstructionfollows(AbstractInstruction *theAbstractInstruction, AbstractInstruction *anAbstractInstruction);
 static sqInt abstractRegisterForConcreteRegister(AbstractInstruction * self_in_abstractRegisterForConcreteRegister, sqInt reg);
 static BlockStart * addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span);
+static void addCleanBlockStarts(void);
 void addCogMethodsToHeapMap(void);
 static AbstractInstruction * addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction);
 static sqInt addressIsInFixups(AbstractInstruction *address);
@@ -627,6 +628,7 @@
 static sqInt genFastPrimFail(void);
 static void genFastPrimTraceUsingand(sqInt r1, sqInt r2);
 static sqInt genFetchIndexRegisterfrominto(sqInt indexReg, sqInt tableObj, sqInt destReg);
+static sqInt genFramelessStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex);
 static sqInt genGetClassFormatOfNonIntintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg);
 static sqInt genGetClassObjectOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg);
 static sqInt genGetCompactClassIndexNonIntOfinto(sqInt instReg, sqInt destReg);
@@ -681,6 +683,7 @@
 static sqInt genPrimitiveBitOr(void);
 static sqInt genPrimitiveBitShift(void);
 static sqInt genPrimitiveBitXor(void);
+static sqInt genPrimitiveClass(void);
 static sqInt genPrimitiveClosureValue(void);
 static sqInt genPrimitiveDiv(void);
 static sqInt genPrimitiveDivide(void);
@@ -915,7 +918,9 @@
 sqInt mnuOffset(void);
 static sqInt modRMRO(AbstractInstruction * self_in_modRMRO, sqInt mod, sqInt regMode, sqInt regOpcode);
 static AbstractInstruction * gNegateR(sqInt reg);
+static sqInt needsFrameIfFollowsSend(sqInt isInBlock);
 static sqInt needsFrameIfInBlock(sqInt isInBlock);
+static sqInt needsFrameIfMod16GENumArgs(sqInt isInBlock);
 static sqInt needsFrameNever(sqInt isInBlock);
 static sqInt noAssertMethodClassAssociationOf(sqInt methodPointer);
 static sqInt noCogMethodsMaximallyMarked(void);
@@ -988,6 +993,7 @@
 static AbstractInstruction * gSubCqR(sqInt quickConstant, sqInt reg);
 static AbstractInstruction * gSubCwR(sqInt wordConstant, sqInt reg);
 static void scanBlock(BlockStart *blockStart);
+static sqInt scanForCleanBlocks(void);
 static sqInt scanMethod(void);
 void setBreakMethod(sqInt anObj);
 static sqInt setLabelOffset(AbstractInstruction * self_in_setLabelOffset, sqInt aValue);
@@ -1000,6 +1006,7 @@
 static sqInt sizeImmediateGroup1at(AbstractInstruction * self_in_sizeImmediateGroup1at, sqInt op, sqInt pc);
 static sqInt sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress);
 static sqInt slotOffsetOfInstVarIndex(sqInt index);
+static sqInt spanForCleanBlockStartingAt(sqInt startPC);
 static void ssAllocateCallReg(sqInt requiredReg);
 static void ssAllocateCallRegand(sqInt requiredReg1, sqInt requiredReg2);
 static void ssAllocateCallRegandandand(sqInt requiredReg1, sqInt requiredReg2, sqInt requiredReg3, sqInt requiredReg4);
@@ -1166,22 +1173,22 @@
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
@@ -1348,8 +1355,8 @@
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genSpecialSelectorClass, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genSpecialSelectorEqualsEquals, 0, needsFrameIfFollowsSend, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genSpecialSelectorClass, 0, needsFrameIfFollowsSend, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
@@ -1470,18 +1477,18 @@
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushReceiverBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genExtPushPseudoVariableOrOuterBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushConstantZeroBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
@@ -1508,8 +1515,8 @@
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genSpecialSelectorClass, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genSpecialSelectorEqualsEquals, 0, needsFrameIfFollowsSend, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genSpecialSelectorClass, 0, needsFrameIfFollowsSend, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
@@ -1697,6 +1704,7 @@
 static sqInt picAbortTrampolines[4];
 static sqInt picMissTrampolines[4];
 static void (*postCompileHook)(CogMethod *, void *);
+static BytecodeDescriptor * prevBCDescriptor;
 static AbstractInstruction * primInvokeLabel;
 static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = {
 	{ 0, -1, 0 },
@@ -1810,6 +1818,7 @@
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
 	{ genPrimitiveEquivalent, 1, 0 },
+	{ genPrimitiveClass, -1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
@@ -1867,7 +1876,6 @@
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
-	{ 0, -1, 0 },
 	{ genPrimitiveNotEquivalent, 1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
@@ -1949,7 +1957,7 @@
 /*** Macros ***/
 #define abstractInstructionAt(index) (&abstractOpcodes[index])
 #define allocateBlockStarts(numBlocks) do { \
-		blockStarts = numBlocks ? alloca(sizeof(BlockStart) * numBlocks) : 0; \
+		blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \
 } while (0)
 #define allocateOpcodesbytecodes(numberOfAbstractOpcodes,numberOfBytecodes) do { \
 		int opcodeSize = sizeof(AbstractInstruction) * (numAbstractOpcodes = (numberOfAbstractOpcodes)); \
@@ -2136,7 +2144,27 @@
 	return blockStart;
 }
 
+static void
+addCleanBlockStarts(void)
+{
+    sqInt i;
+    sqInt iLimiT;
+    sqInt lit;
+    sqInt startPCOrNil;
 
+	for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) {
+		lit = fetchPointerofObject(i, methodObj);
+		if (((startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj))) == null) {
+			null;
+		}
+		else {
+			maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex);
+			addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1));
+		}
+	}
+}
+
+
 /*	Perform an integrity/leak check using the heapMap.
 	Set a bit at each cog method's header. */
 
@@ -4161,6 +4189,7 @@
     sqInt extra;
     sqInt numBlocks;
     sqInt numBytecodes;
+    sqInt numCleanBlocks;
     sqInt result;
 
 	methodOrBlockNumTemps = tempCountOf(methodObj);
@@ -4188,7 +4217,13 @@
 	if (((numBlocks = scanMethod())) < 0) {
 		return ((CogMethod *) numBlocks);
 	}
-	allocateBlockStarts(numBlocks);
+	numCleanBlocks = scanForCleanBlocks();
+	allocateBlockStarts(numBlocks + numCleanBlocks);
+	blockCount = 0;
+	if (numCleanBlocks > 0) {
+		addCleanBlockStarts();
+	}
+	/* begin maybeAllocAndInitCounters */
 	blockEntryLabel = null;
 	(methodLabel->dependent = null);
 	if (((result = compileEntireMethod())) < 0) {
@@ -4288,7 +4323,6 @@
 		return result;
 	}
 	compileFrameBuild();
-	blockCount = 0;
 	if (((result = compileMethodBody())) < 0) {
 		return result;
 	}
@@ -9919,7 +9953,44 @@
 	return 0;
 }
 
+static sqInt
+genFramelessStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex)
+{
+    sqInt constVal;
+    sqInt topReg;
+    sqInt valueReg;
 
+	assert(!needsFrame);
+	ssFlushUpThroughReceiverVariable(slotIndex);
+	constVal = maybeConstant(ssTop());
+	if ((((ssTop()->type)) == SSConstant)
+	 && (!(shouldAnnotateObjectReference(constVal)))) {
+		ensureReceiverResultRegContainsSelf();
+		ssStorePoptoPreferredReg(popBoolean, TempReg);
+		if (traceStores > 0) {
+			CallRT(ceTraceStoreTrampoline);
+		}
+		return genStoreImmediateInSourceRegslotIndexdestReg(TempReg, slotIndex, ReceiverResultReg);
+	}
+	topReg = ClassReg;
+	ssPop(1);
+	ssAllocateCallReg(topReg);
+	ssPush(1);
+	valueReg = ssStorePoptoPreferredReg(popBoolean, topReg);
+	if (valueReg != topReg) {
+		/* begin MoveR:R: */
+		genoperandoperand(MoveRR, valueReg, topReg);
+	}
+	ensureReceiverResultRegContainsSelf();
+	if (traceStores > 0) {
+		/* begin MoveR:R: */
+		genoperandoperand(MoveRR, topReg, TempReg);
+		CallRT(ceTraceStoreTrampoline);
+	}
+	return genStoreSourceRegslotIndexdestRegscratchReg(topReg, slotIndex, ReceiverResultReg, TempReg);
+}
+
+
 /*	Fetch the instance's class format into destReg, assuming the object is
 	non-int. 
  */
@@ -11283,7 +11354,16 @@
 	return 0;
 }
 
+static sqInt
+genPrimitiveClass(void)
+{
+	genGetClassObjectOfintoscratchReg(ReceiverResultReg, ReceiverResultReg, TempReg);
+	/* begin RetN: */
+	genoperand(RetN, 0);
+	return 0;
+}
 
+
 /*	Check the argument count. Fail if wrong.
 	Get the method from the outerContext and see if it is cogged. If so, jump
 	to the
@@ -13314,6 +13394,9 @@
     sqInt topReg;
     sqInt valueReg;
 
+	if (!needsFrame) {
+		return genFramelessStorePopReceiverVariable(popBoolean, slotIndex);
+	}
 	ssFlushUpThroughReceiverVariable(slotIndex);
 	constVal = maybeConstant(ssTop());
 	if ((((ssTop()->type)) == SSConstant)
@@ -15995,13 +16078,41 @@
 	return genoperand(NegateR, reg);
 }
 
+
+/*	As of August 2013, the code generator can't deal with spills in frameless
+	methods (the
+	issue is to do with the stack offset to get at an argument, which is
+	changed when there's a spill).
+	The only context in a spill is needed in a frameless method that I can
+	think of is sends
+	following sends as in e.g. TextColor>>#dominates: other ^other class ==
+	self class.
+	Only need to check for the frameless sends since all other sends will
+	force a frame.
+ */
+
 static sqInt
+needsFrameIfFollowsSend(sqInt isInBlock)
+{
+	assert((prevBCDescriptor != null)
+	 && (((prevBCDescriptor->needsFrameFunction)) != null));
+	return (((prevBCDescriptor->generator)) == genSpecialSelectorEqualsEquals)
+	 || (((prevBCDescriptor->generator)) == genSpecialSelectorClass);
+}
+
+static sqInt
 needsFrameIfInBlock(sqInt isInBlock)
 {
 	return inBlock;
 }
 
 static sqInt
+needsFrameIfMod16GENumArgs(sqInt isInBlock)
+{
+	return (byte0 % 16) >= methodOrBlockNumArgs;
+}
+
+static sqInt
 needsFrameNever(sqInt isInBlock)
 {
 	return 0;
@@ -17346,6 +17457,7 @@
     sqInt stackDelta;
 
 	needsFrame = 0;
+	prevBCDescriptor = null;
 	methodOrBlockNumArgs = (blockStart->numArgs);
 	nExts = 0;
 	pc = (blockStart->startpc);
@@ -17385,6 +17497,7 @@
 		nExts = ((descriptor->isExtension)
 			? nExts + 1
 			: 0);
+		prevBCDescriptor = descriptor;
 	}
 	if (!needsFrame) {
 		assert((stackDelta >= 0)
@@ -17394,6 +17507,31 @@
 }
 
 
+/*	Answer the number of clean blocks found in the literal frame */
+
+static sqInt
+scanForCleanBlocks(void)
+{
+    sqInt i;
+    sqInt iLimiT;
+    sqInt lit;
+    sqInt numCleanBlocks;
+    sqInt startPCOrNil;
+
+	numCleanBlocks = 0;
+	for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) {
+		lit = fetchPointerofObject(i, methodObj);
+		if (((startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj))) == null) {
+			null;
+		}
+		else {
+			numCleanBlocks += 1;
+		}
+	}
+	return numCleanBlocks;
+}
+
+
 /*	Scan the method to determine
 	- what the last bytecode is; extra bytes at the end of a method are used
 	to encode things like source pointers or temp names
@@ -17414,6 +17552,7 @@
     sqInt targetPC;
 
 	needsFrame = 0;
+	prevBCDescriptor = null;
 	if ((primitiveIndex > 0)
 	 && (isQuickPrimitiveIndex(primitiveIndex))) {
 		return 0;
@@ -17453,6 +17592,7 @@
 		nExts = ((descriptor->isExtension)
 			? nExts + 1
 			: 0);
+		prevBCDescriptor = descriptor;
 	}
 	return numBlocks;
 }
@@ -17675,7 +17815,27 @@
 	return (index * BytesPerWord) + BaseHeaderSize;
 }
 
+static sqInt
+spanForCleanBlockStartingAt(sqInt startPC)
+{
+    BytecodeDescriptor *descriptor;
+    sqInt end;
+    sqInt pc;
 
+	pc = startPC;
+	end = byteLengthOf(methodObj);
+	while (pc <= end) {
+		descriptor = generatorAt((fetchByteofObject(pc, methodObj)) + bytecodeSetOffset);
+		pc += (descriptor->numBytes);
+		if ((descriptor->isReturn)) {
+			return pc - startPC;
+		}
+	}
+	error("couldn't locate end of clean block");
+	return 0;
+}
+
+
 /*	Allocate a register needed in a run-time call (i.e. flush uses of the
 	register to the real stack). Since the run-time can smash any and
 	all caller-saved registers also flush all caller-saved registers. */

Modified: branches/Cog/nscogsrc/vm/cogit.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogit.h	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/cogit.h	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb
+	CCodeGenerator VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
 
 

Modified: branches/Cog/nscogsrc/vm/cogmethod.h
===================================================================
--- branches/Cog/nscogsrc/vm/cogmethod.h	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/cogmethod.h	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb
+	CCodeGenerator VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
 
 typedef struct {

Modified: branches/Cog/nscogsrc/vm/cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/cointerp.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
    from
-	CoInterpreter VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CoInterpreter VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -159,6 +159,7 @@
 #define ClassPoint 12
 #define ClassSemaphore 18
 #define ClassUnsafeAlien 54
+#define ClosureCopiedValuesIndex 3
 #define ClosureFirstCopiedValueIndex 3
 #define ClosureIndex 4
 #define ClosureNumArgsIndex 2
@@ -364,6 +365,7 @@
 static char * allocateMemoryminimumimageFileheaderSize(sqInt heapSize, sqInt minimumMemory, sqImageFile fileStream, sqInt headerSize);
 static sqInt allYoungand(sqInt array1, sqInt array2);
 usqInt argumentCountAddress(void);
+sqInt argumentCountOfClosure(sqInt closurePointer);
 sqInt argumentCountOfMethodHeader(sqInt header);
 sqInt argumentCountOf(sqInt methodPointer);
 void * arrayValueOf(sqInt arrayOop);
@@ -477,6 +479,7 @@
 static sqInt contextInstructionPointerframe(sqInt theIP, char *theFP);
 static sqInt contexthasSender(sqInt thisCntx, sqInt aContext);
 static sqInt contexthasValidInversePCMappingOfin(sqInt aContext, sqInt theIP, char *theFP);
+sqInt copiedValueCountOfClosure(sqInt closurePointer);
 sqInt copyBits(void);
 sqInt copyBitsFromtoat(sqInt x0, sqInt x1, sqInt y);
 static sqInt copyObjtoSegmentaddrstopAtsaveOopAtheaderAt(sqInt oop, sqInt segmentWordArray, sqInt lastSeg, sqInt stopAddr, sqInt oopPtr, sqInt hdrPtr);
@@ -1171,6 +1174,7 @@
 void * startOfAlienData(sqInt oop);
 sqInt startPCOfMethodHeader(sqInt aCompiledMethodHeader);
 sqInt startPCOfMethod(sqInt aCompiledMethod);
+sqInt startPCOrNilOfLiteralin(sqInt lit, sqInt aMethodObj);
 sqInt stObjectat(sqInt array, sqInt index);
 sqInt stObjectatput(sqInt array, sqInt index, sqInt value);
 static sqInt storeImageSegmentIntooutPointersroots(sqInt segmentWordArray, sqInt outPointerArray, sqInt arrayOfRoots);
@@ -1989,7 +1993,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.317";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.321";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13306,7 +13310,21 @@
 	return ((usqInt)((&GIV(argumentCount))));
 }
 
+
+/*	for Cogit */
+
 sqInt
+argumentCountOfClosure(sqInt closurePointer)
+{
+    sqInt oop;
+
+	/* begin quickFetchInteger:ofObject: */
+	oop = longAt((closurePointer + BaseHeaderSize) + (ClosureNumArgsIndex << ShiftForWord));
+	assert((oop & 1));
+	return (oop >> 1);
+}
+
+sqInt
 argumentCountOfMethodHeader(sqInt header)
 {
 	return (((usqInt) header) >> 25) & 15;
@@ -18172,6 +18190,15 @@
 }
 
 
+/*	for Cogit */
+
+sqInt
+copiedValueCountOfClosure(sqInt closurePointer)
+{
+	return (fetchWordLengthOf(closurePointer)) - ClosureFirstCopiedValueIndex;
+}
+
+
 /*	This entry point needs to be implemented for the interpreter proxy.
 	Since BitBlt is now a plugin we need to look up BitBltPlugin:=copyBits
 	and call it. This entire mechanism should eventually go away and be
@@ -39704,9 +39731,7 @@
 
 	newValue = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	index = longAt(GIV(stackPointer) + (1 * BytesPerWord));
-	if (((index & 1) == 0)
-	 || ((index == ConstOne)
-	 && ((newValue & 1) == 0))) {
+	if ((index & 1) == 0) {
 		(GIV(primFailCode) = PrimErrBadArgument); return;
 	}
 	index = (index >> 1);
@@ -39721,9 +39746,21 @@
 		: (((usqInt) realHeader) >> 10) & 255)) + LiteralStart)))) {
 		(GIV(primFailCode) = PrimErrBadIndex); return;
 	}
-	if ((index == 1)
-	 && (isCogMethodReference(rawHeader))) {
-		(((CogMethod *) rawHeader)->methodHeader = newValue);
+	if (index == 1) {
+		if (((newValue & 1) == 0)
+		 || ((((((sqInt) newValue)) < 0
+		? (((usqInt) newValue) >> 1) & 65535
+		: (((usqInt) newValue) >> 10) & 255)) != (((((sqInt) realHeader)) < 0
+		? (((usqInt) realHeader) >> 1) & 65535
+		: (((usqInt) realHeader) >> 10) & 255)))) {
+			(GIV(primFailCode) = PrimErrBadArgument); return;
+		}
+		if (isCogMethodReference(rawHeader)) {
+			(((CogMethod *) rawHeader)->methodHeader = newValue);
+		}
+		else {
+			longAtput((thisReceiver + BaseHeaderSize) + (0 << ShiftForWord), newValue);
+		}
 	}
 	else {
 		/* begin storePointer:ofObject:withValue: */
@@ -51074,6 +51111,37 @@
 }
 
 
+/*	Answer the startPC of lit if it is a (clean) block in aMethodObj,
+	oitherwise answer nil.
+ */
+
+sqInt
+startPCOrNilOfLiteralin(sqInt lit, sqInt aMethodObj)
+{
+    sqInt oop;
+    sqInt outerContext;
+
+	if ((lit & 1)) {
+		return null;
+	}
+	if ((lastPointerOf(lit)) <= ClosureCopiedValuesIndex) {
+		return null;
+	}
+	outerContext = longAt((lit + BaseHeaderSize) + (ClosureOuterContextIndex << ShiftForWord));
+	if (!(((outerContext & 1) == 0)
+		 && (((((usqInt) (longAt(outerContext))) >> 12) & 31) == ClassMethodContextCompactIndex))) {
+		return null;
+	}
+	if (aMethodObj != (longAt((outerContext + BaseHeaderSize) + (MethodIndex << ShiftForWord)))) {
+		return null;
+	}
+	/* begin quickFetchInteger:ofObject: */
+	oop = longAt((lit + BaseHeaderSize) + (ClosureStartPCIndex << ShiftForWord));
+	assert((oop & 1));
+	return (oop >> 1);
+}
+
+
 /*	Return what ST would return for <obj> at: index. */
 
 sqInt

Modified: branches/Cog/nscogsrc/vm/cointerp.h
===================================================================
--- branches/Cog/nscogsrc/vm/cointerp.h	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/cointerp.h	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
 
 
@@ -8,6 +8,7 @@
 sqInt addressCouldBeObj(sqInt address);
 sqInt addressCouldBeOop(sqInt address);
 usqInt argumentCountAddress(void);
+sqInt argumentCountOfClosure(sqInt closurePointer);
 sqInt argumentCountOfMethodHeader(sqInt header);
 sqInt argumentCountOf(sqInt methodPointer);
 void assertValidMachineCodeFrame(sqInt instrPtr);
@@ -61,6 +62,7 @@
 sqInt compactClassIndexOfHeader(sqInt header);
 sqInt compactClassIndexOf(sqInt oop);
 void compilationBreakpointFor(sqInt selectorOop);
+sqInt copiedValueCountOfClosure(sqInt closurePointer);
 sqInt createClosureNumArgsnumCopiedstartpc(sqInt numArgs, sqInt numCopied, sqInt initialIP);
 char * cStringOrNullFor(sqInt oop);
 sqInt doSignalSemaphoreWithIndex(sqInt index);
@@ -202,6 +204,7 @@
 void * startOfAlienData(sqInt oop);
 sqInt startPCOfMethodHeader(sqInt aCompiledMethodHeader);
 sqInt startPCOfMethod(sqInt aCompiledMethod);
+sqInt startPCOrNilOfLiteralin(sqInt lit, sqInt aMethodObj);
 sqInt storePointerUncheckedofObjectwithValue(sqInt fieldIndex, sqInt oop, sqInt valuePointer);
 sqInt stringForCString(const char *aCString);
 sqInt tempCountOf(sqInt methodPointer);

Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
    from
-	CoInterpreter VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CoInterpreter VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3 " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -162,6 +162,7 @@
 #define ClassPoint 12
 #define ClassSemaphore 18
 #define ClassUnsafeAlien 54
+#define ClosureCopiedValuesIndex 3
 #define ClosureFirstCopiedValueIndex 3
 #define ClosureIndex 4
 #define ClosureNumArgsIndex 2
@@ -367,6 +368,7 @@
 static char * allocateMemoryminimumimageFileheaderSize(sqInt heapSize, sqInt minimumMemory, sqImageFile fileStream, sqInt headerSize);
 static sqInt allYoungand(sqInt array1, sqInt array2);
 usqInt argumentCountAddress(void);
+sqInt argumentCountOfClosure(sqInt closurePointer);
 sqInt argumentCountOfMethodHeader(sqInt header);
 sqInt argumentCountOf(sqInt methodPointer);
 void * arrayValueOf(sqInt arrayOop);
@@ -480,6 +482,7 @@
 static sqInt contextInstructionPointerframe(sqInt theIP, char *theFP);
 static sqInt contexthasSender(sqInt thisCntx, sqInt aContext);
 static sqInt contexthasValidInversePCMappingOfin(sqInt aContext, sqInt theIP, char *theFP);
+sqInt copiedValueCountOfClosure(sqInt closurePointer);
 sqInt copyBits(void);
 sqInt copyBitsFromtoat(sqInt x0, sqInt x1, sqInt y);
 static sqInt copyObjtoSegmentaddrstopAtsaveOopAtheaderAt(sqInt oop, sqInt segmentWordArray, sqInt lastSeg, sqInt stopAddr, sqInt oopPtr, sqInt hdrPtr);
@@ -1174,6 +1177,7 @@
 void * startOfAlienData(sqInt oop);
 sqInt startPCOfMethodHeader(sqInt aCompiledMethodHeader);
 sqInt startPCOfMethod(sqInt aCompiledMethod);
+sqInt startPCOrNilOfLiteralin(sqInt lit, sqInt aMethodObj);
 sqInt stObjectat(sqInt array, sqInt index);
 sqInt stObjectatput(sqInt array, sqInt index, sqInt value);
 static sqInt storeImageSegmentIntooutPointersroots(sqInt segmentWordArray, sqInt outPointerArray, sqInt arrayOfRoots);
@@ -1992,7 +1996,7 @@
 	/* 575 */ (void (*)(void))0,
  0 };
 static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void);
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.317";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.321";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */;
 volatile int sendTrace;
 
@@ -13315,7 +13319,21 @@
 	return ((usqInt)((&GIV(argumentCount))));
 }
 
+
+/*	for Cogit */
+
 sqInt
+argumentCountOfClosure(sqInt closurePointer)
+{
+    sqInt oop;
+
+	/* begin quickFetchInteger:ofObject: */
+	oop = longAt((closurePointer + BaseHeaderSize) + (ClosureNumArgsIndex << ShiftForWord));
+	assert((oop & 1));
+	return (oop >> 1);
+}
+
+sqInt
 argumentCountOfMethodHeader(sqInt header)
 {
 	return (((usqInt) header) >> 25) & 15;
@@ -18181,6 +18199,15 @@
 }
 
 
+/*	for Cogit */
+
+sqInt
+copiedValueCountOfClosure(sqInt closurePointer)
+{
+	return (fetchWordLengthOf(closurePointer)) - ClosureFirstCopiedValueIndex;
+}
+
+
 /*	This entry point needs to be implemented for the interpreter proxy.
 	Since BitBlt is now a plugin we need to look up BitBltPlugin:=copyBits
 	and call it. This entire mechanism should eventually go away and be
@@ -39713,9 +39740,7 @@
 
 	newValue = longAt(GIV(stackPointer) + (0 * BytesPerWord));
 	index = longAt(GIV(stackPointer) + (1 * BytesPerWord));
-	if (((index & 1) == 0)
-	 || ((index == ConstOne)
-	 && ((newValue & 1) == 0))) {
+	if ((index & 1) == 0) {
 		(GIV(primFailCode) = PrimErrBadArgument); return;
 	}
 	index = (index >> 1);
@@ -39730,9 +39755,21 @@
 		: (((usqInt) realHeader) >> 10) & 255)) + LiteralStart)))) {
 		(GIV(primFailCode) = PrimErrBadIndex); return;
 	}
-	if ((index == 1)
-	 && (isCogMethodReference(rawHeader))) {
-		(((CogMethod *) rawHeader)->methodHeader = newValue);
+	if (index == 1) {
+		if (((newValue & 1) == 0)
+		 || ((((((sqInt) newValue)) < 0
+		? (((usqInt) newValue) >> 1) & 65535
+		: (((usqInt) newValue) >> 10) & 255)) != (((((sqInt) realHeader)) < 0
+		? (((usqInt) realHeader) >> 1) & 65535
+		: (((usqInt) realHeader) >> 10) & 255)))) {
+			(GIV(primFailCode) = PrimErrBadArgument); return;
+		}
+		if (isCogMethodReference(rawHeader)) {
+			(((CogMethod *) rawHeader)->methodHeader = newValue);
+		}
+		else {
+			longAtput((thisReceiver + BaseHeaderSize) + (0 << ShiftForWord), newValue);
+		}
 	}
 	else {
 		/* begin storePointer:ofObject:withValue: */
@@ -51083,6 +51120,37 @@
 }
 
 
+/*	Answer the startPC of lit if it is a (clean) block in aMethodObj,
+	oitherwise answer nil.
+ */
+
+sqInt
+startPCOrNilOfLiteralin(sqInt lit, sqInt aMethodObj)
+{
+    sqInt oop;
+    sqInt outerContext;
+
+	if ((lit & 1)) {
+		return null;
+	}
+	if ((lastPointerOf(lit)) <= ClosureCopiedValuesIndex) {
+		return null;
+	}
+	outerContext = longAt((lit + BaseHeaderSize) + (ClosureOuterContextIndex << ShiftForWord));
+	if (!(((outerContext & 1) == 0)
+		 && (((((usqInt) (longAt(outerContext))) >> 12) & 31) == ClassMethodContextCompactIndex))) {
+		return null;
+	}
+	if (aMethodObj != (longAt((outerContext + BaseHeaderSize) + (MethodIndex << ShiftForWord)))) {
+		return null;
+	}
+	/* begin quickFetchInteger:ofObject: */
+	oop = longAt((lit + BaseHeaderSize) + (ClosureStartPCIndex << ShiftForWord));
+	assert((oop & 1));
+	return (oop >> 1);
+}
+
+
 /*	Return what ST would return for <obj> at: index. */
 
 sqInt

Modified: branches/Cog/nscogsrc/vm/interp.h
===================================================================
--- branches/Cog/nscogsrc/vm/interp.h	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/interp.h	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
 
 #define VM_PROXY_MAJOR 1

Modified: branches/Cog/nscogsrc/vm/vmCallback.h
===================================================================
--- branches/Cog/nscogsrc/vm/vmCallback.h	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/nscogsrc/vm/vmCallback.h	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.317 uuid: 18267235-d270-4acf-8626-28095c535f32
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
 
 #define VM_CALLBACK_INC 1


Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
___________________________________________________________________
Modified: checkindate
   - Mon Aug 12 10:07:26 PDT 2013
   + Wed Aug 14 17:00:50 PDT 2013

Modified: branches/Cog/platforms/Mac OS/vm/sqMacMain.c
===================================================================
--- branches/Cog/platforms/Mac OS/vm/sqMacMain.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/platforms/Mac OS/vm/sqMacMain.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -126,7 +126,7 @@
 				gSqueakVMPathAnswersResources=false;
 long			gSqueakMouseMappings[4][4] = {{0},{0}};
 long			gSqueakBrowserMouseMappings[4][4] = {{0},{0}};
-usqInt          gMaxHeapSize=512*1024*1024;
+usqLong         gMaxHeapSize=512*1024*1024;
 UInt32			gSqueakWindowType=zoomDocProc,gSqueakWindowAttributes=0;
 long			gSqueakUIFlushPrimaryDeferNMilliseconds=20,
 				gSqueakUIFlushSecondaryCleanupDelayMilliseconds=20,
@@ -933,13 +933,8 @@
 				if (gSqueakBrowserMouseMappings[i][j] < 0 || gSqueakBrowserMouseMappings[i][j] > 3)
 					gSqueakBrowserMouseMappings[i][j] = 0;
 				}
-    if (SqueakMaxHeapSizeType) {
-#if SQ_IMAGE64
+    if (SqueakMaxHeapSizeType)
         CFNumberGetValue(SqueakMaxHeapSizeType,kCFNumberLongLongType,(sqInt *) &gMaxHeapSize);
-#else
-        CFNumberGetValue(SqueakMaxHeapSizeType,kCFNumberLongType,(sqInt *) &gMaxHeapSize);
-#endif
-		}
 
 	if (SqueakUIFlushUseHighPercisionClock)
         gSqueakUIFlushUseHighPercisionClock = CFBooleanGetValue(SqueakUIFlushUseHighPercisionClock);

Modified: branches/Cog/platforms/Mac OS/vm/sqMacMemory.c
===================================================================
--- branches/Cog/platforms/Mac OS/vm/sqMacMemory.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/platforms/Mac OS/vm/sqMacMemory.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -25,8 +25,8 @@
 #include <sys/mman.h>
 #include <unistd.h>
 
-extern usqInt  gMaxHeapSize;
-static usqInt	gHeapSize;
+extern usqLong  gMaxHeapSize;
+static usqLong	gHeapSize;
 void *mmapWasAt;
 
 /* compute the desired memory allocation */
@@ -37,17 +37,13 @@
 
 usqInt	sqGetAvailableMemory() {
 
-	sqInt 	availableMemory;
-	
-	availableMemory = gMaxHeapSize;
-
 	/******
 	  Note: 	    
 	    For os-x this doesn't matter we just mmap 512MB for the image, and 
 	    the application allocates more out of the 4GB address for VM logic. 
 	******/
 
-	return availableMemory;
+	return gMaxHeapSize >= 0xFFFFFFFFULL ? 0xFFFFFFFF : gMaxHeapSize;
 }
 
 usqInt sqAllocateMemoryMac(sqInt minHeapSize, sqInt desiredHeapSize) {
@@ -83,7 +79,7 @@
 }
 
 sqInt sqMemoryExtraBytesLeft(int flag) {
-    return (flag) ? gMaxHeapSize - gHeapSize : 0;
+    return flag ? gMaxHeapSize - gHeapSize : 0;
 }
 
 void sqMacMemoryFree() {

Modified: branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c
===================================================================
--- branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -48,7 +48,7 @@
 extern       int    argCnt;	/* global copies for access from plugins */
 extern       char **argVec;
 extern       char **envVec;
-extern UInt32 gMaxHeapSize;
+extern usqLong gMaxHeapSize;
 
 static void outOfMemory(void);
 static void parseArguments(int argc, char **argv);
@@ -56,6 +56,7 @@
 static void usage(void);
 static void parseEnvironment(void);
 static int strtobkm(const char *str);
+static usqLong strtolbkm(const char *str);
 static void printUsage(void);
 static void printUsageNotes(void);
 void resolveWhatTheImageNameIs(char *guess);
@@ -173,7 +174,7 @@
 #endif
   else if (argc > 1) {
 	  if (!strcmp(argv[0], "-memory"))	{ 
-		gMaxHeapSize = strtobkm(argv[1]);	 
+		gMaxHeapSize = strtolbkm(argv[1]);	 
 		return 2; }
 #if STACKVM || NewspeakVM
       else if (!strcmp(argv[0], "-breaksel")) { 
@@ -334,7 +335,8 @@
   exit(1);
 }
 
-static int strtobkm(const char *str)
+static int
+strtobkm(const char *str)
 {
   char *suffix;
   int value= strtol(str, &suffix, 10);
@@ -350,6 +352,23 @@
   return value;
 }
 
+static usqLong
+strtolbkm(const char *str)
+{
+  char *suffix;
+  usqLong value= strtol(str, &suffix, 10);
+  switch (*suffix)
+    {
+    case 'k': case 'K':
+      value*= 1024ULL;
+      break;
+    case 'm': case 'M':
+      value*= 1024ULL*1024ULL;
+      break;
+    }
+  return value;
+}
+
 static void parseEnvironment(void)
 {
 	char *ev;
@@ -357,7 +376,7 @@
 	if ((ev= getenv(IMAGE_ENV_NAME)))		
 		resolveWhatTheImageNameIs(ev);
 	if ((ev= getenv("SQUEAK_MEMORY")))
-		gMaxHeapSize= strtobkm(ev);
+		gMaxHeapSize= strtolbkm(ev);
 	if ((ev= getenv("SQUEAK_PATHENC")))
 		setEncodingType(ev);
 }

Modified: branches/Cog/src/vm/cogit.c
===================================================================
--- branches/Cog/src/vm/cogit.c	2013-08-12 17:08:01 UTC (rev 2764)
+++ branches/Cog/src/vm/cogit.c	2013-08-15 00:03:27 UTC (rev 2765)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb
+	CCodeGenerator VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb
+	StackToRegisterMappingCogit VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.315 uuid: edf4f6ec-fb34-404f-a50a-f3690c4f6dbb " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.321 uuid: 6134e40b-c38c-41ec-8f31-64a7f1c002b3 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -360,6 +360,7 @@
 static sqInt abstractInstructionfollows(AbstractInstruction *theAbstractInstruction, AbstractInstruction *anAbstractInstruction);
 static sqInt abstractRegisterForConcreteRegister(AbstractInstruction * self_in_abstractRegisterForConcreteRegister, sqInt reg);
 static BlockStart * addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span);
+static void addCleanBlockStarts(void);
 void addCogMethodsToHeapMap(void);
 static AbstractInstruction * addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction);
 static sqInt addressIsInFixups(AbstractInstruction *address);
@@ -601,6 +602,7 @@
 static sqInt genFastPrimFail(void);
 static void genFastPrimTraceUsingand(sqInt r1, sqInt r2);
 static sqInt genFetchIndexRegisterfrominto(sqInt indexReg, sqInt tableObj, sqInt destReg);
+static sqInt genFramelessStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex);
 static sqInt genGetClassFormatOfNonIntintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg);
 static sqInt genGetClassObjectOfintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg);
 static sqInt genGetCompactClassIndexNonIntOfinto(sqInt instReg, sqInt destReg);
@@ -650,6 +652,7 @@
 static sqInt genPrimitiveBitOr(void);
 static sqInt genPrimitiveBitShift(void);
 static sqInt genPrimitiveBitXor(void);
+static sqInt genPrimitiveClass(void);
 static sqInt genPrimitiveClosureValue(void);
 static sqInt genPrimitiveDiv(void);
 static sqInt genPrimitiveDivide(void);
@@ -870,7 +873,9 @@
 sqInt mnuOffset(void);
 static sqInt modRMRO(AbstractInstruction * self_in_modRMRO, sqInt mod, sqInt regMode, sqInt regOpcode);
 static AbstractInstruction * gNegateR(sqInt reg);
+static sqInt needsFrameIfFollowsSend(sqInt isInBlock);
 static sqInt needsFrameIfInBlock(sqInt isInBlock);
+static sqInt needsFrameIfMod16GENumArgs(sqInt isInBlock);
 static sqInt needsFrameNever(sqInt isInBlock);
 static sqInt noAssertMethodClassAssociationOf(sqInt methodPointer);
 static sqInt noCogMethodsMaximallyMarked(void);
@@ -941,6 +946,7 @@
 static AbstractInstruction * gSubCqR(sqInt quickConstant, sqInt reg);
 static AbstractInstruction * gSubCwR(sqInt wordConstant, sqInt reg);
 static void scanBlock(BlockStart *blockStart);
+static sqInt scanForCleanBlocks(void);
 static sqInt scanMethod(void);
 void setBreakMethod(sqInt anObj);
 static sqInt setLabelOffset(AbstractInstruction * self_in_setLabelOffset, sqInt aValue);
@@ -953,6 +959,7 @@
 static sqInt sizeImmediateGroup1at(AbstractInstruction * self_in_sizeImmediateGroup1at, sqInt op, sqInt pc);
 static sqInt sizePCDependentInstructionAt(AbstractInstruction * self_in_sizePCDependentInstructionAt, sqInt eventualAbsoluteAddress);
 static sqInt slotOffsetOfInstVarIndex(sqInt index);
+static sqInt spanForCleanBlockStartingAt(sqInt startPC);
 static void ssAllocateCallReg(sqInt requiredReg);
 static void ssAllocateCallRegand(sqInt requiredReg1, sqInt requiredReg2);
 static sqInt ssAllocatePreferredReg(sqInt preferredReg);
@@ -1109,22 +1116,22 @@
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genPushTemporaryVariableBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genPushTemporaryVariableBytecode, 0, needsFrameIfMod16GENumArgs, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushLiteralConstantBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
@@ -1291,8 +1298,8 @@
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
-	{ genSpecialSelectorEqualsEquals, 0, needsFrameNever, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
-	{ genSpecialSelectorClass, 0, needsFrameNever, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genSpecialSelectorEqualsEquals, 0, needsFrameIfFollowsSend, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+	{ genSpecialSelectorClass, 0, needsFrameIfFollowsSend, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
 	{ genSpecialSelectorSend, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 },
@@ -1384,6 +1391,7 @@
 static sqInt picAbortTrampolines[4];
 static sqInt picMissTrampolines[4];
 static void (*postCompileHook)(CogMethod *, void *);
+static BytecodeDescriptor * prevBCDescriptor;
 static AbstractInstruction * primInvokeLabel;
 static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = {
 	{ 0, -1, 0 },
@@ -1497,6 +1505,7 @@
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
 	{ genPrimitiveEquivalent, 1, 0 },
+	{ genPrimitiveClass, -1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
@@ -1554,7 +1563,6 @@
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
-	{ 0, -1, 0 },
 	{ genPrimitiveNotEquivalent, 1, 0 },
 	{ 0, -1, 0 },
 	{ 0, -1, 0 },
@@ -1636,7 +1644,7 @@
 /*** Macros ***/
 #define abstractInstructionAt(index) (&abstractOpcodes[index])
 #define allocateBlockStarts(numBlocks) do { \
-		blockStarts = numBlocks ? alloca(sizeof(BlockStart) * numBlocks) : 0; \
+		blockStarts = (numBlocks) ? alloca(sizeof(BlockStart) * (numBlocks)) : 0; \
 } while (0)
 #define allocateOpcodesbytecodes(numberOfAbstractOpcodes,numberOfBytecodes) do { \
 		int opcodeSize = sizeof(AbstractInstruction) * (numAbstractOpcodes = (numberOfAbstractOpcodes)); \
@@ -1823,7 +1831,27 @@
 	return blockStart;
 }
 
+static void
+addCleanBlockStarts(void)
+{
+    sqInt i;
+    sqInt iLimiT;
+    sqInt lit;
+    sqInt startPCOrNil;
 
+	for (i = 1, iLimiT = (literalCountOf(methodObj)); i <= iLimiT; i += 1) {
+		lit = fetchPointerofObject(i, methodObj);
+		if (((startPCOrNil = startPCOrNilOfLiteralin(lit, methodObj))) == null) {
+			null;
+		}
+		else {
+			maxLitIndex = ((maxLitIndex < i) ? i : maxLitIndex);
+			addBlockStartAtnumArgsnumCopiedspan(startPCOrNil - 1, argumentCountOfClosure(lit), copiedValueCountOfClosure(lit), spanForCleanBlockStartingAt(startPCOrNil - 1));
+		}
+	}
+}
+
+
 /*	Perform an integrity/leak check using the heapMap.
 	Set a bit at each cog method's header. */
 
@@ -3744,6 +3772,7 @@
     sqInt extra;
     sqInt numBlocks;
     sqInt numBytecodes;
+    sqInt numCleanBlocks;
     sqInt result;
 
 	methodOrBlockNumTemps = tempCountOf(methodObj);
@@ -3771,7 +3800,13 @@
 	if (((numBlocks = scanMethod())) < 0) {
 		return ((CogMethod *) numBlocks);
 	}
-	allocateBlockStarts(numBlocks);
+	numCleanBlocks = scanForCleanBlocks();
+	allocateBlockStarts(numBlocks + numCleanBlocks);
+	blockCount = 0;
+	if (numCleanBlocks > 0) {
+		addCleanBlockStarts();
+	}
+	/* begin maybeAllocAndInitCounters */
 	blockEntryLabel = null;
 	(methodLabel->dependent = null);
 	if (((result = compileEntireMethod())) < 0) {
@@ -3871,7 +3906,6 @@
 		return result;
 	}
 	compileFrameBuild();
-	blockCount = 0;
 	if (((result = compileMethodBody())) < 0) {
 		return result;
 	}
@@ -9034,7 +9068,44 @@
 	return 0;
 }
 
+static sqInt
+genFramelessStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex)
+{

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list