[Vm-dev] [commit][3672] CogVM source as per VMMaker.oscog-eem.1822

commits at squeakvm.org commits at squeakvm.org
Tue Apr 19 18:21:16 UTC 2016


Revision: 3672
Author:   eliot
Date:     2016-04-19 11:21:14 -0700 (Tue, 19 Apr 2016)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1822

General:
Add support for full block closures (visible in the Ssta VMs).  Full
block closures have their own method, and receiver, independent of
their outerContext's.


Spur:
Fix bug in following state on primitive failure. The old code would
always follow to depth 1, even if the accessor depth was 0.
Hard-code primitiveSize's depth to 0 (accessing length in at:[put:]
and size causes the stack depth computation to answer 1 instead of
0 for these primitives.

Fix assert and dequeueMourner for case where mournQueue is nil.

- use option:IMMUTABILITY instead of cppIf: to make the immutability
  primitive code look better.
- fixed a bug in receiver accessing in immutability primitive for
  mirror primitive.

- change primitiveSetOrHasIdentityHash to patch the class table if
  the new hash is set to a behavior (the primitive knows it's a
  behavior if the second (optional) argument is true)
  For example:
	FullBlockClosure tryPrimitive: 161 withArgs: {38.true}

No longer follow the method and context fields in a closure in
activateNewClosureMethod:numArgs:mayContextSwitch:; the caller will
have failed if these are forwarders, so no need to check again.


Cogit:
Follow selectors in the openPICList post Spur become.

Removed all the annoteUse (from the struct, its usage, etc...)
Abstract out the asnnotate Label or Nop routine and use it to fix
doubleExtendedDoAnythingBytecode

- improved support for register allocation: branch merge
  successfully compiled with register moved instead of spilling.

- refactored annotateUse in CogSimStackEntry to share code between methods
- tried to make some sense out of the fixup merge logic. Now all
  return and unconditionnal jumps marked explicitly the execution
  flow as being deadCode. At each merge point, depending if the
  execution can fall through or not, handle the merge differently.

Rename ScratchNReg to ExtraNReg. Provide availableRegisterOrNoneFor:
in ARM & X64 to allocate ExtraNRegs when available.
Provide isCallerSavedReg: as a convenience and use it where
(self register: ReceiverResultReg isInMask: callerSavedRegMask) was.

- Made explicit messages related to bytecode fixup (abstract away
  from integer flags)

JIT and execution-time support for full block closures.  Use the old
cpicHasMNUFlag in CMMethod to mark full block code, hence renaming
the flag to cpicHasMNUCaseOrCMIsFullBlock.  Provide
isVanillaBlockClosure: to disinguish between standard and full block
closures.  Use it in makeBaseFrameFor:.


Sista Bytecodes:
Added the ExtB flags extension to tip the JIT how what machine code
checks can be ignored on specific operations.

Sista Cogit:
Don't bother to add counters to conditional jumps implementing and:
and or:.  Added the remote inst var access bytecode in sista V1
bytecode set without interfering with existing code.


Plugins:
Upgrade LargeIntegersPlugin to v2.0
LargeInteger primitives now deal with 32-bits digits.
At image side, LargeInteger digits are still 8-bit wide.
This enables fallback code to work in absence of the plugin.

Subtle code:
1) Large integers still have byteLength calculated as short as possible
   this is to avoid having null highest 8-bit digit at image side
2) For this reason largeInt:growTo: takes a byte-length parameter
   and we need to restore byteSizeOfCSI: and byteSizeOfLargeInt:
3) For multiply, the result is allocated with just enough bytes
   for example 13 bytes*11 bytes->24 bytes->6 digits
   If we would round to digits, that would be: 4 digits*3 digits->7 digits
   for this reason, an additional parameter (resLen) has been added to cDigitMultiply
   and care is taken to not write a (null) carry past this result length
4) For hypothetical big-endian machines, bytes are swapped on the fly at each fetch/store from/to memory (see cDigitOf:at: / cDigitOf:at:put:)
   This is achieved thru byteSwapped32IfBigEndian: which translates to a C macro SQ_SWAP_4_BYTES_IF_BIGENDIAN (defined in SVN platforms/Cross/vm/sqMemoryAccess.h)
   But this is necessary only for arithmetic ops (+ - * / < > ...)
   For bit ops or copy, there is no need to swap bytes, so direct access to pointer is used.

Other than that I renamed a few messages
cDigitOfCSI:at: -> digitOfCSI:at:
cDigitLengthOfCSI: -> digitSizeOfCSI:
This was to have a better symetry with digitOfLargeInt:at: digitSizeOfLargeInt:


Slang:
Use the new macro SQ_SWAP_4/8_BYTES_IF_BIGENDIAN to factor out
proliferation of cppIf: VMBIGENDIAN.

Memory is 8 bytes aligned on Spur. When storing 32/64 bits large
integers values, allways fill the eight bytes whatever the
effectivily used size, rather than bother with dissertion of size.

Prepare the same change for fetching 32/64 LargeIntegers values on
SpurVM, but comment it out for now as it's unclear whether those
oversize bytes are effectivly zero for extant LargeIntegers.

Fix generation of byteSwapped in v3.

Go the extra quarter-mile and define an optional primitive as the
fast primitive fail code (null pointer) so that unselected optional
primitives are in the prmitiveTable as fast primitive fails.

Changes to get the RegisterAllocatingCogit to compile.  The struct
classes must be generated in the order specified in the Cogit's
ancilliaryClasses since the structs referent each other and the
first must precede the referers.  CogSimStackEntry and subclasses
get SimStackEntry as their struct name.  The ancilliary classes must
include the most specific fixup and simstackentry classes only.

Factor out the duplicated code generating C integer literals.
Generate sqInt literals as 0x123ULL so that they're valid in
64-bit compiles as well as 32-bit.


Mac OS Builds:
Don't link with -fvisibility=hidden; it breaks external plugins. Use
-fvisibility=default instead.

Modified Paths:
--------------
    branches/Cog/build.macos32x86/common/Makefile.flags
    branches/Cog/build.macos64x64/common/Makefile.flags
    branches/Cog/build.macos64x64/common/Makefile.rules
    branches/Cog/image/LoadSistaSupport.st
    branches/Cog/image/buildsistareaderimage.sh
    branches/Cog/nsspur64src/vm/cogit.h
    branches/Cog/nsspur64src/vm/cogitX64.c
    branches/Cog/nsspur64src/vm/cogmethod.h
    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/cogmethod.h
    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/scripts/lastCheckin
    branches/Cog/spur64src/vm/cogit.h
    branches/Cog/spur64src/vm/cogitX64.c
    branches/Cog/spur64src/vm/cogmethod.h
    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/cogmethod.h
    branches/Cog/spursistasrc/vm/cointerp.c
    branches/Cog/spursistasrc/vm/cointerp.h
    branches/Cog/spursistasrc/vm/gcc3x-cointerp.c
    branches/Cog/spursrc/vm/cogit.h
    branches/Cog/spursrc/vm/cogitARMv5.c
    branches/Cog/spursrc/vm/cogitIA32.c
    branches/Cog/spursrc/vm/cogitMIPSEL.c
    branches/Cog/spursrc/vm/cogmethod.h
    branches/Cog/spursrc/vm/cointerp.c
    branches/Cog/spursrc/vm/cointerp.h
    branches/Cog/spursrc/vm/gcc3x-cointerp.c
    branches/Cog/spurstack64src/vm/gcc3x-interp.c
    branches/Cog/spurstack64src/vm/interp.c
    branches/Cog/spurstacksrc/vm/gcc3x-interp.c
    branches/Cog/spurstacksrc/vm/interp.c
    branches/Cog/src/plugins/ADPCMCodecPlugin/ADPCMCodecPlugin.c
    branches/Cog/src/plugins/AsynchFilePlugin/AsynchFilePlugin.c
    branches/Cog/src/plugins/B2DPlugin/B2DPlugin.c
    branches/Cog/src/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.c
    branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c
    branches/Cog/src/plugins/BochsIA32Plugin/BochsIA32Plugin.c
    branches/Cog/src/plugins/BochsX64Plugin/BochsX64Plugin.c
    branches/Cog/src/plugins/CameraPlugin/CameraPlugin.c
    branches/Cog/src/plugins/CroquetPlugin/CroquetPlugin.c
    branches/Cog/src/plugins/DSAPrims/DSAPrims.c
    branches/Cog/src/plugins/FFTPlugin/FFTPlugin.c
    branches/Cog/src/plugins/FilePlugin/FilePlugin.c
    branches/Cog/src/plugins/FloatArrayPlugin/FloatArrayPlugin.c
    branches/Cog/src/plugins/GdbARMPlugin/GdbARMPlugin.c
    branches/Cog/src/plugins/GeniePlugin/GeniePlugin.c
    branches/Cog/src/plugins/IA32ABI/IA32ABI.c
    branches/Cog/src/plugins/JPEGReaderPlugin/JPEGReaderPlugin.c
    branches/Cog/src/plugins/JoystickTabletPlugin/JoystickTabletPlugin.c
    branches/Cog/src/plugins/Klatt/Klatt.c
    branches/Cog/src/plugins/LargeIntegers/LargeIntegers.c
    branches/Cog/src/plugins/MacMenubarPlugin/MacMenubarPlugin.c
    branches/Cog/src/plugins/Matrix2x3Plugin/Matrix2x3Plugin.c
    branches/Cog/src/plugins/MiscPrimitivePlugin/MiscPrimitivePlugin.c
    branches/Cog/src/plugins/RePlugin/RePlugin.c
    branches/Cog/src/plugins/ScratchPlugin/ScratchPlugin.c
    branches/Cog/src/plugins/SocketPlugin/SocketPlugin.c
    branches/Cog/src/plugins/SoundGenerationPlugin/SoundGenerationPlugin.c
    branches/Cog/src/plugins/SoundPlugin/SoundPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/IA32FFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c
    branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c
    branches/Cog/src/plugins/StarSqueakPlugin/StarSqueakPlugin.c
    branches/Cog/src/plugins/UnicodePlugin/UnicodePlugin.c
    branches/Cog/src/plugins/VMProfileLinuxSupportPlugin/VMProfileLinuxSupportPlugin.c
    branches/Cog/src/plugins/VMProfileMacSupportPlugin/VMProfileMacSupportPlugin.c
    branches/Cog/src/plugins/WeDoPlugin/WeDoPlugin.c
    branches/Cog/src/plugins/Win32OSProcessPlugin/Win32OSProcessPlugin.c
    branches/Cog/src/plugins/ZipPlugin/ZipPlugin.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/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/stacksrc/vm/gcc3x-interp.c
    branches/Cog/stacksrc/vm/interp.c

Added Paths:
-----------
    branches/Cog/scripts/indentit

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

Modified: branches/Cog/build.macos32x86/common/Makefile.flags
===================================================================
--- branches/Cog/build.macos32x86/common/Makefile.flags	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/build.macos32x86/common/Makefile.flags	2016-04-19 18:21:14 UTC (rev 3672)
@@ -14,7 +14,7 @@
 CFLAGS:=$(CFLAGS) -DBUILD_FOR_OSX=1 \
 		-arch $(TARGET_ARCH) \
 		-mmacosx-version-min=$(TARGET_VERSION_MIN) -msse4.2 \
-			-fvisibility=hidden -fwrapv \
+			-fvisibility=default -fwrapv \
 			-fmacro-backtrace-limit=0 -fdiagnostics-show-note-include-stack \
 			-fmessage-length=0 -fpascal-strings -fasm-blocks -fstrict-aliasing \
 		-isysroot $(SDK) \

Modified: branches/Cog/build.macos64x64/common/Makefile.flags
===================================================================
--- branches/Cog/build.macos64x64/common/Makefile.flags	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/build.macos64x64/common/Makefile.flags	2016-04-19 18:21:14 UTC (rev 3672)
@@ -14,7 +14,7 @@
 CFLAGS:=$(CFLAGS) -DBUILD_FOR_OSX=1 \
 		-arch $(TARGET_ARCH) \
 		-mmacosx-version-min=$(TARGET_VERSION_MIN) -msse4.2 \
-			-fvisibility=hidden -fwrapv \
+			-fvisibility=default -fwrapv \
 			-fmacro-backtrace-limit=0 -fdiagnostics-show-note-include-stack \
 			-fmessage-length=0 -fpascal-strings -fasm-blocks -fstrict-aliasing \
 		-isysroot $(SDK) \

Modified: branches/Cog/build.macos64x64/common/Makefile.rules
===================================================================
--- branches/Cog/build.macos64x64/common/Makefile.rules	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/build.macos64x64/common/Makefile.rules	2016-04-19 18:21:14 UTC (rev 3672)
@@ -13,7 +13,6 @@
 
 DEPFLAGS = -MT $@ -MMD -MP -MF deps/$(*F).Td
 ALLFLAGS = $(DEPFLAGS) $(WARNINGS) $(CFLAGS)
-#POSTCOMPILE = mv -f deps/$(*F).Td deps/$(*F).d
 POSTCOMPILE = sed '/^$$/d' <deps/$(*F).Td | sed '/^.*:$$/d' | sed 's/^build[^/]*/$$(BUILD)/' > deps/$(*F).d; rm deps/$(*F).Td; touch -r $< deps/$(*F).d
 
 $(OBJDIR)/%.o: %.c deps/%.d

Modified: branches/Cog/image/LoadSistaSupport.st
===================================================================
--- branches/Cog/image/LoadSistaSupport.st	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/image/LoadSistaSupport.st	2016-04-19 18:21:14 UTC (rev 3672)
@@ -35,4 +35,8 @@
 				ex resume]]]
 		valueWithArguments: tuple].
 
+CompiledMethod installSecondaryBytecodeSet: (Smalltalk classNamed: #EncoderForSistaV1).
+
+FullBlockClosure tryPrimitive: 161 withArgs: #(38 true).
+
 Smalltalk snapshot: true andQuit: true
Modified: branches/Cog/image/buildsistareaderimage.sh
===================================================================
--- branches/Cog/image/buildsistareaderimage.sh	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/image/buildsistareaderimage.sh	2016-04-19 18:21:14 UTC (rev 3672)
@@ -10,7 +10,11 @@
 cp -p trunk50.image sistareader.image
 cp -p trunk50.changes sistareader.changes
 
+if test -n "$1"; then
+	VM="$1"
+else
 . ./getGoodSpurVM.sh
+fi
 
 echo $VM sistareader.image LoadSistaSupport.st
 $VM sistareader.image LoadSistaSupport.st

Modified: branches/Cog/nsspur64src/vm/cogit.h
===================================================================
--- branches/Cog/nsspur64src/vm/cogit.h	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/nsspur64src/vm/cogit.h	2016-04-19 18:21:14 UTC (rev 3672)
@@ -1,5 +1,5 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1756 uuid: 141cf0f3-955a-486f-8082-decbc14645d7
+	CCodeGenerator VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
  */
 
 
@@ -152,4 +152,6 @@
 #define setCStackPointer(theSP) (CStackPointer = (void *)(theSP))
 #define tryLockVMOwner() (ceTryLockVMOwner() != 0)
 #define unlockVMOwner() ceUnlockVMOwner()
+#define fullBlockEntryOffset() "cbEntryOffset"
+#define fullBlockNoContextSwitchEntryOffset() "cbNoSwitchEntryOffset"
 

Modified: branches/Cog/nsspur64src/vm/cogitX64.c
===================================================================
--- branches/Cog/nsspur64src/vm/cogitX64.c	2016-04-09 00:17:14 UTC (rev 3671)
+++ branches/Cog/nsspur64src/vm/cogitX64.c	2016-04-19 18:21:14 UTC (rev 3672)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1756 uuid: 141cf0f3-955a-486f-8082-decbc14645d7
+	CCodeGenerator VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1756 uuid: 141cf0f3-955a-486f-8082-decbc14645d7
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1756 uuid: 141cf0f3-955a-486f-8082-decbc14645d7 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1822 uuid: f18408b3-d8bb-4ac7-9d7d-b37ace026619 " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -82,6 +82,12 @@
 #define DPFPReg1 1
 #define DPFPReg2 2
 #define EncounteredUnknownBytecode -6
+#define Extra0Reg 10
+#define Extra1Reg 11
+#define Extra2Reg 12
+#define Extra3Reg 13
+#define Extra4Reg 14
+#define Extra5Reg 15
 #define Fill32 4
 #define FirstAnnotation 64
 #define FirstJump 11
@@ -209,6 +215,8 @@
 #define MoveXwrRR 47
 #define MULTIPLEBYTECODESETS 1
 #define MulRdRd 112
+#define NeedsMergeFixupFlag 2
+#define NeedsNonMergeFixupFlag 1
 #define NegateR 79
 #define NewspeakVM 1
 #define Nop 5
@@ -260,8 +268,6 @@
 #define RotateRightCqR 87
 #define RSI 6
 #define RSP 4
-#define Scratch0Reg 10
-#define Scratch1Reg 11
 #define SelectorCannotInterpret 34
 #define SelectorDoesNotUnderstand 20
 #define SenderIndex 0
@@ -270,9 +276,13 @@
 #define SIB1 0
 #define SIB4 2
 #define SIB8 3
+#define SistaV1BytecodeSet 0
 #define SistaVM 0
 #define SmallContextSlots 22
 #define SPReg 4
+#if !defined(SPURVM) /* Allow this to be overridden on the compiler command line */
+# define SPURVM 1
+#endif
 #define SpecialSelectors 23
 #define SqrtRd 114
 #define SSBaseOffset 1
@@ -289,6 +299,7 @@
 #define TstCqR 99
 #define UnfailingPrimitive 3
 #define UnimplementedPrimitive -7
+#define UnknownSimStackPtrFlag -2
 #define ValueIndex 1
 #define VarBaseReg 3
 #define XCHGRR 128
@@ -358,6 +369,19 @@
 
 
 typedef struct {
+	char	type;
+	char	spilled;
+	sqInt	annotateUse;
+	sqInt	registerr;
+	sqInt	offset;
+	sqInt	constant;
+	sqInt	bcptr;
+ } SimStackEntry;
+
+#define CogSimStackEntry SimStackEntry
+
+
+typedef struct {
 	AbstractInstruction *targetInstruction;
 	sqInt	instructionIndex;
 	sqInt	simStackPtr;
@@ -368,17 +392,6 @@
 
 
 typedef struct {
-	char	type;
-	char	spilled;
-	char	annotateUse;
-	sqInt	registerr;
-	sqInt	offset;
-	sqInt	constant;
-	sqInt	bcptr;
- } CogSimStackEntry;
-
-
-typedef struct {
 	sqInt	isReceiverResultRegLive;
 	CogSimStackEntry *ssEntry;
  } CogSSOptStatus;
@@ -403,7 +416,6 @@
 #endif
 
 static AbstractInstruction * NoDbgRegParms addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *anInstruction);
-static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask);
 static AbstractInstruction * NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral);
 static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress);
 static AbstractInstruction * NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister);
@@ -420,6 +432,7 @@
 static sqInt NoDbgRegParms rewriteConditionalJumpLongAttarget(AbstractInstruction * self_in_rewriteConditionalJumpLongAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress);
 static sqInt NoDbgRegParms setLabelOffset(AbstractInstruction * self_in_setLabelOffset, sqInt aValue);
 static AbstractInstruction * NoDbgRegParms updateLabel(AbstractInstruction * self_in_updateLabel, AbstractInstruction *labelInstruction);
+static sqInt NoDbgRegParms wantsNearAddressFor(AbstractInstruction * self_in_wantsNearAddressFor, sqInt anObject);
 static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod);
 static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch);
 static sqInt NoDbgRegParms isUnconditionalBranch(BytecodeDescriptor * self_in_isUnconditionalBranch);
@@ -495,6 +508,7 @@
 static sqInt NoDbgRegParms compilePICAbort(sqInt numArgs);
 static void NoDbgRegParms compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt regMask, sqInt pushLinkReg, sqInt resultRegOrNone);
 static void computeEntryOffsets(void);
+static void computeFullBlockEntryOffsets(void);
 static void computeMaximumSizes(void);
 static sqInt NoDbgRegParms configureCPICCase0Case1MethodtagisMNUCasenumArgsdelta(CogMethod *cPIC, CogMethod *case0CogMethod, sqInt case1Method, sqInt case1Tag, sqInt isMNUCase, sqInt numArgs, sqInt addrDelta);
 static sqInt NoDbgRegParms configureMNUCPICmethodOperandnumArgsdelta(CogMethod *cPIC, sqInt methodOperand, sqInt numArgs, sqInt addrDelta);
@@ -516,6 +530,7 @@
 static sqInt NoDbgRegParms findMapLocationForMcpcinMethod(sqInt targetMcpc, CogMethod *cogMethod);
 extern CogBlockMethod * findMethodForStartBcpcinHomeMethod(sqInt startbcpc, CogMethod *cogMethod);
 static sqInt NoDbgRegParms findIsBackwardBranchMcpcBcpcMatchingMcpc(BytecodeDescriptor *descriptor, sqInt isBackwardBranch, char *mcpc, sqInt bcpc, void *targetMcpc);
+static sqInt NoDbgRegParms firstMappedPCFor(CogMethod *cogMethod);
 extern void followForwardedLiteralsIn(CogMethod *cogMethod);
 extern void followForwardedMethods(void);
 static sqInt NoDbgRegParms followMaybeObjRefInClosedPICAt(sqInt mcpc);
@@ -624,6 +639,7 @@
 extern sqInt patchToOpenPICFornumArgsreceiver(sqInt selector, sqInt numArgs, sqInt receiver);
 static sqInt picAbortDiscriminatorValue(void);
 static sqInt picInterpretAbortOffset(void);
+static void preenMethodLabel(void);
 static AbstractInstruction * previousInstruction(void);
 extern void printCogMethodFor(void *address);
 extern void printPCMapPairsFor(CogMethod *cogMethod);
@@ -677,6 +693,7 @@
 static void compactCompiledCode(void);
 static void NoDbgRegParms ensureInYoungReferrers(CogMethod *cogMethod);
 static CogMethod * NoDbgRegParms findPreviouslyCompiledVersionOfwith(sqInt aMethodObj, sqInt aSelectorOop);
+static void followForwardedLiteralsInOpenPICList(void);
 extern void freeMethod(CogMethod *cogMethod);
 static void freeOlderMethodsForCompaction(void);
 static sqInt kosherYoungReferrers(void);
@@ -867,12 +884,15 @@
 static sqInt NoDbgRegParms remapOop(sqInt objOop);
 static sqInt NoDbgRegParms shouldAnnotateObjectReference(sqInt anOop);
 static sqInt NoDbgRegParms slotOffsetOfInstVarIndex(sqInt index);
-static CogSimStackEntry * NoDbgRegParms ensureSpilledAtfrom(CogSimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister);
-static CogSimStackEntry * NoDbgRegParms mergeAtfrom(CogSimStackEntry * self_in_mergeAtfrom, sqInt baseOffset, sqInt baseRegister);
-static CogSimStackEntry * NoDbgRegParms popToReg(CogSimStackEntry * self_in_popToReg, sqInt reg);
-static sqInt NoDbgRegParms registerMask(CogSimStackEntry * self_in_registerMask);
-static sqInt NoDbgRegParms registerOrNone(CogSimStackEntry * self_in_registerOrNone);
-static CogSimStackEntry * NoDbgRegParms storeToReg(CogSimStackEntry * self_in_storeToReg, sqInt reg);
+static SimStackEntry * NoDbgRegParms ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister);
+static SimStackEntry * NoDbgRegParms popToReg(SimStackEntry * self_in_popToReg, sqInt reg);
+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);
@@ -953,7 +973,6 @@
 static sqInt extendedStoreAndPopBytecode(void);
 static sqInt extendedStoreBytecode(void);
 static sqInt NoDbgRegParms frameOffsetOfTemporary(sqInt index);
-static sqInt genBlockReturn(void);
 static AbstractInstruction * NoDbgRegParms genDoubleFailIfZeroArgRcvrarg(sqInt rcvrReg, sqInt argReg);
 static sqInt genExtendedSendBytecode(void);
 static sqInt genExtendedSuperBytecode(void);
@@ -1031,7 +1050,6 @@
 static PrimitiveDescriptor * primitiveGeneratorOrNil(void);
 extern void recordCallOffsetIn(CogMethod *cogMethod);
 static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask);
-static sqInt returnRegForStoreCheck(void);
 extern void rewritePrimInvocationInto(CogMethod *cogMethod, void (*primFunctionPointer)(void));
 static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj);
 static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj);
@@ -1045,7 +1063,6 @@
 static void NoDbgRegParms adjustArgumentsForPerform(sqInt numArgs);
 static sqInt NoDbgRegParms allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask);
 static sqInt NoDbgRegParms allocateRegNotConflictingWith(sqInt regMask);
-static void NoDbgRegParms annotateBytecodeIfAnnotated(CogSimStackEntry *aSimStackEntry);
 static sqInt NoDbgRegParms anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n);
 extern void callCogCodePopReceiverArg0Regs(void);
 extern void callCogCodePopReceiverArg1Arg0Regs(void);
@@ -1064,6 +1081,7 @@
 static void ensureReceiverResultRegContainsSelf(void);
 static void NoDbgRegParms evaluateat(BytecodeDescriptor *descriptor, sqInt pc);
 static sqInt NoDbgRegParms freeAnyRegNotConflictingWith(sqInt regMask);
+static sqInt genBlockReturn(void);
 static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void) ;
 static sqInt genCallPrimitiveBytecode(void);
 static sqInt NoDbgRegParms genEqualsEqualsNoBranchArgIsConstantrcvrIsConstantargRegrcvrReg(sqInt argIsConstant, sqInt rcvrIsConstant, sqInt argReg, sqInt rcvrRegOrNone);
@@ -1110,9 +1128,13 @@
 static sqInt genSpecialSelectorEqualsEqualsWithForwarders(void);
 static sqInt genStaticallyResolvedSpecialSelectorComparison(void);
 static sqInt NoDbgRegParms genStorePopLiteralVariable(sqInt popBoolean, sqInt litVarIndex);
+static sqInt NoDbgRegParms genStorePopLiteralVariableneedsStoreCheck(sqInt popBoolean, sqInt litVarIndex, sqInt needsStoreCheck);
 static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariable(sqInt popBoolean, sqInt slotIndex);
+static sqInt NoDbgRegParms genStorePopMaybeContextReceiverVariableneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck);
 static sqInt NoDbgRegParms genStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex);
+static sqInt NoDbgRegParms genStorePopReceiverVariableneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck);
 static sqInt NoDbgRegParms genStorePopRemoteTempAt(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex);
+static sqInt NoDbgRegParms genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex, sqInt needsStoreCheck);
 static sqInt NoDbgRegParms genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex);
 static sqInt genUpArrowReturn(void);
 static BytecodeFixup * NoDbgRegParms initializeFixupAt(sqInt targetIndex);
@@ -1122,7 +1144,7 @@
 static sqInt liveRegisters(void);
 static void NoDbgRegParms marshallAbsentReceiverSendArguments(sqInt numArgs);
 static void NoDbgRegParms marshallSendArguments(sqInt numArgs);
-static void NoDbgRegParms mergeafterContinuation(BytecodeFixup *fixup, sqInt mergeWithContinuation);
+static sqInt NoDbgRegParms mergeWithFixupIfRequired(BytecodeFixup *fixup);
 static sqInt NoDbgRegParms methodAbortTrampolineFor(sqInt numArgs);
 static sqInt NoDbgRegParms needsFrameIfExtBGT2(sqInt stackDelta);
 static sqInt NoDbgRegParms needsFrameIfMod16GENumArgs(sqInt stackDelta);
@@ -1148,14 +1170,14 @@
 static sqInt NoDbgRegParms ssPushAnnotatedConstant(sqInt literal);
 static sqInt NoDbgRegParms ssPushBaseoffset(sqInt reg, sqInt offset);
 static sqInt NoDbgRegParms ssPushConstant(sqInt literal);
-static sqInt NoDbgRegParms ssPushDesc(CogSimStackEntry simStackEntry);
+static sqInt NoDbgRegParms ssPushDesc(SimStackEntry simStackEntry);
 static sqInt NoDbgRegParms ssPushRegister(sqInt reg);
 static void NoDbgRegParms ssPush(sqInt n);
 static void NoDbgRegParms ssStoreAndReplacePoptoReg(sqInt popBoolean, sqInt reg);
 static sqInt NoDbgRegParms ssStorePoptoPreferredReg(sqInt popBoolean, sqInt preferredReg);
 static void NoDbgRegParms ssStorePoptoReg(sqInt popBoolean, sqInt reg);
 static CogSimStackEntry * ssTop(void);
-static CogSimStackEntry ssTopDescriptor(void);
+static SimStackEntry ssTopDescriptor(void);
 static CogSimStackEntry * NoDbgRegParms ssValue(sqInt n);
 static sqInt NoDbgRegParms tryCollapseTempVectorInitializationOfSize(sqInt slots);
 static void updateSimSpillBase(void);
@@ -1185,6 +1207,8 @@
 void * CFramePointer;
 void * CStackPointer;
 static sqInt callerSavedRegMask;
+static sqInt cbEntryOffset;
+static sqInt cbNoSwitchEntryOffset;
 sqInt ceBaseFrameReturnTrampoline;
 void (*ceCall0ArgsPIC)(void);
 void (*ceCall1ArgsPIC)(void);
@@ -1260,6 +1284,8 @@
 static sqInt firstCPICCaseOffset;
 static sqInt firstSend;
 static BytecodeFixup * fixups;
+static AbstractInstruction * fullBlockEntry;
+static AbstractInstruction * fullBlockNoContextSwitchEntry;
 static BytecodeDescriptor generatorTable[512] = {
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
 	{ genPushReceiverVariableBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0 },
@@ -1827,7 +1853,7 @@
 static AbstractInstruction * sendMiss;
 static CogSimStackEntry simSelf;
 static sqInt simSpillBase;
-static CogSimStackEntry simStack[77];
+static SimStackEntry simStack[70];
 static sqInt simStackPtr;
 static AbstractInstruction * stackCheckLabel;
 static AbstractInstruction * stackOverflowCall;
@@ -1902,6 +1928,8 @@
 #define unalignedLong32Atput(inst,byteAddress,aWord) long32Atput(byteAddress,aWord)
 #define unalignedLongAt(byteAddress) longAt(byteAddress)
 #define unalignedLongAtput(byteAddress,aWord) longAtput(byteAddress,aWord)
+#define fullBlockEntryOffset() "cbEntryOffset"
+#define fullBlockNoContextSwitchEntryOffset() "cbNoSwitchEntryOffset"
 #define fixupAt(index) (&fixups[index])
 #define simStackAt(index) (simStack + (index))
 #define traceDescriptor(ign) 0
@@ -1931,33 +1959,6 @@
 }
 
 
-/*	Answer an unused abstract register in the liveRegMask.
-	Subclasses with more registers can override to answer them. */
-
-	/* CogAbstractInstruction>>#availableRegisterOrNoneFor: */
-static sqInt NoDbgRegParms
-availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask)
-{
-	flag("searching physical registers that are not assigned to abstract registers first will do a better job and allocate with fewer conflicts.  But this will be much easier if we use the same range for concrete and abstract registers (0-N) and simply number abstract registers the same as their corresponding concrete registers.");
-	if (!(liveRegsMask & (1LL << Arg1Reg))) {
-		return Arg1Reg;
-	}
-	if (!(liveRegsMask & (1LL << Arg0Reg))) {
-		return Arg0Reg;
-	}
-	if (!(liveRegsMask & (1LL << SendNumArgsReg))) {
-		return SendNumArgsReg;
-	}
-	if (!(liveRegsMask & (1LL << ClassReg))) {
-		return ClassReg;
-	}
-	if (!(liveRegsMask & (1LL << ReceiverResultReg))) {
-		return ReceiverResultReg;
-	}
-	return NoReg;
-}
-
-
 /*	For out-of-line literal support, clone a literal from a literal. */
 
 	/* CogAbstractInstruction>>#cloneLiteralFrom: */
@@ -2177,6 +2178,20 @@
 	return self_in_updateLabel;
 }
 
+
+/*	A hack hook to allow ARM to override the simulated address for the
+	short-cut trampolines,
+	and to allow x64 to address CStackPointer and CFramePointer relative to
+	VarBaseReg. 
+ */
+
+	/* CogAbstractInstruction>>#wantsNearAddressFor: */
+static sqInt NoDbgRegParms
+wantsNearAddressFor(AbstractInstruction * self_in_wantsNearAddressFor, sqInt anObject)
+{
+	return 0;
+}
+
 	/* CogBlockMethod>>#cmHomeMethod */
 static CogMethod * NoDbgRegParms
 cmHomeMethod(CogBlockMethod * self_in_cmHomeMethod)
@@ -3651,7 +3666,7 @@
 closedPICRefersToUnmarkedObject(CogMethod *cPIC)
 {
     sqInt i;
-    usqInt object;
+    sqInt object;
     sqInt pc;
 
 	if (!((isImmediate((cPIC->selector)))
@@ -3831,7 +3846,7 @@
 		if (isMNUCase) {
 
 			/* this is an MNU so tag the CPIC header and setup a jump to the MNUAbort */
-			(cPIC->cpicHasMNUCase = 1);
+			(cPIC->cpicHasMNUCaseOrCMIsFullBlock) = 1;
 			target = (((sqInt)cPIC)) + (sizeof(CogMethod));
 		}
 		else {
@@ -3853,6 +3868,14 @@
 void
 cogitPostGCAction(sqInt gcMode)
 {
+	
+#  if SPURVM
+	if (gcMode == GCModeBecome) {
+		followForwardedLiteralsInOpenPICList();
+	}
+
+#  endif /* SPURVM */
+
 	assert(allMethodsHaveCorrectHeader());
 	assert(((gcMode & (GCModeFull + GCModeNewSpace)) == 0)
 	 || (kosherYoungReferrers()));
@@ -3964,7 +3987,7 @@
 	(pic->cmNumArgs = numArgs);
 	(pic->cmRefersToYoung = 0);
 	(pic->cmUsageCount = initialClosedPICUsageCount());
-	(pic->cpicHasMNUCase = 1);
+	(pic->cpicHasMNUCaseOrCMIsFullBlock) = 1;
 	(pic->cPICNumCases = 1);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMClosedPIC);
@@ -4033,7 +4056,7 @@
 		addToYoungReferrers(pic);
 	}
 	(pic->cmUsageCount = initialOpenPICUsageCount());
-	(pic->cpicHasMNUCase = 0);
+	(pic->cpicHasMNUCaseOrCMIsFullBlock) = 0;
 	(pic->cPICNumCases = 0);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMOpenPIC);
@@ -4084,7 +4107,7 @@
 	(pic->cmNumArgs = numArgs);
 	(pic->cmRefersToYoung = 0);
 	(pic->cmUsageCount = initialClosedPICUsageCount());
-	(pic->cpicHasMNUCase = isMNUCase);
+	(pic->cpicHasMNUCaseOrCMIsFullBlock) = isMNUCase;
 	(pic->cPICNumCases = 2);
 	(pic->blockEntryOffset = 0);
 	assert(((pic->cmType)) == CMClosedPIC);
@@ -4642,6 +4665,20 @@
 }
 
 
+/*	Generate the entry code for a method to determine cmEntryOffset and
+	cmNoCheckEntryOffset. We
+	need cmNoCheckEntryOffset up front to be able to generate the map starting
+	from cmNoCheckEntryOffset */
+/*	stack allocate the various collections so that they
+	are effectively garbage collected on return. */
+
+	/* Cogit>>#computeFullBlockEntryOffsets */
+static void
+computeFullBlockEntryOffsets(void)
+{
+	}
+
+
 /*	This pass assigns maximum sizes to all abstract instructions and
 	eliminates jump fixups.
 	It hence assigns the maximum address an instruction will occur at which
@@ -5146,7 +5183,7 @@
 		addToYoungReferrers(method);
 	}
 	(method->cmUsageCount = initialMethodUsageCount());
-	(method->cpicHasMNUCase = 0);
+	(method->cpicHasMNUCaseOrCMIsFullBlock) = 0;
 	(method->cmUsesPenultimateLit = maxLitIndex >= ((literalCountOfMethodHeader(methodHeader)) - 2));
 	(method->blockEntryOffset = (blockEntryLabel != null
 		? ((blockEntryLabel->address)) - (((sqInt)method))
@@ -5188,7 +5225,9 @@
     sqInt mapByte;
     sqInt mcpc;
 
-	mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+	mcpc = (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 	map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	if (mcpc == targetMcpc) {
 		return map;
@@ -5252,6 +5291,15 @@
 		: 0);
 }
 
+	/* Cogit>>#firstMappedPCFor: */
+static sqInt NoDbgRegParms
+firstMappedPCFor(CogMethod *cogMethod)
+{
+	return (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
+}
+
 	/* Cogit>>#followForwardedLiteralsIn: */
 void
 followForwardedLiteralsIn(CogMethod *cogMethod)
@@ -5262,7 +5310,8 @@
     sqInt mcpc;
     sqInt result;
 
-	assert(!(isForwarded((cogMethod->methodObject))));
+	assert((((cogMethod->cmType)) != CMMethod)
+	 || (!(isForwarded((cogMethod->methodObject)))));
 	if (shouldRemapOop((cogMethod->selector))) {
 		(cogMethod->selector = remapObj((cogMethod->selector)));
 		if (isYoung((cogMethod->selector))) {
@@ -5270,7 +5319,9 @@
 		}
 	}
 	/* begin mapFor:performUntil:arg: */
-	mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+	mcpc = (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 	map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	enumeratingCogMethod = cogMethod;
 
@@ -5848,12 +5899,12 @@
 generateMapAtstart(sqInt addressOrNull, sqInt startAddress)
 {
     unsigned char annotation;
-    sqInt delta;
+    usqInt delta;
     sqInt i;
     AbstractInstruction *instruction;
     sqInt length;
-    sqInt location;
-    sqInt mapEntry;
+    usqInt location;
+    usqInt mapEntry;
     sqInt maxDelta;
     usqInt mcpc;
 
@@ -6711,6 +6762,7 @@
 	generateStackPointerCapture();
 	generateTrampolines();
 	computeEntryOffsets();
+	computeFullBlockEntryOffsets();
 	generateClosedPICPrototype();
 	manageFromto(methodZoneBase, endAddress);
 	generateOpenPICPrototype();
@@ -7064,7 +7116,7 @@
 	end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	while ((byteAt(end)) != MapEnd) {
 		end -= 1;
-		assert(end > ((((sqInt)cogMethod)) + cmNoCheckEntryOffset));
+		assert(end > (firstMappedPCFor(cogMethod)));
 	}
 	return end;
 }
@@ -7082,7 +7134,9 @@
     sqInt mcpc;
     sqInt result;
 
-	mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+	mcpc = (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 	map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	enumeratingCogMethod = cogMethod;
 
@@ -7238,7 +7292,9 @@
 					}
 				}
 				/* begin mapFor:performUntil:arg: */
-				mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+				mcpc = (0
+					? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+					: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 				map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 				enumeratingCogMethod = cogMethod;
 
@@ -7320,7 +7376,9 @@
 					(cogMethod->methodObject = remapOop((cogMethod->methodObject)));
 				}
 				/* begin mapFor:performUntil:arg: */
-				mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+				mcpc = (0
+					? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+					: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 				map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 				enumeratingCogMethod = cogMethod;
 
@@ -7411,7 +7469,9 @@
 					}
 				}
 				/* begin mapFor:performUntil:arg: */
-				mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+				mcpc = (0
+					? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+					: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 				map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 				enumeratingCogMethod = cogMethod;
 
@@ -7529,7 +7589,9 @@
 
 
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -7573,7 +7635,9 @@
 
 
 			/* begin mapFor:performUntil:arg: */
-			mcpc1 = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc1 = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map1 = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -7677,7 +7741,9 @@
 
 
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -7988,7 +8054,9 @@
 		: cmHomeMethod(aCogMethod));
 	(cogMethod->cmUsageCount = CMMaxUsageCount);
 	/* begin mapFor:performUntil:arg: */
-	mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+	mcpc = (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 	map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	enumeratingCogMethod = cogMethod;
 
@@ -8509,6 +8577,22 @@
 	return (interpretOffset()) - (callInstructionByteSize(backEnd));
 }
 
+
+/*	The methodLabel serves as the reference to the start of the current code
+	object being produced (CMMethod, CMClosedPIC etc), but it also carries
+	type flags for
+	the frame method field, set via the labelOffset. So we must clean the
+	flags on each
+	compilation to avoid stale lags being left behind from previous
+	compilations.  */
+
+	/* Cogit>>#preenMethodLabel */
+static void
+preenMethodLabel(void)
+{
+	setLabelOffset(methodLabel, 0);
+}
+
 	/* Cogit>>#previousInstruction */
 static AbstractInstruction *
 previousInstruction(void)
@@ -8543,7 +8627,9 @@
     sqInt mcpc;
     sqInt value;
 
-	mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+	mcpc = (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 	map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	while (((mapByte = byteAt(map))) != MapEnd) {
 		annotation = ((usqInt) mapByte) >> AnnotationShift;
@@ -8730,7 +8816,9 @@
 		: picAbortTrampolineFor((cogMethod->cmNumArgs)))));
 	relocateCallBeforeReturnPCby(backEnd, (((sqInt)cogMethod)) + missOffset, -callDelta);
 	/* begin mapFor:performUntil:arg: */
-	mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+	mcpc = (0
+		? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+		: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 	map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 	enumeratingCogMethod = cogMethod;
 
@@ -9299,7 +9387,9 @@
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -9741,7 +9831,9 @@
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -9817,7 +9909,7 @@
 	if (isMNUSelector) {
 		while (cogMethod < (limitZony())) {
 			if (((cogMethod->cmType)) != CMFree) {
-				if ((cogMethod->cpicHasMNUCase)) {
+				if ((cogMethod->cpicHasMNUCaseOrCMIsFullBlock)) {
 					assert(((cogMethod->cmType)) == CMClosedPIC);
 					freeMethod(cogMethod);
 					mustScanAndUnlink = 1;
@@ -9854,7 +9946,9 @@
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -9913,7 +10007,9 @@
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -9986,7 +10082,9 @@
 	while (cogMethod < (limitZony())) {
 		if (((cogMethod->cmType)) == CMMethod) {
 			/* begin mapFor:performUntil:arg: */
-			mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset;
+			mcpc = (0
+				? (((usqInt)cogMethod)) + cbNoSwitchEntryOffset
+				: (((usqInt)cogMethod)) + cmNoCheckEntryOffset);
 			map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1;
 			enumeratingCogMethod = cogMethod;
 
@@ -10291,6 +10389,19 @@
 	return null;
 }
 
+	/* CogMethodZone>>#followForwardedLiteralsInOpenPICList */
+static void
+followForwardedLiteralsInOpenPICList(void)
+{
+    CogMethod *openPIC;
+
+	openPIC = openPICList;
+	while (openPIC != null) {
+		followForwardedLiteralsIn(openPIC);
+		openPIC = ((CogMethod *) ((openPIC->nextOpenPIC)));
+	}
+}
+
 	/* CogMethodZone>>#freeMethod: */
 void
 freeMethod(CogMethod *cogMethod)
@@ -12724,8 +12835,8 @@
 	anInstruction12 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg);
 	/* begin JumpZero: */
 	jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0));
-	genGetClassObjectOfClassIndexintoscratchReg(formatReg, Scratch0Reg, TempReg);
-	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Scratch0Reg, formatReg);
+	genGetClassObjectOfClassIndexintoscratchReg(formatReg, Extra0Reg, TempReg);
+	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Extra0Reg, formatReg);
 	genConvertSmallIntegerToIntegerInReg(formatReg);
 	/* begin AndCq:R: */
 	quickConstant8 = fixedFieldsOfClassFormatMask();
@@ -12879,8 +12990,8 @@
 	anInstruction3 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, formatReg);
 	/* begin JumpZero: */
 	jumpIsContext = genConditionalBranchoperand(JumpZero, ((sqInt)0));
-	genGetClassObjectOfClassIndexintoscratchReg(formatReg, Scratch0Reg, TempReg);
-	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Scratch0Reg, formatReg);
+	genGetClassObjectOfClassIndexintoscratchReg(formatReg, Extra0Reg, TempReg);
+	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Extra0Reg, formatReg);
 	genConvertSmallIntegerToIntegerInReg(formatReg);
 	/* begin AndCq:R: */
 	quickConstant2 = fixedFieldsOfClassFormatMask();
@@ -13376,7 +13487,7 @@
 
 	/* Assume there's an available scratch register on 64-bit machines.  This holds the saved numFixedFields and then the value to fill with */
 	headerReg = SendNumArgsReg;
-	fillReg = Scratch0Reg;
+	fillReg = Extra0Reg;
 	assert(fillReg > 0);
 
 	/* The max slots we'll allocate here are those for a single header */
@@ -13807,7 +13918,7 @@
 
 	/* Assume there's an available scratch register on 64-bit machines.  This holds the saved numFixedFields and then the value to fill with */
 	headerReg = SendNumArgsReg;
-	fillReg = Scratch0Reg;
+	fillReg = Extra0Reg;
 	assert(fillReg > 0);
 
 	/* The max slots we'll allocate here are those for a single header */
@@ -14397,7 +14508,8 @@
 	It is called from the send trampolines.
 	If the selector index is negative, convert it into a positive index into
 	the special selectors array and index that. Otherwise, index the current
-	method.  */
+	method. The routine uses Extra0Reg & Extra1Reg, which are available, since
+	they are not live at point of send. */
 
 	/* CogObjectRepresentationFor64BitSpur>>#maybeGenerateSelectorIndexDereferenceRoutine */
 static void
@@ -14407,10 +14519,10 @@
     AbstractInstruction *anInstruction;
     AbstractInstruction *anInstruction1;
     AbstractInstruction *anInstruction10;
+    AbstractInstruction *anInstruction11;
+    AbstractInstruction *anInstruction12;
     AbstractInstruction *anInstruction2;
     AbstractInstruction *anInstruction3;
-    AbstractInstruction *anInstruction4;
-    AbstractInstruction *anInstruction5;
     AbstractInstruction *anInstruction6;
     AbstractInstruction *anInstruction7;
     AbstractInstruction *anInstruction8;
@@ -14427,32 +14539,32 @@
 	/* begin JumpLess: */
 	jumpNegative = genConditionalBranchoperand(JumpLess, ((sqInt)0));
 	/* begin MoveMw:r:R: */
-	anInstruction4 = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, Scratch0Reg);
+	anInstruction6 = genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, Extra0Reg);
 	/* begin AddCq:R: */
 	anInstruction1 = genoperandoperand(AddCqR, 2, ClassReg);
 	/* begin TstCq:R: */
-	anInstruction5 = genoperandoperand(TstCqR, MFMethodFlagIsBlockFlag, Scratch0Reg);
+	anInstruction7 = genoperandoperand(TstCqR, MFMethodFlagIsBlockFlag, Extra0Reg);
 	/* begin JumpZero: */
 	jumpNotBlock = genConditionalBranchoperand(JumpZero, ((sqInt)0));
 	/* begin AndCq:R: */
 	quickConstant = -(alignment());
 	/* begin gen:quickConstant:operand: */
-	anInstruction2 = genoperandoperand(AndCqR, quickConstant, Scratch0Reg);
+	anInstruction2 = genoperandoperand(AndCqR, quickConstant, Extra0Reg);
 	/* begin MoveM16:r:R: */
-	anInstruction6 = genoperandoperandoperand(MoveM16rR, 0, Scratch0Reg, Scratch1Reg);
+	anInstruction8 = genoperandoperandoperand(MoveM16rR, 0, Extra0Reg, Extra1Reg);
 	/* begin SubR:R: */
-	genoperandoperand(SubRR, Scratch1Reg, Scratch0Reg);
+	genoperandoperand(SubRR, Extra1Reg, Extra0Reg);
 	jmpTarget(jumpNotBlock, gLabel());
 	/* begin AndCq:R: */
 	quickConstant1 = -(alignment());
 	/* begin gen:quickConstant:operand: */
-	anInstruction3 = genoperandoperand(AndCqR, quickConstant1, Scratch0Reg);
+	anInstruction3 = genoperandoperand(AndCqR, quickConstant1, Extra0Reg);
 	/* begin MoveMw:r:R: */
 	offset = offsetof(CogMethod, methodObject);
 	/* begin gen:quickConstant:operand:operand: */
-	anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, Scratch0Reg, Scratch1Reg);
+	anInstruction9 = genoperandoperandoperand(MoveMwrR, offset, Extra0Reg, Extra1Reg);
 	/* begin MoveXwr:R:R: */
-	genoperandoperandoperand(MoveXwrRR, ClassReg, Scratch1Reg, ClassReg);
+	genoperandoperandoperand(MoveXwrRR, ClassReg, Extra1Reg, ClassReg);
 	/* begin RetN: */
 	genoperand(RetN, 0);
 	jmpTarget(jumpNegative, gLabel());
@@ -14463,13 +14575,13 @@
 	/* begin MoveAw:R: */
 	address = specialObjectsArrayAddress();
 	/* begin gen:literal:operand: */
-	anInstruction8 = genoperandoperand(MoveAwR, address, Scratch0Reg);
+	anInstruction10 = genoperandoperand(MoveAwR, address, Extra0Reg);
 	/* begin SubCq:R: */
-	anInstruction9 = genoperandoperand(SubCqR, 1, ClassReg);
+	anInstruction11 = genoperandoperand(SubCqR, 1, ClassReg);
 	/* begin MoveMw:r:R: */
-	anInstruction10 = genoperandoperandoperand(MoveMwrR, (SpecialSelectors + 1) * BytesPerWord, Scratch0Reg, Scratch1Reg);
+	anInstruction12 = genoperandoperandoperand(MoveMwrR, (SpecialSelectors + 1) * BytesPerWord, Extra0Reg, Extra1Reg);
 	/* begin MoveXwr:R:R: */
-	genoperandoperandoperand(MoveXwrRR, ClassReg, Scratch1Reg, ClassReg);
+	genoperandoperandoperand(MoveXwrRR, ClassReg, Extra1Reg, ClassReg);
 	/* begin RetN: */
 	genoperand(RetN, 0);
 	ceDereferenceSelectorIndex = methodZoneBase();
@@ -14850,7 +14962,9 @@
 		genoperand(RetN, 0);
 		jmpTarget(jumpSC, gLabel());
 	}
-	ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, (((callerSavedRegMask()) | (1LL << ReceiverResultReg)) - (1LL << ReceiverResultReg)), 1, returnRegForStoreCheck(), CheckRememberedInTrampoline);
+	ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, (((callerSavedRegMask()) | (1LL << ReceiverResultReg)) - (1LL << ReceiverResultReg)), 1, (callerSavedRegMask & (1LL << ReceiverResultReg)
+		? ReceiverResultReg
+		: RAX), CheckRememberedInTrampoline);
 	ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline();
 	ceScheduleScavengeTrampoline = genTrampolineForcalledregsToSave(ceScheduleScavenge, "ceScheduleScavengeTrampoline", callerSavedRegMask());
 	ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext");
@@ -15021,7 +15135,7 @@
 		genoperandoperandoperand(MoveXwrRR, TempReg, FPReg, TempReg);
 	}
 	else {
-		/* begin genMoveConstant:R: */
+		/* begin genMoveNilR: */
 		constant = nilObject();
 		if (shouldAnnotateObjectReference(constant)) {
 			annotateobjRef(gMoveCwR(constant, TempReg), constant);
@@ -15870,8 +15984,8 @@
 	anInstruction9 = genoperandoperand(CmpCqR, ClassMethodContextCompactIndex, TempReg);
 	/* begin JumpZero: */
 	jumpIsContext1 = genConditionalBranchoperand(JumpZero, ((sqInt)0));
-	genGetClassObjectOfClassIndexintoscratchReg(SendNumArgsReg, Scratch0Reg, TempReg);
-	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Scratch0Reg, SendNumArgsReg);
+	genGetClassObjectOfClassIndexintoscratchReg(SendNumArgsReg, Extra0Reg, TempReg);
+	genLoadSlotsourceRegdestReg(InstanceSpecificationIndex, Extra0Reg, SendNumArgsReg);
 	genConvertSmallIntegerToIntegerInReg(SendNumArgsReg);
 	/* begin AndCq:R: */
 	quickConstant6 = fixedFieldsOfClassFormatMask();
@@ -16451,11 +16565,13 @@
 }
 
 	/* CogSimStackEntry>>#ensureSpilledAt:from: */
-static CogSimStackEntry * NoDbgRegParms
-ensureSpilledAtfrom(CogSimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister)
+static SimStackEntry * NoDbgRegParms
+ensureSpilledAtfrom(SimStackEntry * self_in_ensureSpilledAtfrom, sqInt baseOffset, sqInt baseRegister)
 {
     AbstractInstruction *anInstruction;
+    AbstractInstruction *anInstruction1;
     sqInt baseReg;
+    sqInt constant;
     AbstractInstruction *inst;
     sqInt offset;
     sqInt reg;
@@ -16470,7 +16586,16 @@
 	assert(((self_in_ensureSpilledAtfrom->type)) != SSSpill);
 	traceSpill(self_in_ensureSpilledAtfrom);
 	if (((self_in_ensureSpilledAtfrom->type)) == SSConstant) {
-		inst = annotateobjRef(gPushCw((self_in_ensureSpilledAtfrom->constant)), (self_in_ensureSpilledAtfrom->constant));
+		/* begin genPushConstant: */
+		constant = (self_in_ensureSpilledAtfrom->constant);
+		if (shouldAnnotateObjectReference(constant)) {
+			inst = annotateobjRef(gPushCw(constant), constant);
+		}
+		else {
+			/* begin PushCq: */
+			anInstruction = genoperand(PushCq, constant);
+			inst = anInstruction;
+		}
 	}
 	else {
 		if (((self_in_ensureSpilledAtfrom->type)) == SSBaseOffset) {
@@ -16478,7 +16603,7 @@
 			offset = (self_in_ensureSpilledAtfrom->offset);
 			baseReg = (self_in_ensureSpilledAtfrom->registerr);
 			/* begin gen:quickConstant:operand:operand: */
-			anInstruction = genoperandoperandoperand(MoveMwrR, offset, baseReg, TempReg);
+			anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, baseReg, TempReg);
 			/* begin PushR: */
 			inst = genoperand(PushR, TempReg);
 		}
@@ -16493,37 +16618,12 @@
 		(self_in_ensureSpilledAtfrom->registerr) = baseRegister;
 	}
 	(self_in_ensureSpilledAtfrom->spilled) = 1;
-	if ((self_in_ensureSpilledAtfrom->annotateUse)) {
-		/* begin annotateBytecode: */
-		(inst->annotation = HasBytecodePC);
-		(self_in_ensureSpilledAtfrom->annotateUse) = 0;
-	}
 	return self_in_ensureSpilledAtfrom;
 }
 
-
-/*	Discard type information because of a control-flow merge. */
-
-	/* CogSimStackEntry>>#mergeAt:from: */
-static CogSimStackEntry * NoDbgRegParms
-mergeAtfrom(CogSimStackEntry * self_in_mergeAtfrom, sqInt baseOffset, sqInt baseRegister)
-{
-	assert((self_in_mergeAtfrom->spilled));
-	if (((self_in_mergeAtfrom->type)) == SSSpill) {
-		assert((((self_in_mergeAtfrom->offset)) == baseOffset)
-		 && (((self_in_mergeAtfrom->registerr)) == baseRegister));
-	}
-	else {
-		(self_in_mergeAtfrom->type) = SSSpill;
-		(self_in_mergeAtfrom->offset) = baseOffset;
-		(self_in_mergeAtfrom->registerr) = baseRegister;
-	}
-	return self_in_mergeAtfrom;
-}
-
 	/* CogSimStackEntry>>#popToReg: */
-static CogSimStackEntry * NoDbgRegParms
-popToReg(CogSimStackEntry * self_in_popToReg, sqInt reg)
+static SimStackEntry * NoDbgRegParms
+popToReg(SimStackEntry * self_in_popToReg, sqInt reg)
 {
     AbstractInstruction *anInstruction;
     AbstractInstruction *anInstruction1;
@@ -16575,11 +16675,6 @@
 			error("Case not found and no otherwise clause");
 		}
 	}
-	if ((self_in_popToReg->annotateUse)) {
-		/* begin annotateBytecode: */
-		(inst->annotation = HasBytecodePC);
-		(self_in_popToReg->annotateUse) = 0;
-	}
 	return self_in_popToReg;
 }
 
@@ -16588,7 +16683,7 @@
 
 	/* CogSimStackEntry>>#registerMask */
 static sqInt NoDbgRegParms
-registerMask(CogSimStackEntry * self_in_registerMask)
+registerMask(SimStackEntry * self_in_registerMask)
 {
     sqInt reg;
 
@@ -16602,7 +16697,7 @@
 
 	/* CogSimStackEntry>>#registerOrNone */
 static sqInt NoDbgRegParms
-registerOrNone(CogSimStackEntry * self_in_registerOrNone)
+registerOrNone(SimStackEntry * self_in_registerOrNone)
 {
 	return (((self_in_registerOrNone->type)) == SSRegister
 		? (self_in_registerOrNone->registerr)
@@ -16610,8 +16705,8 @@
 }
 
 	/* CogSimStackEntry>>#storeToReg: */
-static CogSimStackEntry * NoDbgRegParms
-storeToReg(CogSimStackEntry * self_in_storeToReg, sqInt reg)
+static SimStackEntry * NoDbgRegParms
+storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg)
 {
     AbstractInstruction *anInstruction;
     AbstractInstruction *anInstruction1;
@@ -16658,15 +16753,79 @@
 	default:
 		error("Case not found and no otherwise clause");
 	}
-	if ((self_in_storeToReg->annotateUse)) {
-		/* begin annotateBytecode: */
-		(inst->annotation = HasBytecodePC);
-		(self_in_storeToReg->annotateUse) = 0;
-	}
 	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)
+{
+	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. */
+/*	Answer an unused abstract register in the liveRegMask.
+	Subclasses with more registers can override to answer them.
+	N.B. Do /not/ allocate TempReg. */
+
+	/* CogX64Compiler>>#availableRegisterOrNoneFor: */
+static sqInt NoDbgRegParms
+availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask)
+{
+	if (!(liveRegsMask & (1LL << Extra5Reg))) {
+		return Extra5Reg;
+	}
+	if (!(liveRegsMask & (1LL << Extra4Reg))) {
+		return Extra4Reg;
+	}
+	if (!(liveRegsMask & (1LL << Extra3Reg))) {
+		return Extra3Reg;
+	}
+	if (!(liveRegsMask & (1LL << Extra2Reg))) {
+		return Extra2Reg;
+	}
+	if (!(liveRegsMask & (1LL << Extra1Reg))) {
+		return Extra1Reg;
+	}
+	if (!(liveRegsMask & (1LL << Extra0Reg))) {
+		return Extra0Reg;
+	}
+	if (!(liveRegsMask & (1LL << Arg1Reg))) {
+		return Arg1Reg;
+	}
+	if (!(liveRegsMask & (1LL << Arg0Reg))) {
+		return Arg0Reg;
+	}
+	if (!(liveRegsMask & (1LL << SendNumArgsReg))) {
+		return SendNumArgsReg;
+	}
+	if (!(liveRegsMask & (1LL << ClassReg))) {
+		return ClassReg;
+	}
+	if (!(liveRegsMask & (1LL << ReceiverResultReg))) {
+		return ReceiverResultReg;
+	}
+	return NoReg;
+}
+
+
 /*	See e.g. Figure 3.4 Register Usage in
 	System V Application Binary Interface
 	AMD64 Architecture Processor Supplement
@@ -21478,6 +21637,7 @@
     sqInt quickConstant;
     sqInt reg;
 
+	preenMethodLabel();
 	compilePICAbort(numArgs);
 	entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, ClassReg, TempReg);
 	/* begin MoveR:R: */
@@ -21487,7 +21647,7 @@
 	if (!(isWithinMwOffsetRange(backEnd, methodCacheAddress()))) {
 		/* begin MoveCq:R: */
 		quickConstant = ((sqInt) (methodCacheAddress()));
-		reg = (cacheBaseReg = Scratch0Reg);
+		reg = (cacheBaseReg = Extra0Reg);
 		/* begin gen:quickConstant:operand: */
 		anInstruction = genoperandoperand(MoveCqR, quickConstant, reg);
 	}
@@ -21734,24 +21894,6 @@
 		: (FoxMFReceiver - BytesPerWord) + ((methodOrBlockNumArgs - index) * BytesPerWord));
 }
 
-
-/*	Return from block, assuming result already loaded into ReceiverResultReg. */
-
-	/* SimpleStackBasedCogit>>#genBlockReturn */
-static sqInt
-genBlockReturn(void)
-{
-	if (needsFrame) {
-		/* begin MoveR:R: */
-		genoperandoperand(MoveRR, FPReg, SPReg);
-		/* begin PopR: */
-		genoperand(PopR, FPReg);
-			}
-	/* begin RetN: */
-	genoperand(RetN, (methodOrBlockNumArgs + 1) * BytesPerWord);
-	return 0;
-}
-
 	/* SimpleStackBasedCogit>>#genDoubleFailIfZeroArgRcvr:arg: */
 static AbstractInstruction * NoDbgRegParms
 genDoubleFailIfZeroArgRcvrarg(sqInt rcvrReg, sqInt argReg)
@@ -22357,7 +22499,7 @@
 	if (!(isWithinMwOffsetRange(backEnd, methodCacheAddress()))) {
 		/* begin MoveCq:R: */
 		quickConstant = ((sqInt) (methodCacheAddress()));
-		reg = (cacheBaseReg = Scratch0Reg);
+		reg = (cacheBaseReg = Extra0Reg);
 		/* begin gen:quickConstant:operand: */
 		anInstruction1 = genoperandoperand(MoveCqR, quickConstant, reg);
 	}
@@ -22655,17 +22797,17 @@
 genQuickReturnConst(void)
 {
     AbstractInstruction *anInstruction;
-    AbstractInstruction *anInstruction1;
     sqInt constant;
 
 	constant = quickPrimitiveConstantFor(primitiveIndex);
-	annotateobjRef((isImmediate(constant)
-		? (/* begin MoveCq:R: */
-			(anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg)),
-			anInstruction)
-		: (/* begin MoveCw:R: */
-			(anInstruction1 = genoperandoperand(MoveCwR, constant, ReceiverResultReg)),
-			anInstruction1)), constant);
+	/* begin genMoveConstant:R: */
+	if (shouldAnnotateObjectReference(constant)) {
+		annotateobjRef(gMoveCwR(constant, ReceiverResultReg), constant);
+	}
+	else {
+		/* begin MoveCq:R: */
+		anInstruction = genoperandoperand(MoveCqR, constant, ReceiverResultReg);
+	}
 	genUpArrowReturn();
 	return UnfailingPrimitive;
 }
@@ -22722,7 +22864,7 @@
     AbstractInstruction *anInstruction;
     sqInt constant;
 
-	/* begin genMoveConstant:R: */
+	/* begin genMoveNilR: */
 	constant = nilObject();
 	if (shouldAnnotateObjectReference(constant)) {
 		annotateobjRef(gMoveCwR(constant, ReceiverResultReg), constant);
@@ -23568,25 +23710,6 @@
 	return mask & (1LL << reg);
 }
 
-
-/*	We must ensure the ReceiverResultReg is live across the store check so
-	that we can store into receiver inst vars in a frameless method since self
-	exists only in ReceiverResultReg in a frameless method. So if

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list