[Vm-dev] [commit][3733] CogVM source as per VMMaker.oscog-eem.1876

commits at squeakvm.org commits at squeakvm.org
Wed Jun 1 19:32:09 UTC 2016


Revision: 3733
Author:   eliot
Date:     2016-06-01 12:32:08 -0700 (Wed, 01 Jun 2016)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1876

Cogit:
Change the JIT so that (with Immutability/Write barrier ON) methods with only
frameless instance variable stores are compiled with two paths. The code first
checks if the receiver is immutable/read-only, and takes the right path
accordingly. The first path is frameless and does not include immutability/write
barrier checks. The second one is frameful and does all the immutability/write
barrier checks.

Eliminate the callerSavedRegMask variable and replace it with a
CallerSavedRegisterMask variable computed at register initialization time.

On ARM:
- define the caller-saved registers as the subset of the caller-saved registers
  that excludes R0/CArg0Reg/TempReg & R1/CArg1Reg (R0 is the C result register),
  and use R2 & R3 for abstract registers (ClassReg and Arg0Reg).
- save and restore elements of the caller-saved registers as appropriate around
  run-time calls.
- use LDM & STM to do the saving.
- hence provide two extra registers, now provinding Extra[012]Reg

Fix some compilation warnings in cogitX64.c

Plugins:
Change the JPEGReaderPlugin to handle 8- and 16- bit JPEGs (thank you Laura ! ;
still to integrate the refactoring into C and Smalltalk code).

More inlining of low-level copy routines in the LargeInegersPlugin.

Modified Paths:
--------------
    branches/Cog/nsspur64src/vm/cogit.h
    branches/Cog/nsspur64src/vm/cogitX64.c
    branches/Cog/nsspur64src/vm/cointerp.c
    branches/Cog/nsspur64src/vm/cointerp.h
    branches/Cog/nsspur64src/vm/gcc3x-cointerp.c
    branches/Cog/nsspursrc/vm/cogit.h
    branches/Cog/nsspursrc/vm/cogitARMv5.c
    branches/Cog/nsspursrc/vm/cogitIA32.c
    branches/Cog/nsspursrc/vm/cogitMIPSEL.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/spur64src/vm/cogit.h
    branches/Cog/spur64src/vm/cogitX64.c
    branches/Cog/spur64src/vm/cointerp.c
    branches/Cog/spur64src/vm/cointerp.h
    branches/Cog/spur64src/vm/gcc3x-cointerp.c
    branches/Cog/spursistasrc/vm/cogit.h
    branches/Cog/spursistasrc/vm/cogitARMv5.c
    branches/Cog/spursistasrc/vm/cogitIA32.c
    branches/Cog/spursistasrc/vm/cogitMIPSEL.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/cogitMIPSEL.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/plugins/B2DPlugin/B2DPlugin.c
    branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c
    branches/Cog/src/plugins/JPEGReaderPlugin/JPEGReaderPlugin.c
    branches/Cog/src/plugins/LargeIntegers/LargeIntegers.c
    branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c
    branches/Cog/src/vm/cogit.h
    branches/Cog/src/vm/cogitARMv5.c
    branches/Cog/src/vm/cogitIA32.c
    branches/Cog/src/vm/cogitMIPSEL.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/nsspur64src/vm/cogit.h
===================================================================
--- branches/Cog/nsspur64src/vm/cogit.h	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspur64src/vm/cogit.h	2016-06-01 19:32:08 UTC (rev 3733)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
 
 

Modified: branches/Cog/nsspur64src/vm/cogitX64.c
===================================================================
--- branches/Cog/nsspur64src/vm/cogitX64.c	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspur64src/vm/cogitX64.c	2016-06-01 19:32:08 UTC (rev 3733)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24
+	CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -45,6 +45,7 @@
 #define BlockCreationBytecodeSize 4
 #define BytecodeSetHasDirectedSuperSend 0
 #define Call 6
+#define CallerSavedRegisterMask 0xFC7
 #define CallFull 7
 #define CDQ 116
 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */
@@ -248,8 +249,6 @@
 #define PushCq 74
 #define PushCw 75
 #define PushR 73
-#define R10 10
-#define R11 11
 #define R12 12
 #define R13 13
 #define R15 15
@@ -469,6 +468,7 @@
 static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg);
 extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod);
 static AbstractInstruction * NoDbgRegParms CallNewspeakSend(sqInt callTarget);
+static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved);
 static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget);
 static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg);
 static AbstractInstruction * NoDbgRegParms gCmpCwR(sqInt wordConstant, sqInt reg);
@@ -601,7 +601,7 @@
 static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg);
 static AbstractInstruction * NoDbgRegParms gMoveRMwr(sqInt sourceReg, sqInt offset, sqInt baseReg);
 static AbstractInstruction * NoDbgRegParms gMoveRR(sqInt reg1, sqInt reg2);
-static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod);
+static sqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod);
 static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, sqInt arg), sqInt arg);
 static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC);
 static void mapObjectReferencesInGeneratedRuntime(void);
@@ -632,7 +632,7 @@
 static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta);
 static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer);
 static sqInt noCogMethodsMaximallyMarked(void);
-static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(sqInt cPIC);
+static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC);
 static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress);
 static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress);
 static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant);
@@ -889,11 +889,8 @@
 static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask);
 static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone);
 static SimStackEntry * NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg);
-static sqInt NoDbgRegParms isBackwardBranchFixup(BytecodeFixup * self_in_isBackwardBranchFixup);
 static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup);
-static sqInt NoDbgRegParms isMergeFixupOrIsFixedUp(BytecodeFixup * self_in_isMergeFixupOrIsFixedUp);
 static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask);
-static sqInt NoDbgRegParms callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask);
 static sqInt NoDbgRegParms callFullTargetFromReturnAddress(AbstractInstruction * self_in_callFullTargetFromReturnAddress, sqInt callSiteReturnAddress);
 static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize);
 static sqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress);
@@ -1076,6 +1073,9 @@
 static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector);
 static sqInt compileEntireMethod(void);
 static void compileFrameBuild(void);
+#if IMMUTABILITY
+static void compileTwoPathFrameBuild(void);
+#endif /* IMMUTABILITY */
 static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs);
 static sqInt doubleExtendedDoAnythingBytecode(void);
 static sqInt duplicateTopBytecode(void);
@@ -1210,7 +1210,6 @@
 static sqInt bytecodeSetOffset;
 void * CFramePointer;
 void * CStackPointer;
-static sqInt callerSavedRegMask;
 static sqInt cbEntryOffset;
 static sqInt cbNoSwitchEntryOffset;
 sqInt ceBaseFrameReturnTrampoline;
@@ -1273,12 +1272,13 @@
 static sqInt debugFixupBreaks;
 static sqInt debugOpcodeIndices;
 unsigned long debugPrimCallStackOffset;
+static sqInt debugStackPointers;
 static sqInt disassemblingMethod;
 static sqInt dynamicSuperSendTrampolines[NumSendTrampolines];
 static AbstractInstruction * endCPICCase0;
 static sqInt endPC;
 static AbstractInstruction * entry;
-static sqInt enumeratingCogMethod;
+static CogMethod * enumeratingCogMethod;
 static sqInt expectedFPAlignment;
 static sqInt expectedSPAlignment;
 static sqInt extA;
@@ -1831,6 +1831,7 @@
 sqInt missOffset;
 static usqInt mzFreeStart;
 static sqInt needsFrame;
+static sqInt needsTwoPath;
 static AbstractInstruction * noCheckEntry;
 static sqInt numAbstractOpcodes;
 static sqInt numIRCs;
@@ -1885,7 +1886,6 @@
 #define blockAlignment(self) 8
 #define blockStartAt(index) (&blockStarts[index])
 #define breakOnImplicitReceiver() (traceFlags & 64)
-#define callerSavedRegMask() callerSavedRegMask
 #define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline
 #define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline)
 #define ceCheckFeatures() ceCheckFeaturesFunction()
@@ -2605,7 +2605,7 @@
 static sqInt NoDbgRegParms
 addressIsInInstructions(AbstractInstruction *address)
 {
-	return !((unsigned)(address) & BytesPerWord-1) \
+	return !((usqInt)(address) & BytesPerWord-1) \
 				&& (address) >= &abstractOpcodes[0] \
 				&& (address) < &abstractOpcodes[opcodeIndex];
 }
@@ -2796,7 +2796,7 @@
     sqInt byte;
     BytecodeDescriptor *descriptor;
     sqInt distance;
-    usqInt endbcpc;
+    sqInt endbcpc;
     CogMethod *homeMethod;
     sqInt isBackwardBranch;
     sqInt isInBlock;
@@ -2962,6 +2962,44 @@
 	return abstractInstruction;
 }
 
+	/* Cogit>>#CallRT:registersToBeSavedMask: */
+static AbstractInstruction * NoDbgRegParms
+CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved)
+{
+    AbstractInstruction *abstractInstruction;
+    sqInt callerSavedRegsToBeSaved;
+    AbstractInstruction *lastInst;
+    sqInt reg;
+    sqInt registersToBePushed;
+
+	reg = 0;
+	callerSavedRegsToBeSaved = CallerSavedRegisterMask & registersToBeSaved;
+	registersToBePushed = callerSavedRegsToBeSaved;
+	reg = 0;
+	while (registersToBePushed != 0) {
+		if (registersToBePushed & 1) {
+			/* begin PushR: */
+			genoperand(PushR, reg);
+		}
+		reg += 1;
+		registersToBePushed = ((sqInt) registersToBePushed) >> 1;
+	}
+
+	/* begin CallRT: */
+	abstractInstruction = genoperand(Call, callTarget);
+	(abstractInstruction->annotation = IsRelativeCall);
+	lastInst = abstractInstruction;
+	while (reg >= 0) {
+		if (callerSavedRegsToBeSaved & (1LL << reg)) {
+			/* begin PopR: */
+			lastInst = genoperand(PopR, reg);
+		}
+		reg -= 1;
+	}
+	return lastInst;
+
+}
+
 	/* Cogit>>#Call: */
 static AbstractInstruction * NoDbgRegParms
 gCall(sqInt callTarget)
@@ -3667,7 +3705,7 @@
 closedPICRefersToUnmarkedObject(CogMethod *cPIC)
 {
     sqInt i;
-    sqInt object;
+    usqInt object;
     sqInt pc;
 
 	if (!((isImmediate((cPIC->selector)))
@@ -4464,6 +4502,8 @@
 
 	
 #  if ABI == MSVC
+
+	/* completely untested... */
 	if (regOrConst2 < NoReg) {
 		/* begin MoveCq:R: */
 		anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst2, R8);
@@ -5236,7 +5276,7 @@
 findMapLocationForMcpcinMethod(sqInt targetMcpc, CogMethod *cogMethod)
 {
     sqInt annotation;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
 
@@ -5320,7 +5360,7 @@
 followForwardedLiteralsIn(CogMethod *cogMethod)
 {
     sqInt annotation;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -6721,8 +6761,7 @@
 	(methodLabel->opcode = Label);
 	((methodLabel->operands))[0] = 0;
 	((methodLabel->operands))[1] = 0;
-	callerSavedRegMask = callerSavedRegisterMask(backEnd);
-	assert(((registerMaskFor(VarBaseReg)) & callerSavedRegMask) == 0);
+	assert(((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask) == 0);
 
 }
 
@@ -7136,10 +7175,10 @@
 /*	Answer the address of the null byte at the end of the method map. */
 
 	/* Cogit>>#mapEndFor: */
-static usqInt NoDbgRegParms
+static sqInt NoDbgRegParms
 mapEndFor(CogMethod *cogMethod)
 {
-    usqInt end;
+    sqInt end;
 
 	end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	while ((byteAt(end)) != MapEnd) {
@@ -7157,7 +7196,7 @@
 mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, sqInt arg), sqInt arg)
 {
     sqInt annotation;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -7264,7 +7303,7 @@
     sqInt freedPIC;
     sqInt hasYoungObj;
     sqInt hasYoungObjPtr;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt remappedMethod;
@@ -7382,7 +7421,7 @@
 {
     sqInt annotation;
     CogMethod *cogMethod;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -7462,7 +7501,7 @@
     CogMethod *cogMethod;
     sqInt hasYoungObj;
     sqInt hasYoungObjPtr;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     usqInt pointer;
@@ -7582,8 +7621,8 @@
     sqInt annotation;
     sqInt annotation1;
     CogMethod *cogMethod;
-    usqInt map;
-    usqInt map1;
+    sqInt map;
+    sqInt map1;
     sqInt mapByte;
     sqInt mapByte1;
     usqInt mcpc;
@@ -7742,7 +7781,7 @@
 markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit)
 {
     sqInt annotation;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -8070,7 +8109,7 @@
 {
     sqInt annotation;
     CogMethod *cogMethod;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -8198,7 +8237,7 @@
     sqInt byte;
     BytecodeDescriptor *descriptor;
     sqInt distance;
-    usqInt endbcpc;
+    sqInt endbcpc;
     CogMethod *homeMethod;
     sqInt isBackwardBranch;
     sqInt isInBlock;
@@ -8483,7 +8522,7 @@
 
 	/* Cogit>>#noTargetsFreeInClosedPIC: */
 static sqInt NoDbgRegParms
-noTargetsFreeInClosedPIC(sqInt cPIC)
+noTargetsFreeInClosedPIC(CogMethod *cPIC)
 {
 	return !(cPICHasFreedTargets(cPIC));
 }
@@ -8628,8 +8667,15 @@
 
 	cogMethod = methodFor(address);
 	if (cogMethod == 0) {
-		print("not a method");
-		cr();
+		if ((codeEntryFor(address)) == null) {
+			print("not a method");
+			cr();
+		}
+		else {
+			print("trampoline ");
+			print(codeEntryNameFor(address));
+			cr();
+		}
 	}
 	else {
 		printCogMethod(cogMethod);
@@ -8641,9 +8687,9 @@
 printPCMapPairsFor(CogMethod *cogMethod)
 {
     sqInt annotation;
-    usqInt map;
+    sqInt map;
     unsigned char mapByte;
-    usqInt mcpc;
+    sqInt mcpc;
     sqInt value;
 
 	mcpc = (0
@@ -8820,7 +8866,7 @@
 {
     sqInt annotation;
     sqLong callDelta;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqLong refDelta;
@@ -9394,7 +9440,7 @@
 {
     sqInt annotation;
     CogMethod *cogMethod;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -9837,7 +9883,7 @@
     sqInt annotation;
     CogMethod *cogMethod;
     sqInt freedPIC;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -9914,7 +9960,7 @@
 {
     sqInt annotation;
     CogMethod *cogMethod;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt mustScanAndUnlink;
@@ -10013,7 +10059,7 @@
 {
     sqInt annotation;
     CogMethod *cogMethod;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -10082,7 +10128,7 @@
     sqInt annotation;
     CogMethod *cogMethod;
     sqInt freedPIC;
-    usqInt map;
+    sqInt map;
     sqInt mapByte;
     usqInt mcpc;
     sqInt result;
@@ -10471,8 +10517,6 @@
 freeOlderMethodsForCompaction(void)
 {
     usqInt amountToFree;
-    sqInt cascade0;
-    sqInt cascade1;
     CogMethod *cogMethod;
     sqInt freeableUsage;
     usqInt freedSoFar;
@@ -10499,7 +10543,7 @@
 		}
 	} while((freedSoFar < amountToFree)
 		 && (((freeableUsage += 1)) < CMMaxUsageCount));
-	}
+}
 
 
 /*	Answer that all entries in youngReferrers are in-use and have the
@@ -15000,11 +15044,11 @@
 		genoperand(RetN, 0);
 		jmpTarget(jumpSC, gLabel());
 	}
-	ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, (((callerSavedRegMask()) | (1LL << ReceiverResultReg)) - (1LL << ReceiverResultReg)), 1, (callerSavedRegMask & (1LL << ReceiverResultReg)
+	ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1LL << ReceiverResultReg)) - (1LL << ReceiverResultReg)), 1, (CallerSavedRegisterMask & (1LL << ReceiverResultReg)
 		? ReceiverResultReg
 		: RAX), CheckRememberedInTrampoline);
 	ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline();
-	ceScheduleScavengeTrampoline = genTrampolineForcalledregsToSave(ceScheduleScavenge, "ceScheduleScavengeTrampoline", callerSavedRegMask());
+	ceScheduleScavengeTrampoline = genTrampolineForcalledregsToSave(ceScheduleScavenge, "ceScheduleScavengeTrampoline", CallerSavedRegisterMask);
 	ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext");
 	ceSmallActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 1, "ceSmallBlockContext");
 	ceLargeActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, 0, "ceLargeMethodContext");
@@ -15020,7 +15064,6 @@
 static sqInt NoDbgRegParms
 genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock)
 {
-    AbstractInstruction *abstractInstruction;
     sqInt address;
     sqInt address1;
     AbstractInstruction *anInstruction;
@@ -15241,9 +15284,7 @@
 	/* begin RetN: */
 	genoperand(RetN, 0);
 	jmpTarget(jumpNeedScavenge, gLabel());
-	/* begin CallRT: */
-	abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline);
-	(abstractInstruction->annotation = IsRelativeCall);
+	CallRTregistersToBeSavedMask(ceScheduleScavengeTrampoline, ((1LL << ReceiverResultReg) | (1LL << SendNumArgsReg)) | (1LL << ClassReg));
 
 	/* begin Jump: */
 	genoperand(Jump, ((sqInt)continuation));
@@ -16794,13 +16835,6 @@
 	return self_in_storeToReg;
 }
 
-	/* CogSSBytecodeFixup>>#isBackwardBranchFixup */
-static sqInt NoDbgRegParms
-isBackwardBranchFixup(BytecodeFixup * self_in_isBackwardBranchFixup)
-{
-	return ((self_in_isBackwardBranchFixup->simStackPtr)) == UnknownSimStackPtrFlag;
-}
-
 	/* CogSSBytecodeFixup>>#isMergeFixup */
 static sqInt NoDbgRegParms
 isMergeFixup(BytecodeFixup * self_in_isMergeFixup)
@@ -16808,14 +16842,7 @@
 	return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag;
 }
 
-	/* CogSSBytecodeFixup>>#isMergeFixupOrIsFixedUp */
-static sqInt NoDbgRegParms
-isMergeFixupOrIsFixedUp(BytecodeFixup * self_in_isMergeFixupOrIsFixedUp)
-{
-	return (((usqInt)((self_in_isMergeFixupOrIsFixedUp->targetInstruction)))) >= NeedsMergeFixupFlag;
-}
 
-
 /*	Answer an unused abstract register in the liveRegMask.
 	Subclasses with more registers can override to answer them.
 	N.B. Do /not/ allocate TempReg. */
@@ -16864,20 +16891,6 @@
 }
 
 
-/*	See e.g. Figure 3.4 Register Usage in
-	System V Application Binary Interface
-	AMD64 Architecture Processor Supplement
-	N.B. We are playing fast and loose here being processor-specific.
-	Soon enough this needs to be OS-specific. */
-
-	/* CogX64Compiler>>#callerSavedRegisterMask */
-static sqInt NoDbgRegParms
-callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask)
-{
-	return ((((((((1LL << RAX) | (1LL << RCX)) | (1LL << RDX)) | (1LL << RSI)) | (1LL << RDI)) | (1LL << R8)) | (1LL << R9)) | (1LL << R10)) | (1LL << R11);
-}
-
-
 /*	Answer the address the full call immediately preceding
 	callSiteReturnAddress will jump to.
  */
@@ -23144,7 +23157,7 @@
     CogBlockMethod *cogMethod1;
     BytecodeDescriptor *descriptor;
     sqInt distance;
-    usqInt endbcpc;
+    sqInt endbcpc;
     sqInt errCode;
     CogMethod *homeMethod;
     sqInt isBackwardBranch;
@@ -24748,7 +24761,6 @@
 compileCogMethod(sqInt selector)
 {
     unsigned long allocBytes;
-    sqInt debugStackPointers;
     int extra;
     unsigned long fixupBytes;
     sqInt numBlocks;
@@ -24880,6 +24892,15 @@
     sqInt iLimiT;
     AbstractInstruction *jumpSkip;
 
+	
+#  if IMMUTABILITY
+	if (needsTwoPath) {
+		compileTwoPathFrameBuild();
+		return;
+	}
+
+#  endif /* IMMUTABILITY */
+
 	if (!needsFrame) {
 		initSimStackForFramelessMethod(initialPC);
 		return;
@@ -24945,6 +24966,134 @@
 	initSimStackForFramefulMethod(initialPC);
 }
 
+
+/*	Build a frame for a CogMethod activation. See CoInterpreter
+	class>>initializeFrameIndices. receiver (in ReceiverResultReg)
+	arg0
+	...
+	argN
+	caller's saved ip/this stackPage (for a base frame)
+	fp->	saved fp
+	method
+	context (uninitialized?)
+	receiver
+	first temp
+	...
+	sp->	Nth temp
+	If there is a primitive and an error code the Nth temp is the error code.
+	Ensure SendNumArgsReg is set early on (incidentally to nilObj) because
+	it is the flag determining whether context switch is allowed on
+	stack-overflow.  */
+/*	We are in a method where the frame is needed *only* for instance variable
+	store, typically a setter method.
+	This case has 20% overhead with Immutability compared to setter without
+	immutability because of the stack
+	frame creation. We compile two path, one where the object is immutable,
+	one where it isn't. At the beginning 
+	of the frame build, we take one path or the other depending on the
+	receiver mutability.
+	
+	Note: this specific case happens only where there are only instance
+	variabel stores. We could do something
+	similar for literal variable stores, but we don't as it's too uncommon.
+ */
+
+	/* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */
+#if IMMUTABILITY
+static void
+compileTwoPathFrameBuild(void)
+{
+    sqInt address;
+    AbstractInstruction *anInstruction;
+    AbstractInstruction *anInstruction1;
+    AbstractInstruction *anInstruction2;
+    AbstractInstruction *anInstruction3;
+    sqInt constant;
+    sqInt i;
+    sqInt iLimiT;
+    AbstractInstruction * jumpImmutable;
+    AbstractInstruction *jumpSkip;
+
+	assert(needsFrame);
+	assert(IMMUTABILITY);
+	assert(needsTwoPath);
+	assert(blockCount == 0);
+
+	/* first path. The receiver is mutable */
+	jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg);
+	initSimStackForFramelessMethod(initialPC);
+	/* begin compileMethodBody */
+	if (endPC < initialPC) {
+		goto l7;
+	}
+	compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC);
+l7:	/* end compileMethodBody */;
+
+	/* reset because it impact inst var store compilation */
+	needsTwoPath = 0;
+	jmpTarget(jumpImmutable, gLabel());
+	genPushRegisterArgs();
+	if (!needsFrame) {
+		return;
+	}
+	/* begin PushR: */
+	genoperand(PushR, FPReg);
+	/* begin MoveR:R: */
+	genoperandoperand(MoveRR, SPReg, FPReg);
+	addDependent(methodLabel, annotateAbsolutePCRef(gPushCw(((sqInt)methodLabel))));
+	/* begin genMoveNilR: */
+	constant = nilObject();
+	if (shouldAnnotateObjectReference(constant)) {
+		annotateobjRef(gMoveCwR(constant, SendNumArgsReg), constant);
+	}
+	else {
+		/* begin MoveCq:R: */
+		anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg);
+	}
+	/* begin PushR: */
+	genoperand(PushR, SendNumArgsReg);
+	/* begin PushR: */
+	genoperand(PushR, ReceiverResultReg);
+	for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) {
+		/* begin PushR: */
+		genoperand(PushR, SendNumArgsReg);
+	}
+	if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0)
+	 && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject(initialPC + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) {
+		compileGetErrorCode();
+	}
+	/* begin MoveAw:R: */
+	address = stackLimitAddress();
+	/* begin gen:literal:operand: */
+	anInstruction3 = genoperandoperand(MoveAwR, address, TempReg);
+	/* begin CmpR:R: */
+	genoperandoperand(CmpRR, TempReg, SPReg);
+	if (canContextSwitchIfActivatingheader(methodObj, methodHeader)) {
+		/* begin JumpBelow: */
+		genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall));
+		/* begin Label */
+		stackCheckLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC);
+	}
+	else {
+		/* begin JumpAboveOrEqual: */
+		jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0));
+		/* begin MoveCq:R: */
+		anInstruction1 = genoperandoperand(MoveCqR, 0, SendNumArgsReg);
+		/* begin Jump: */
+		genoperand(Jump, ((sqInt)stackOverflowCall));
+		jmpTarget(jumpSkip, (stackCheckLabel = gLabel()));
+	}
+	/* begin annotateBytecode: */
+	(stackCheckLabel->annotation = HasBytecodePC);
+	if (numIRCs > 0) {
+		/* begin PrefetchAw: */
+		anInstruction2 = genoperand(PrefetchAw, theIRCs);
+	}
+
+	initSimStackForFramefulMethod(initialPC);
+}
+#endif /* IMMUTABILITY */
+
 	/* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */
 static sqInt NoDbgRegParms
 cPICMissTrampolineFor(sqInt numArgs)
@@ -25561,9 +25710,9 @@
 static void
 generateTracingTrampolines(void)
 {
-	ceTraceLinkedSendTrampoline = genTrampolineForcalledargregsToSave(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", ReceiverResultReg, callerSavedRegMask);
-	ceTraceBlockActivationTrampoline = genTrampolineForcalledregsToSave(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", callerSavedRegMask);
-	ceTraceStoreTrampoline = genTrampolineForcalledargargregsToSave(ceTraceStoreOfinto, "ceTraceStoreTrampoline", TempReg, ReceiverResultReg, callerSavedRegMask);
+	ceTraceLinkedSendTrampoline = genTrampolineForcalledargregsToSave(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", ReceiverResultReg, CallerSavedRegisterMask);
+	ceTraceBlockActivationTrampoline = genTrampolineForcalledregsToSave(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", CallerSavedRegisterMask);
+	ceTraceStoreTrampoline = genTrampolineForcalledargargregsToSave(ceTraceStoreOfinto, "ceTraceStoreTrampoline", TempReg, ReceiverResultReg, CallerSavedRegisterMask);
 }
 
 	/* StackToRegisterMappingCogit>>#genJumpBackTo: */
@@ -26076,7 +26225,7 @@
 	ensureReceiverResultRegContainsSelf();
 	/* begin genPushMaybeContextSlotIndex: */
 	assert(needsFrame);
-	if (callerSavedRegMask & (1LL << ReceiverResultReg)) {
+	if (CallerSavedRegisterMask & (1LL << ReceiverResultReg)) {
 
 		/* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */
 		(optStatus.isReceiverResultRegLive = 0);
@@ -26979,6 +27128,7 @@
     AbstractInstruction *anInstruction;
     sqInt association;
     sqInt topReg;
+    sqInt topReg1;
 
 	assert(needsFrame);
 	/* begin genLoadLiteralVariable:in: */
@@ -26998,17 +27148,27 @@
 	/* begin genStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */
 	
 #  if IMMUTABILITY
-	/* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */
-	ssAllocateRequiredReg(ClassReg);
-	ssStoreAndReplacePoptoReg(popBoolean, ClassReg);
-	ssFlushTo(simStackPtr);
-	genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0);
+	if (needsTwoPath) {
 
+		/* first path, receiver is mutable */
+		/* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */
+		topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg);
+		ssStorePoptoReg(popBoolean, topReg);
+		genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
+	}
+	else {
+		/* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */
+		ssAllocateRequiredReg(ClassReg);
+		ssStoreAndReplacePoptoReg(popBoolean, ClassReg);
+		ssFlushTo(simStackPtr);
+		genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0);
+	}
+
 #  else /* IMMUTABILITY */
 	/* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */
-	topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg);
-	ssStorePoptoReg(popBoolean, topReg);
-	genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
+	topReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg);
+	ssStorePoptoReg(popBoolean, topReg1);
+	genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg1, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
 
 #  endif /* IMMUTABILITY */
 
@@ -27108,23 +27268,34 @@
 genStorePopReceiverVariableneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck)
 {
     sqInt topReg;
+    sqInt topReg1;
 
 	ssFlushUpThroughReceiverVariable(slotIndex);
 	ensureReceiverResultRegContainsSelf();
 	/* begin genStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */
 	
 #  if IMMUTABILITY
-	/* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */
-	ssAllocateRequiredReg(ClassReg);
-	ssStoreAndReplacePoptoReg(popBoolean, ClassReg);
-	ssFlushTo(simStackPtr);
-	genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck, 1);
+	if (needsTwoPath) {
 
+		/* first path, receiver is mutable */
+		/* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */
+		topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg);
+		ssStorePoptoReg(popBoolean, topReg);
+		genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
+	}
+	else {
+		/* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */
+		ssAllocateRequiredReg(ClassReg);
+		ssStoreAndReplacePoptoReg(popBoolean, ClassReg);
+		ssFlushTo(simStackPtr);
+		genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck, 1);
+	}
+
 #  else /* IMMUTABILITY */
 	/* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */
-	topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg);
-	ssStorePoptoReg(popBoolean, topReg);
-	genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
+	topReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg);
+	ssStorePoptoReg(popBoolean, topReg1);
+	genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg1, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
 
 #  endif /* IMMUTABILITY */
 
@@ -27207,6 +27378,7 @@
 {
     AbstractInstruction *abstractInstruction;
     AbstractInstruction *abstractInstruction1;
+    sqInt framelessReturn;
     sqInt offset;
 
 
@@ -27222,7 +27394,17 @@
 		(abstractInstruction->annotation = HasBytecodePC);
 		return 0;
 	}
-	if (needsFrame) {
+	
+#  if IMMUTABILITY
+	framelessReturn = needsFrame
+	 && (!needsTwoPath);
+
+#  else /* IMMUTABILITY */
+	framelessReturn = needsFrame;
+
+#  endif /* IMMUTABILITY */
+
+	if (framelessReturn) {
 		/* begin MoveR:R: */
 		genoperandoperand(MoveRR, FPReg, SPReg);
 		/* begin PopR: */
@@ -27871,6 +28053,12 @@
 
 	needsFrame = 0;
 	prevBCDescriptor = null;
+	
+#  if IMMUTABILITY
+	needsTwoPath = 0;
+
+#  endif /* IMMUTABILITY */
+
 	numIRCs = 0;
 
 	if ((primitiveIndex > 0)
@@ -27895,6 +28083,21 @@
 		 && (pc >= latestContinuation)) {
 			endPC = pc;
 		}
+		
+#    if IMMUTABILITY
+		if (!(needsFrame
+			 && (!needsTwoPath))) {
+			if ((((descriptor->needsFrameFunction)) == null)
+			 || (((descriptor->needsFrameFunction))(framelessStackDelta))) {
+				needsFrame = 1;
+				needsTwoPath = ((descriptor->generator)) == genStoreAndPopReceiverVariableBytecode;
+			}
+			else {
+				framelessStackDelta += (descriptor->stackDelta);
+			}
+		}
+
+#    else /* IMMUTABILITY */
 		if (!needsFrame) {
 			if ((((descriptor->needsFrameFunction)) == null)
 			 || (((descriptor->needsFrameFunction))(framelessStackDelta))) {
@@ -27904,6 +28107,9 @@
 				framelessStackDelta += (descriptor->stackDelta);
 			}
 		}
+
+#    endif /* IMMUTABILITY */
+
 		if (isBranch(descriptor)) {
 			distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj);
 			targetPC = (pc + ((descriptor->numBytes))) + distance;
@@ -27945,7 +28151,7 @@
 static void NoDbgRegParms
 ssAllocateCallReg(sqInt requiredReg)
 {
-	ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | (1LL << requiredReg), simStackPtr);
+	ssAllocateRequiredRegMaskupThrough(CallerSavedRegisterMask | (1LL << requiredReg), simStackPtr);
 }
 
 
@@ -27957,7 +28163,7 @@
 static void NoDbgRegParms
 ssAllocateCallRegand(sqInt requiredReg1, sqInt requiredReg2)
 {
-	ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | ((1LL << requiredReg1) | (1LL << requiredReg2)), simStackPtr);
+	ssAllocateRequiredRegMaskupThrough(CallerSavedRegisterMask | ((1LL << requiredReg1) | (1LL << requiredReg2)), simStackPtr);
 }
 
 
@@ -27969,7 +28175,7 @@
 static void NoDbgRegParms
 ssAllocateCallRegandand(sqInt requiredReg1, sqInt requiredReg2, sqInt requiredReg3)
 {
-	ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | ((1LL << requiredReg1) | ((1LL << requiredReg2) | (1LL << requiredReg3))), simStackPtr);
+	ssAllocateRequiredRegMaskupThrough(CallerSavedRegisterMask | ((1LL << requiredReg1) | ((1LL << requiredReg2) | (1LL << requiredReg3))), simStackPtr);
 }
 
 	/* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough: */

Modified: branches/Cog/nsspur64src/vm/cointerp.c
===================================================================
--- branches/Cog/nsspur64src/vm/cointerp.c	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspur64src/vm/cointerp.c	2016-06-01 19:32:08 UTC (rev 3733)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
    from
-	CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2452,7 +2452,7 @@
 	};
 sqInt checkedPluginName;
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1872";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1876";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -40930,7 +40930,7 @@
     sqInt oopRcvr;
     sqInt oopResult;
     usqLong result;
-    sqInt resultIsNegative;
+    int resultIsNegative;
     char *sp;
 
 	oopArg = longAt(GIV(stackPointer) + (0 * BytesPerWord));
@@ -61627,7 +61627,7 @@
     usqInt prevFree;
     usqInt prevFreeChunk;
     usqInt prevPrevFree;
-    usqInt prevPrevFreeChunk;
+    sqInt prevPrevFreeChunk;
     sqInt slotBytes;
     sqInt slotBytes1;
     usqInt there;
@@ -67437,7 +67437,7 @@
 bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil)
 {
     usqInt bridgeSpan;
-    usqInt clifton;
+    sqInt clifton;
     usqInt segEnd;
 
 	segEnd = ((aSegment->segSize)) + ((aSegment->segStart));
@@ -67618,7 +67618,7 @@
 static void
 postSnapshot(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    usqInt address;
+    sqInt address;
     sqInt bytes;
     usqInt freeChunk;
     sqInt i;
@@ -67681,7 +67681,7 @@
     sqInt limit;
     sqInt newEndOfMemory;
     sqInt next;
-    usqInt node;
+    sqInt node;
     usqInt numSlots;
     usqInt numSlots1;
     SpurSegmentInfo *seg;
@@ -68024,8 +68024,8 @@
 {
     usqLong firstSavedBridgeWord;
     sqInt nWritten;
-    usqInt pier1;
-    usqInt pier2;
+    sqInt pier1;
+    sqInt pier2;
     usqLong secondSavedBridgeWord;
 
 	pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * BaseHeaderSize);

Modified: branches/Cog/nsspur64src/vm/cointerp.h
===================================================================
--- branches/Cog/nsspur64src/vm/cointerp.h	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspur64src/vm/cointerp.h	2016-06-01 19:32:08 UTC (rev 3733)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
 
 

Modified: branches/Cog/nsspur64src/vm/gcc3x-cointerp.c
===================================================================
--- branches/Cog/nsspur64src/vm/gcc3x-cointerp.c	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspur64src/vm/gcc3x-cointerp.c	2016-06-01 19:32:08 UTC (rev 3733)
@@ -2,11 +2,11 @@
 
 
 /* Automatically generated by
-	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
    from
-	CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
-static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 " __DATE__ ;
+static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ;
 char *__interpBuildInfo = __buildInfo;
 
 
@@ -2455,7 +2455,7 @@
 	};
 sqInt checkedPluginName;
 char expensiveAsserts = 0;
-const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1872";
+const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1876";
 sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */;
 volatile int sendTrace;
 
@@ -40939,7 +40939,7 @@
     sqInt oopRcvr;
     sqInt oopResult;
     usqLong result;
-    sqInt resultIsNegative;
+    int resultIsNegative;
     char *sp;
 
 	oopArg = longAt(GIV(stackPointer) + (0 * BytesPerWord));
@@ -61636,7 +61636,7 @@
     usqInt prevFree;
     usqInt prevFreeChunk;
     usqInt prevPrevFree;
-    usqInt prevPrevFreeChunk;
+    sqInt prevPrevFreeChunk;
     sqInt slotBytes;
     sqInt slotBytes1;
     usqInt there;
@@ -67446,7 +67446,7 @@
 bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil)
 {
     usqInt bridgeSpan;
-    usqInt clifton;
+    sqInt clifton;
     usqInt segEnd;
 
 	segEnd = ((aSegment->segSize)) + ((aSegment->segStart));
@@ -67627,7 +67627,7 @@
 static void
 postSnapshot(void)
 {   DECL_MAYBE_SQ_GLOBAL_STRUCT
-    usqInt address;
+    sqInt address;
     sqInt bytes;
     usqInt freeChunk;
     sqInt i;
@@ -67690,7 +67690,7 @@
     sqInt limit;
     sqInt newEndOfMemory;
     sqInt next;
-    usqInt node;
+    sqInt node;
     usqInt numSlots;
     usqInt numSlots1;
     SpurSegmentInfo *seg;
@@ -68033,8 +68033,8 @@
 {
     usqLong firstSavedBridgeWord;
     sqInt nWritten;
-    usqInt pier1;
-    usqInt pier2;
+    sqInt pier1;
+    sqInt pier2;
     usqLong secondSavedBridgeWord;
 
 	pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * BaseHeaderSize);

Modified: branches/Cog/nsspursrc/vm/cogit.h
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.h	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspursrc/vm/cogit.h	2016-06-01 19:32:08 UTC (rev 3733)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4
+	CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
 
 

Modified: branches/Cog/nsspursrc/vm/cogitARMv5.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogitARMv5.c	2016-05-26 20:01:37 UTC (rev 3732)
+++ branches/Cog/nsspursrc/vm/cogitARMv5.c	2016-06-01 19:32:08 UTC (rev 3733)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24
+	CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -39,8 +39,8 @@
 #define AndOpcode 0
 #define AndRR 91
 #define AnnotationShift 5
-#define Arg0Reg 4
-#define Arg1Reg 5
+#define Arg0Reg 3
+#define Arg1Reg 4
 #define ArithmeticShiftRightCqR 80
 #define ArithmeticShiftRightRR 81
 #define BadRegisterSet 1
@@ -52,6 +52,7 @@
 #define CArg2Reg 2
 #define CArg3Reg 3
 #define Call 6
+#define CallerSavedRegisterMask 0x120C
 #define CallFull 7
 #define CC 3
 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */
@@ -61,7 +62,7 @@
 #define ClassBlockClosureCompactIndex 37
 #define ClassFloatCompactIndex 34
 #define ClassMethodContextCompactIndex 36
-#define ClassReg 8
+#define ClassReg 2
 #define ClosureFirstCopiedValueIndex 3
 #define ClosureIndex 4
 #define ClosureNumArgsIndex 2
@@ -73,7 +74,7 @@
 #define CMMaxUsageCount 7
 #define CMMethod 2
 #define CMOpenPIC 5
-#define CMPSMULL 121
+#define CMPSMULL 123
 #define CmpC32R 102
 #define CmpCqR 94
 #define CmpCwR 101
@@ -96,7 +97,9 @@
 #define DPFPReg2 2
 #define EncounteredUnknownBytecode -6
 #define EQ 0
-#define Extra0Reg 9
+#define Extra0Reg 7
+#define Extra1Reg 8
+#define Extra2Reg 9
 #define Fill32 4
 #define FirstAnnotation 64
 #define FirstJump 11
@@ -249,6 +252,7 @@
 #define PC 15
 #define PCReg 15
 #define PL 5
+#define PopLDM 119
 #define PopR 72
 #define PrefetchAw 76
 #define PrimCallCollectsProfileSamples 8
@@ -261,9 +265,10 @@
 #define PushCq 74
 #define PushCw 75
 #define PushR 73
+#define PushSTM 120
 #define R0 0
 #define ReceiverIndex 5
-#define ReceiverResultReg 7
+#define ReceiverResultReg 5
 #define RetN 8
 #define RISCTempReg 12
 #define RsbOpcode 3
@@ -445,7 +450,6 @@
 static sqInt NoDbgRegParms bicsrnimmror(AbstractInstruction * self_in_bicsrnimmror, sqInt destReg, sqInt srcReg, sqInt immediate, sqInt rot);
 static sqInt NoDbgRegParms bl(AbstractInstruction * self_in_bl, sqInt offset);
 static sqInt NoDbgRegParms b(AbstractInstruction * self_in_b, sqInt offset);
-static sqInt NoDbgRegParms callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask);
 static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize);
 static sqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress);
 static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize);
@@ -456,6 +460,7 @@
 static void NoDbgRegParms concretizeConditionalInstruction(AbstractInstruction * self_in_concretizeConditionalInstruction);
 static usqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32);
 static usqInt NoDbgRegParms concretizeMSR(AbstractInstruction * self_in_concretizeMSR);
+static usqInt NoDbgRegParms concretizePushOrPopMultipleRegisters(AbstractInstruction * self_in_concretizePushOrPopMultipleRegisters, sqInt doPush);
 static usqInt NoDbgRegParms concretizeSMULL(AbstractInstruction * self_in_concretizeSMULL);
 static sqInt NoDbgRegParms conditionIsNotNever(AbstractInstruction * self_in_conditionIsNotNever, sqInt instr);
 static sqInt NoDbgRegParms dataOpTyperdrnrmlsr(AbstractInstruction * self_in_dataOpTyperdrnrmlsr, sqInt armOpcode, sqInt destReg, sqInt srcReg, sqInt addReg, sqInt shft);
@@ -472,8 +477,6 @@
 static AbstractInstruction * NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored);
 static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n);
 static AbstractInstruction * NoDbgRegParms genRestoreRegsExcept(AbstractInstruction * self_in_genRestoreRegsExcept, sqInt abstractReg);
-static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask);
-static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask);
 static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers);
 static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc);
 static sqInt NoDbgRegParms instructionBeforeAddress(AbstractInstruction * self_in_instructionBeforeAddress, sqInt followingAddress);
@@ -569,7 +572,9 @@
 static sqInt NoDbgRegParms blockCreationBytecodeSizeForHeader(sqInt aMethodHeader);
 static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg);
 extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod);
+static AbstractInstruction * NoDbgRegParms CallFullRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved);
 static AbstractInstruction * NoDbgRegParms CallNewspeakSend(sqInt callTarget);
+static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved);
 static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget);
 static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg);
 static AbstractInstruction * NoDbgRegParms gCmpCwR(sqInt wordConstant, sqInt reg);
@@ -703,7 +708,7 @@
 static AbstractInstruction * NoDbgRegParms gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg);
 static AbstractInstruction * NoDbgRegParms gMoveRMwr(sqInt sourceReg, sqInt offset, sqInt baseReg);
 static AbstractInstruction * NoDbgRegParms gMoveRR(sqInt reg1, sqInt reg2);
-static sqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod);
+static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod);
 static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, sqInt arg), sqInt arg);
 static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC);
 static void mapObjectReferencesInGeneratedRuntime(void);
@@ -734,7 +739,7 @@
 static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta);
 static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer);
 static sqInt noCogMethodsMaximallyMarked(void);
-static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(sqInt cPIC);
+static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC);
 static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress);
 static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress);
 static AbstractInstruction * NoDbgRegParms gPopR(sqInt reg);
@@ -992,9 +997,7 @@
 static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask);
 static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone);
 static SimStackEntry * NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg);
-static sqInt NoDbgRegParms isBackwardBranchFixup(BytecodeFixup * self_in_isBackwardBranchFixup);
 static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup);
-static sqInt NoDbgRegParms isMergeFixupOrIsFixedUp(BytecodeFixup * self_in_isMergeFixupOrIsFixedUp);
 static AbstractInstruction * NoDbgRegParms allocateLiteral(sqInt aLiteral);
 static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction);
 static sqInt NoDbgRegParms dumpLiterals(sqInt generateBranchAround);
@@ -1117,6 +1120,9 @@
 static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector);
 static sqInt compileEntireMethod(void);
 static void compileFrameBuild(void);
+#if IMMUTABILITY
+static void compileTwoPathFrameBuild(void);
+#endif /* IMMUTABILITY */
 static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs);
 static sqInt doubleExtendedDoAnythingBytecode(void);
 static sqInt duplicateTopBytecode(void);
@@ -1251,7 +1257,6 @@
 static sqInt bytecodeSetOffset;
 void * CFramePointer;
 void * CStackPointer;
-static sqInt callerSavedRegMask;
 static sqInt cbEntryOffset;
 static sqInt cbNoSwitchEntryOffset;
 sqInt ceBaseFrameReturnTrampoline;
@@ -1314,6 +1319,7 @@
 static sqInt debugFixupBreaks;
 static sqInt debugOpcodeIndices;
 unsigned long debugPrimCallStackOffset;
+static sqInt debugStackPointers;
 static sqInt disassemblingMethod;
 static sqInt dynamicSuperSendTrampolines[NumSendTrampolines];
 static AbstractInstruction * endCPICCase0;
@@ -1877,6 +1883,7 @@
 sqInt missOffset;
 static usqInt mzFreeStart;
 static sqInt needsFrame;
+static sqInt needsTwoPath;
 static sqInt nextLiteralIndex;
 static AbstractInstruction * noCheckEntry;
 static sqInt numAbstractOpcodes;
@@ -1938,7 +1945,6 @@
 #define blockAlignment(self) 8
 #define blockStartAt(index) (&blockStarts[index])
 #define breakOnImplicitReceiver() (traceFlags & 64)
-#define callerSavedRegMask() callerSavedRegMask
 #define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline
 #define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline)
 #define ceCheckFeatures() ceCheckFeaturesFunction()
@@ -2341,6 +2347,12 @@
 	if (!(liveRegsMask & (1L << Extra0Reg))) {
 		return Extra0Reg;
 	}
+	if (!(liveRegsMask & (1L << Extra1Reg))) {
+		return Extra1Reg;
+	}
+	if (!(liveRegsMask & (1L << Extra2Reg))) {
+		return Extra2Reg;
+	}
 	if (!(liveRegsMask & (1L << Arg1Reg))) {
 		return Arg1Reg;
 	}
@@ -2399,23 +2411,6 @@
 }
 
 
-/*	According to IHI0042E ARM Architecture Procedure Calling Standard, in
-	section 5.1.1:
-	A subroutine must preserve the contents of the registers r4-r8, r10, r11
-	and SP (and r9 in PCS variants that designate r9 as v6).
-	SP = r13, so the callee-saved regs are r4-r8 & r10-r12.
-	The caller-saved registers are those that are not callee-saved and not
-	reserved for hardware/abi uses,
-	i..e r0-r3, r9 & r12. */
-
-	/* CogARMCompiler>>#callerSavedRegisterMask */
-static sqInt NoDbgRegParms
-callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask)
-{
-	return (((((1L << 0) | (1L << 1)) | (1L << 2)) | (1L << 3)) | (1L << 9)) | (1L << 12);
-}
-
-
 /*	ARM calls and jumps span +/- 32 mb, more than enough for intra-zone calls
 	and jumps.
  */
@@ -2533,6 +2528,8 @@
 	case SMULL:
 	case MSR:
 	case CMPSMULL:
+	case PopLDM:
+	case PushSTM:
 	case MoveRR:
 	case MoveRdRd:
 	case MoveXbrRR:
@@ -2851,7 +2848,18 @@
 	return ((self_in_concretizeMSR->machineCodeSize) = 4);
 }
 
+	/* CogARMCompiler>>#concretizePushOrPopMultipleRegisters: */
+static usqInt NoDbgRegParms
+concretizePushOrPopMultipleRegisters(AbstractInstruction * self_in_concretizePushOrPopMultipleRegisters, sqInt doPush)
+{
+	assert((((self_in_concretizePushOrPopMultipleRegisters->operands))[0]) != 0);
+	((self_in_concretizePushOrPopMultipleRegisters->machineCode))[0] = ((((AL << 28) + ((doPush
+	? 146L << 20
+	: 139L << 20))) + (SP << 16)) + (((self_in_concretizePushOrPopMultipleRegisters->operands))[0]));
+	return ((self_in_concretizePushOrPopMultipleRegisters->machineCodeSize) = 4);
+}
 
+
 /*	Generate an SMULL loResultReg, hiResultReg, srcA, srcB instruction */
 
 	/* CogARMCompiler>>#concretizeSMULL */
@@ -5008,6 +5016,14 @@
 		concretizeMSR(self_in_dispatchConcretize);
 		return;
 
+	case PopLDM:
+		concretizePushOrPopMultipleRegisters(self_in_dispatchConcretize, 0);
+		return;
+
+	case PushSTM:
+		concretizePushOrPopMultipleRegisters(self_in_dispatchConcretize, 1);
+		return;
+
 	case MoveCqR:
 		/* begin concretizeMoveCqR */
 		word2 = ((self_in_dispatchConcretize->operands))[0];
@@ -5838,7 +5854,6 @@
 static AbstractInstruction * NoDbgRegParms
 genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder)
 {
-    sqInt callTarget;
     usqInt divRemFunctionAddr;
     AbstractInstruction * inst;
     sqInt rDividend;
@@ -5876,12 +5891,8 @@
 	self_in_saveAndRestoreLinkRegAround = ((AbstractInstruction *) (backEnd()));
 	/* begin PushR: */
 	inst = genoperand(PushR, LinkReg);
-	/* begin CallFullRT: */
-	callTarget = ((usqInt)divRemFunctionAddr);
-	/* begin CallFull: */

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list