[Vm-dev] [commit][3310] CogVM source as per VMMaker.oscog-eem.1202

commits at squeakvm.org commits at squeakvm.org
Thu Apr 16 21:33:19 UTC 2015


Revision: 3310
Author:   eliot
Date:     2015-04-16 14:33:16 -0700 (Thu, 16 Apr 2015)
Log Message:
-----------
CogVM source as per VMMaker.oscog-eem.1202

Cogits:

Fix regression in map machinery due to adding AnnotationExtension scheme.
findMapLocationForMcpc:inMethod: must not be confused by IsDisplacementX2N
bytes.  This is likely the cause of the recent crashes with r3308 and earlier.

Lay the groundwork for 32-bit intra-zone jumps and calls on ARM by introducing
CallFull and JumpFull (and rewrites thereof) that are expected to span the full
address space, leaving Call/JumpLong to span merely the 16mb code zone.  On x86
CallFull and JumpFull simply default to Call/JumpLong.

Replace bytecode trapIfNotInstanceOf by jumpIfNotInstanceOfOrPop.

Rewrote the JIT logic for traps to be able to write trap trampolines calls at
the end of the cogMethod.

Refactor the slot store and store check machinery to take an inFrame: argument
and hence deal with the store check in genInnerPrimitiveAtPut: on ARM.

Introduce marryFrameCopiesTemps and use it to
not copy temps in Spur contect creation trampolines.

Change initial usage counts to keep more recently jitted methods around for
longer, and do *not* throw away PICs in freeOlderMethodsForCompaction, so that
there's a better chance of Sista finding send and branch data for the tripping
method.

Don't save the header in a scratch register unless
it is useful to do so in the Spur at:[put:] primitives.

Fix limitation with MoveRXbrR; can only do movb from
%al through %dl, so swap with %eax around movb.

Fix mistake with genGetNumBytesOf:into: by refactoring
genGetFormatOf:into:baseHeaderIntoScratch: into
genGetBits:ofFormatByteOf:into:baseHeaderIntoScratch:
and hence fetching and subtracting only odd bits of format.

Fix slip in genGetNumBytesOf:into:.  And notice that
genGetFormatOf:into:baseHeaderIntoScratch: et al can use byte access
to get at format, as intended in the Spur header design.

Correct the in-line primitive SmallInteger comparisons; CmpXR is confusing ;-)

Fix var op var unsafe byte at:.  Result must be converted to SmallInteger.

Correct the generated Slang for the new register allocation code by adding a
read-before-written pass to C generation that initializes variables
read-before-written with 0 (the C equivalent of nil).

fix a bug where sometimes register allocation was marking ReceiverResultReg as
dead whereas it was still alive.

Added some abstraction over register allocation. This is now used in inline
primitives.

Fix unlinking dynamic super sends.

Reduce false positives in access control violation reporting by marking the
super send we actually use as privileged. Remove unused Newspeak bytecodes.

Fix code generation bug surfaced by inline primitives.  On x86 movb N(%reg),%rl
can only store into al, bl, cl & dl, whereas movzbl can store into any reg.  On
ARM move byte also zero-extends.  So change definition of MoveMbrR to always
zero-extend, use movzbl on x86 and remove all the MoveCq: 0 R: used to zero the
bits of the target of a MoveMb:r:R:.  And now that we have
genGetNumSlotsOf:into:, use it.

Fix a slip in genTrinaryInlinePrimitive:, meet constraint that the target must
be in ReceiverResultReg, and do a better job of register allocation there-in.

Do dead code elimination for the branch following an inlined comparison (this
is done in genBinaryInlineComparison:opFalse:destReg: copying the scheme in
genSpecialSelectorEqualsEquals).

Do register allocation in the right place in genUnaryInlinePrimitive:.

Fix overflow slot access in genGetNumSlotsOf:into: et al.

Fix several slips in inline primitive generation: Object>>at:put: needs to
include a store check.  Some register allocation code was wrong.  Some results
needed converting to SmallIntegers and recording results as pushed on the sim
stack.

extendedPushBytecode /does/ need a frame.

Change callPrimitiveBytecode to genCallPrimitiveBytecode in the Cogit.
remove the misnomer genConvertIntegerToSmallIntegerInScratchReg:

Modified Paths:
--------------
    branches/Cog/nsspursrc/vm/cogit.c
    branches/Cog/nsspursrc/vm/cogit.h
    branches/Cog/nsspursrc/vm/cointerp.c
    branches/Cog/nsspursrc/vm/cointerp.h
    branches/Cog/nsspursrc/vm/gcc3x-cointerp.c
    branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c
    branches/Cog/nsspurstacksrc/vm/interp.c
    branches/Cog/spursistasrc/vm/cogit.c
    branches/Cog/spursistasrc/vm/cogit.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.c
    branches/Cog/spursrc/vm/cogit.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/vm/cogit.c
    branches/Cog/src/vm/cogit.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

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

Modified: branches/Cog/nsspursrc/vm/cogit.c
===================================================================
--- branches/Cog/nsspursrc/vm/cogit.c	2015-04-13 02:34:55 UTC (rev 3309)
+++ branches/Cog/nsspursrc/vm/cogit.c	2015-04-16 21:33:16 UTC (rev 3310)
@@ -1,9 +1,9 @@
 /* Automatically generated by
-	CCodeGenerator VMMaker.oscog-eem.1178 uuid: bb034bb1-371f-44a6-a66f-bbcfaff35456
+	CCodeGenerator VMMaker.oscog-eem.1202 uuid: 992991db-47cc-4d19-85cf-4959c54bd41f
    from
-	StackToRegisterMappingCogit VMMaker.oscog-eem.1178 uuid: bb034bb1-371f-44a6-a66f-bbcfaff35456
+	StackToRegisterMappingCogit VMMaker.oscog-eem.1202 uuid: 992991db-47cc-4d19-85cf-4959c54bd41f
  */
-static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1178 uuid: bb034bb1-371f-44a6-a66f-bbcfaff35456 " __DATE__ ;
+static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1202 uuid: 992991db-47cc-4d19-85cf-4959c54bd41f " __DATE__ ;
 char *__cogitBuildInfo = __buildInfo;
 
 
@@ -114,27 +114,28 @@
 
 
 /*** Constants ***/
-#define AddCqR 93
-#define AddCwR 100
-#define AddRdRd 108
-#define AddRR 86
+#define AddCqR 95
+#define AddCwR 102
+#define AddRdRd 110
+#define AddRR 88
 #define AlignmentNops 2
 #define AltBlockCreationBytecodeSize 3
 #define AltFirstSpecialSelector 80
-#define AndCqR 95
-#define AndCqRR 106
-#define AndCwR 102
-#define AndRR 88
+#define AndCqR 97
+#define AndCqRR 108
+#define AndCwR 104
+#define AndRR 90
 #define AnnotationShift 5
 #define Arg0Reg -7
 #define Arg1Reg -8
-#define ArithmeticShiftRightCqR 79
-#define ArithmeticShiftRightRR 80
+#define ArithmeticShiftRightCqR 81
+#define ArithmeticShiftRightRR 82
 #define BadRegisterSet 1
 #define BlockCreationBytecodeSize 4
 #define BytecodeSetHasDirectedSuperSend 0
 #define Call 9
-#define CDQ 115
+#define CallFull 10
+#define CDQ 117
 #define ClassArrayCompactIndex 51
 #define ClassBlockClosureCompactIndex 37
 #define ClassFloatCompactIndex 34
@@ -151,19 +152,19 @@
 #define CMMaxUsageCount 7
 #define CMMethod 2
 #define CMOpenPIC 5
-#define CMPXCHGAwR 123
-#define CMPXCHGMwrR 124
-#define CmpCqR 92
-#define CmpCwR 99
-#define CmpRdRd 107
-#define CmpRR 85
+#define CMPXCHGAwR 125
+#define CMPXCHGMwrR 126
+#define CmpCqR 94
+#define CmpCwR 101
+#define CmpRdRd 109
+#define CmpRR 87
 #define ConstZero 1
-#define ConvertRRd 114
-#define CPUID 118
+#define ConvertRRd 116
+#define CPUID 120
 #define Debug DEBUGVM
 #define DisplacementMask 0x1F
 #define DisplacementX2N 0
-#define DivRdRd 111
+#define DivRdRd 113
 #define DPFPReg0 -9
 #define DPFPReg1 -10
 #define DPFPReg2 -11
@@ -185,8 +186,8 @@
 #define Fill32 6
 #define FillFromWord 7
 #define FirstAnnotation 64
-#define FirstJump 13
-#define FirstShortJump 16
+#define FirstJump 14
+#define FirstShortJump 18
 #define FirstSpecialSelector 176
 #define FoxCallerSavedIP 4
 #define FoxMethod -4
@@ -201,8 +202,8 @@
 #define GPRegMin -8
 #define HasBytecodePC 4
 #define HeaderIndex 0
-#define IDIVR 116
-#define IMULRR 117
+#define IDIVR 118
+#define IMULRR 119
 #define InstanceSpecificationIndex 2
 #define InstructionPointerIndex 1
 #define InsufficientCodeSpace -2
@@ -211,53 +212,53 @@
 #define IsDirectedSuperSend 9
 #define IsDisplacementX2N 0
 #define IsNSDynamicSuperSend 11
-#define IsNSImplicitReceiverSend 12
 #define IsNSSelfSend 10
 #define IsNSSendCall 6
 #define IsObjectReference 2
 #define IsRelativeCall 5
 #define IsSendCall 7
 #define IsSuperSend 8
-#define Jump 16
-#define JumpAbove 31
-#define JumpAboveOrEqual 30
-#define JumpBelow 29
-#define JumpBelowOrEqual 32
-#define JumpCarry 23
-#define JumpFPEqual 33
-#define JumpFPGreater 37
-#define JumpFPGreaterOrEqual 38
-#define JumpFPLess 35
-#define JumpFPLessOrEqual 36
-#define JumpFPNotEqual 34
-#define JumpFPOrdered 39
-#define JumpFPUnordered 40
-#define JumpGreater 27
-#define JumpGreaterOrEqual 26
-#define JumpLess 25
-#define JumpLessOrEqual 28
-#define JumpLong 13
-#define JumpLongNonZero 15
-#define JumpLongZero 14
-#define JumpNegative 19
-#define JumpNoCarry 24
-#define JumpNonNegative 20
-#define JumpNonZero 18
-#define JumpNoOverflow 22
-#define JumpOverflow 21
-#define JumpR 11
-#define JumpZero 17
+#define Jump 18
+#define JumpAbove 33
+#define JumpAboveOrEqual 32
+#define JumpBelow 31
+#define JumpBelowOrEqual 34
+#define JumpCarry 25
+#define JumpFPEqual 35
+#define JumpFPGreater 39
+#define JumpFPGreaterOrEqual 40
+#define JumpFPLess 37
+#define JumpFPLessOrEqual 38
+#define JumpFPNotEqual 36
+#define JumpFPOrdered 41
+#define JumpFPUnordered 42
+#define JumpFull 14
+#define JumpGreater 29
+#define JumpGreaterOrEqual 28
+#define JumpLess 27
+#define JumpLessOrEqual 30
+#define JumpLong 15
+#define JumpLongNonZero 17
+#define JumpLongZero 16
+#define JumpNegative 21
+#define JumpNoCarry 26
+#define JumpNonNegative 22
+#define JumpNonZero 20
+#define JumpNoOverflow 24
+#define JumpOverflow 23
+#define JumpR 12
+#define JumpZero 19
 #define Label 1
 #define LargeContextSlots 62
-#define LastJump 40
-#define LFENCE 119
+#define LastJump 42
+#define LFENCE 121
 #define LinkReg -17
-#define LOCK 122
-#define LoadEffectiveAddressMwrR 76
-#define LogicalShiftLeftCqR 83
-#define LogicalShiftLeftRR 84
-#define LogicalShiftRightCqR 81
-#define LogicalShiftRightRR 82
+#define LOCK 124
+#define LoadEffectiveAddressMwrR 78
+#define LogicalShiftLeftCqR 85
+#define LogicalShiftLeftRR 86
+#define LogicalShiftRightCqR 83
+#define LogicalShiftRightRR 84
 #define MapEnd 0
 #define MaxCompiledPrimitiveIndex 222
 #define MaxMethodSize 65535
@@ -272,33 +273,33 @@
 #define MethodCacheSelector 1
 #define MethodIndex 3
 #define MethodTooBig -4
-#define MFENCE 120
+#define MFENCE 122
 #define MFMethodFlagHasContextFlag 1
 #define MFMethodFlagIsBlockFlag 2
 #define ModReg 3
 #define ModRegInd 0
 #define ModRegRegDisp32 2
 #define ModRegRegDisp8 1
-#define MoveAwR 42
-#define MoveCqR 64
-#define MoveCwR 65
-#define MoveM16rR 52
-#define MoveM64rRd 69
-#define MoveMbrR 60
-#define MoveMwrR 46
-#define MoveRAw 43
-#define MoveRdM64r 70
-#define MoveRdRd 68
-#define MoveRMbr 61
-#define MoveRMwr 47
-#define MoveRR 41
-#define MoveRXbrR 63
-#define MoveRXwrR 49
-#define MoveXbrRR 62
-#define MoveXwrRR 48
+#define MoveAwR 44
+#define MoveCqR 66
+#define MoveCwR 67
+#define MoveM16rR 54
+#define MoveM64rRd 71
+#define MoveMbrR 62
+#define MoveMwrR 48
+#define MoveRAw 45
+#define MoveRdM64r 72
+#define MoveRdRd 70
+#define MoveRMbr 63
+#define MoveRMwr 49
+#define MoveRR 43
+#define MoveRXbrR 65
+#define MoveRXwrR 51
+#define MoveXbrRR 64
+#define MoveXwrRR 50
 #define MULTIPLEBYTECODESETS 1
-#define MulRdRd 110
-#define NegateR 78
+#define MulRdRd 112
+#define NegateR 80
 #define NewspeakVM 1
 #define Nop 8
 #define NotFullyInitialized -1
@@ -309,54 +310,54 @@
 #define NumOopsPerNSC 6
 #define NumSendTrampolines 4
 #define NumTrampolines 70
-#define OrCqR 96
-#define OrCwR 103
-#define OrRR 89
+#define OrCqR 98
+#define OrCwR 105
+#define OrRR 91
 #define PCReg -19
-#define PopR 71
-#define PrefetchAw 75
+#define PopR 73
+#define PrefetchAw 77
 #define PrimCallCollectsProfileSamples 8
 #define PrimCallDoNotJIT 32
 #define PrimCallMayCallBack 4
 #define PrimCallNeedsNewMethod 1
 #define PrimCallNeedsPrimitiveFunction 2
 #define PrimErrWritePastObject 17
-#define PushCq 73
-#define PushCw 74
-#define PushR 72
+#define PushCq 75
+#define PushCw 76
+#define PushR 74
 #define ReceiverIndex 5
 #define ReceiverResultReg -3
-#define RetN 10
+#define RetN 11
 #define RISCTempReg -18
 #define SelectorCannotInterpret 34
 #define SelectorDoesNotUnderstand 20
 #define SenderIndex 0
 #define SendNumArgsReg -6
-#define SFENCE 121
+#define SFENCE 123
 #define ShouldNotJIT -8
 #define SIB1 0
 #define SIB4 2
 #define SistaVM 0
 #define SmallContextSlots 22
 #define SPReg -2
-#define SqrtRd 113
+#define SqrtRd 115
 #define SSBaseOffset 1
 #define SSConstant 2
 #define SSRegister 3
 #define SSSpill 4
 #define StackPointerIndex 2
-#define Stop 12
-#define SubCqR 94
-#define SubCwR 101
-#define SubRdRd 109
-#define SubRR 87
+#define Stop 13
+#define SubCqR 96
+#define SubCwR 103
+#define SubRdRd 111
+#define SubRR 89
 #define TempReg -4
 #define UnimplementedPrimitive -7
 #define ValueIndex 1
 #define VarBaseReg -20
-#define XCHGAwR 125
-#define XCHGMwrR 126
-#define XCHGRR 127
+#define XCHGAwR 127
+#define XCHGMwrR 128
+#define XCHGRR 129
 #define XMM0L 0
 #define XMM1L 2
 #define XMM2L 4
@@ -365,8 +366,8 @@
 #define XMM5L 10
 #define XMM6L 12
 #define XMM7L 14
-#define XorCwR 104
-#define XorRR 90
+#define XorCwR 106
+#define XorRR 92
 #define YoungSelectorInPIC -5
 
 
@@ -405,6 +406,8 @@
 static unsigned long labelOffset(AbstractInstruction * self_in_labelOffset) NoDbgRegParms;
 static sqInt numICacheFlushOpcodes(AbstractInstruction * self_in_numICacheFlushOpcodes) NoDbgRegParms;
 static AbstractInstruction * resolveJumpTarget(AbstractInstruction * self_in_resolveJumpTarget) NoDbgRegParms;
+static sqInt rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) NoDbgRegParms;
+static sqInt rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress) NoDbgRegParms;
 static sqInt setLabelOffset(AbstractInstruction * self_in_setLabelOffset, sqInt aValue) NoDbgRegParms;
 static AbstractInstruction * updateLabel(AbstractInstruction * self_in_updateLabel, AbstractInstruction *labelInstruction) NoDbgRegParms;
 static sqInt wantsNearAddressFor(AbstractInstruction * self_in_wantsNearAddressFor, sqInt anObject) NoDbgRegParms;
@@ -510,7 +513,6 @@
 static sqInt blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg) NoDbgRegParms;
 sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod);
 static AbstractInstruction * CallNewspeakSend(sqInt callTarget) NoDbgRegParms;
-static AbstractInstruction * CallRT(sqInt callTarget) NoDbgRegParms;
 static AbstractInstruction * CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved) NoDbgRegParms;
 static AbstractInstruction * gCall(sqInt callTarget) NoDbgRegParms;
 static AbstractInstruction * gCmpCqR(sqInt quickConstant, sqInt reg) NoDbgRegParms;
@@ -626,7 +628,6 @@
 static AbstractInstruction * gJumpFPLessOrEqual(void *jumpTarget) NoDbgRegParms;
 static AbstractInstruction * gJumpFPLess(void *jumpTarget) NoDbgRegParms;
 static AbstractInstruction * gJumpFPNotEqual(void *jumpTarget) NoDbgRegParms;
-static AbstractInstruction * JumpRT(sqInt callTarget) NoDbgRegParms;
 static AbstractInstruction * gLabel(void);
 static AbstractInstruction * gLogicalShiftLeftCqR(sqInt quickConstant, sqInt reg) NoDbgRegParms;
 static AbstractInstruction * lastOpcode(void);
@@ -756,7 +757,6 @@
 static sqInt genAddSmallIntegerTagsTo(sqInt aRegister) NoDbgRegParms;
 static void genConvertCharacterToSmallIntegerInReg(sqInt reg) NoDbgRegParms;
 static sqInt genConvertIntegerToSmallIntegerInReg(sqInt reg) NoDbgRegParms;
-static sqInt genConvertIntegerToSmallIntegerInScratchReg(sqInt scratchReg) NoDbgRegParms;
 static void genConvertSmallIntegerToCharacterInReg(sqInt reg) NoDbgRegParms;
 static sqInt genConvertSmallIntegerToIntegerInReg(sqInt reg) NoDbgRegParms;
 static sqInt genCreateClosureAtnumArgsnumCopiedcontextNumArgslargeinBlock(sqInt bcpc, sqInt numArgs, sqInt numCopied, sqInt ctxtNumArgs, sqInt isLargeCtxt, sqInt isInBlock) NoDbgRegParms;
@@ -766,6 +766,9 @@
 static sqInt genGetHashFieldNonImmOfasSmallIntegerInto(sqInt instReg, sqInt destReg) NoDbgRegParms;
 static sqInt genGetHashFieldNonImmOfinto(sqInt instReg, sqInt destReg) NoDbgRegParms;
 static AbstractInstruction * genGetInlineCacheClassTagFromintoforEntry(sqInt sourceReg, sqInt destReg, sqInt forEntry) NoDbgRegParms;
+static sqInt genGetNumBytesOfinto(sqInt srcReg, sqInt destReg) NoDbgRegParms;
+static sqInt genGetNumSlotsOfinto(sqInt srcReg, sqInt destReg) NoDbgRegParms;
+static sqInt genGetOverflowSlotsOfinto(sqInt srcReg, sqInt destReg) NoDbgRegParms;
 static sqInt genInnerPrimitiveAtPut(sqInt retNoffset) NoDbgRegParms;
 static sqInt genInnerPrimitiveAt(sqInt retNoffset) NoDbgRegParms;
 static sqInt genInnerPrimitiveIdentityHash(sqInt retNoffset) NoDbgRegParms;
@@ -802,6 +805,7 @@
 static sqInt genEnsureOopInRegNotForwardedscratchReg(sqInt reg, sqInt scratch) NoDbgRegParms;
 static void generateObjectRepresentationTrampolines(void);
 static sqInt genGetActiveContextNumArgslargeinBlock(sqInt numArgs, sqInt isLargeContext, sqInt isInBlock) NoDbgRegParms;
+static sqInt genGetBitsofFormatByteOfintobaseHeaderIntoScratch(sqInt mask, sqInt sourceReg, sqInt destReg, sqInt scratchReg) NoDbgRegParms;
 static sqInt genGetClassIndexOfNonImminto(sqInt sourceReg, sqInt destReg) NoDbgRegParms;
 static sqInt genGetClassObjectOfClassIndexintoscratchReg(sqInt instReg, sqInt destReg, sqInt scratchReg) NoDbgRegParms;
 static sqInt genGetClassObjectOfintoscratchReginstRegIsReceiver(sqInt instReg, sqInt destReg, sqInt scratchReg, sqInt instRegIsReceiver) NoDbgRegParms;
@@ -816,9 +820,9 @@
 static AbstractInstruction * genJumpImmediateInScratchReg(sqInt aRegister) NoDbgRegParms;
 static AbstractInstruction * genJumpNotCharacterInScratchReg(sqInt reg) NoDbgRegParms;
 static sqInt genLoadSlotsourceRegdestReg(sqInt index, sqInt sourceReg, sqInt destReg) NoDbgRegParms;
-static sqInt genStoreCheckReceiverRegvalueRegscratchReg(sqInt destReg, sqInt valueReg, sqInt scratchReg) NoDbgRegParms;
+static sqInt genStoreCheckReceiverRegvalueRegscratchReginFrame(sqInt destReg, sqInt valueReg, sqInt scratchReg, sqInt inFrame) NoDbgRegParms;
 static sqInt genStoreImmediateInSourceRegslotIndexdestReg(sqInt sourceReg, sqInt index, sqInt destReg) NoDbgRegParms;
-static sqInt genStoreSourceRegslotIndexdestRegscratchReg(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg) NoDbgRegParms;
+static sqInt genStoreSourceRegslotIndexdestRegscratchReginFrame(sqInt sourceReg, sqInt index, sqInt destReg, sqInt scratchReg, sqInt inFrame) NoDbgRegParms;
 static sqInt genStoreSourceRegslotIndexintoNewObjectInDestReg(sqInt sourceReg, sqInt index, sqInt destReg) NoDbgRegParms;
 static sqInt getActiveContextAllocatesInMachineCode(void);
 static sqInt hasSpurMemoryManagerAPI(void);
@@ -844,7 +848,6 @@
 static sqInt registerMask(CogSimStackEntry * self_in_registerMask) NoDbgRegParms;
 static sqInt registerOrNil(CogSimStackEntry * self_in_registerOrNil) NoDbgRegParms;
 static CogSimStackEntry * storeToReg(CogSimStackEntry * self_in_storeToReg, sqInt reg) NoDbgRegParms;
-static sqInt callPrimitiveBytecode(void);
 static sqInt compileBlockDispatch(void);
 static sqInt compileFallbackToInterpreterPrimitive(void);
 static void compileGetErrorCode(void);
@@ -951,6 +954,8 @@
 static sqInt v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) NoDbgRegParms;
 void voidCogCompiledCode(void);
 static BlockStart * addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) NoDbgRegParms;
+static sqInt allocateOneRegister(void);
+static sqInt allocateRegisterNotConflictingWith(sqInt registerMask) NoDbgRegParms;
 static void annotateBytecodeIfAnnotated(CogSimStackEntry *aSimStackEntry) NoDbgRegParms;
 static sqInt anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) NoDbgRegParms;
 void callCogCodePopReceiverArg0Regs(void);
@@ -970,7 +975,13 @@
 static BytecodeFixup * ensureNonMergeFixupAt(sqInt targetIndex) NoDbgRegParms;
 static void ensureReceiverResultRegContainsSelf(void);
 static void evaluateat(BytecodeDescriptor *descriptor, sqInt pc) NoDbgRegParms;
+static sqInt freeRegisterNotConflictingWith(sqInt registerMask) NoDbgRegParms;
+static sqInt genBinaryConstOpVarInlinePrimitive(sqInt prim) NoDbgRegParms;
+static sqInt genBinaryInlineComparisonopFalsedestReg(sqInt opTrue, sqInt opFalse, sqInt destReg) NoDbgRegParms;
+static sqInt genBinaryVarOpConstInlinePrimitive(sqInt prim) NoDbgRegParms;
+static sqInt genBinaryVarOpVarInlinePrimitive(sqInt prim) NoDbgRegParms;
 static void (*genCallPICEnilopmartNumArgs(sqInt numArgs))(void)  NoDbgRegParms;
+static sqInt genCallPrimitiveBytecode(void);
 static sqInt genDoubleArithmeticpreOpCheck(sqInt arithmeticOperator, AbstractInstruction *(*preOpCheckOrNil)(int rcvrReg, int argReg)) NoDbgRegParms;
 static sqInt genDoubleComparisoninvert(AbstractInstruction *(*jumpOpcodeGenerator)(void *), sqInt invertComparison) NoDbgRegParms;
 static sqInt genExternalizePointersForPrimitiveCall(void);
@@ -986,6 +997,7 @@
 static sqInt genJumpTo(sqInt targetBytecodePC) NoDbgRegParms;
 static sqInt genMarshalledSendnumArgssendTable(sqInt selector, sqInt numArgs, sqInt *sendTable) NoDbgRegParms;
 static sqInt genMethodAbortTrampolineFor(sqInt numArgs) NoDbgRegParms;
+static sqInt genNullaryInlinePrimitive(sqInt prim) NoDbgRegParms;
 static sqInt genPICAbortTrampolineFor(sqInt numArgs) NoDbgRegParms;
 static sqInt genPICMissTrampolineFor(sqInt numArgs) NoDbgRegParms;
 static sqInt genPopStackBytecode(void);
@@ -1050,6 +1062,8 @@
 static sqInt genStorePopReceiverVariable(sqInt popBoolean, sqInt slotIndex) NoDbgRegParms;
 static sqInt genStorePopRemoteTempAt(sqInt popBoolean, sqInt slotIndex, sqInt remoteTempIndex) NoDbgRegParms;
 static sqInt genStorePopTemporaryVariable(sqInt popBoolean, sqInt tempIndex) NoDbgRegParms;
+static sqInt genTrinaryInlinePrimitive(sqInt prim) NoDbgRegParms;
+static sqInt genUnaryInlinePrimitive(sqInt prim) NoDbgRegParms;
 static sqInt genUpArrowReturn(void);
 static BytecodeFixup * initializeFixupAt(sqInt targetIndex) NoDbgRegParms;
 static void initSimStackForFramefulMethod(sqInt startpc) NoDbgRegParms;
@@ -1067,6 +1081,7 @@
 static sqInt picAbortTrampolineFor(sqInt numArgs) NoDbgRegParms;
 static sqInt prevInstIsPCAnnotated(void);
 static sqInt pushNilSizenumInitialNils(sqInt aMethodObj, sqInt numInitialNils) NoDbgRegParms;
+static sqInt registerisInMask(sqInt reg, sqInt mask) NoDbgRegParms;
 static void reinitializeFixupsFromthrough(sqInt start, sqInt end) NoDbgRegParms;
 static sqInt returnRegForStoreCheck(void);
 static void scanBlock(BlockStart *blockStart) NoDbgRegParms;
@@ -1321,7 +1336,7 @@
 	{ genReturnTopFromBlock, 0, needsFrameNever, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 },
 	{ unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0 },
 	{ unknownBytecode, 0, 0, 0, Nop, 1, 0, 0, 0, 0, 0, 0, 1, 0 },
-	{ extendedPushBytecode, 0, needsFrameNever, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ extendedPushBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ extendedStoreBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ extendedStoreAndPopBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genExtendedSendBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0 },
@@ -1332,7 +1347,7 @@
 	{ duplicateTopBytecode, 0, needsFrameNever, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushActiveContextBytecode, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushNewArrayBytecode, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0 },
-	{ callPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -1698,7 +1713,7 @@
 	{ unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0 },
 	{ unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0 },
 	{ unknownBytecode, 0, 0, 0, Nop, 2, 0, 0, 0, 0, 0, 0, 1, 0 },
-	{ callPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
+	{ genCallPrimitiveBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genPushRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genStoreRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
 	{ genStoreAndPopRemoteTempLongBytecode, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0 },
@@ -1912,6 +1927,7 @@
 static sqInt
 availableRegisterOrNilFor(AbstractInstruction * self_in_availableRegisterOrNilFor, sqInt liveRegsMask)
 {
+	flag("searching physical registers that are not assigned to abstract registers first will do a better job and allocate with fewer conflicts");
 	if (!(liveRegsMask & (registerMaskFor(Arg1Reg)))) {
 		return Arg1Reg;
 	}
@@ -2044,6 +2060,34 @@
 }
 
 
+/*	Rewrite a CallFull instruction to call a different target. This variant is
+	used to rewrite cached primitive calls.
+	Answer the extent of the code change which is used to compute the range of
+	the icache to flush.
+	This defaults to rewriteCallAt:target:; proessors that differentiate
+	between Call and CallFull will override. */
+
+static sqInt
+rewriteCallFullAttarget(AbstractInstruction * self_in_rewriteCallFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress)
+{
+	return rewriteCallAttarget(self_in_rewriteCallFullAttarget, callSiteReturnAddress, callTargetAddress);
+}
+
+
+/*	Rewrite a JumpFull instruction to jump to a different target. This variant
+	is used to rewrite cached primitive calls.
+	Answer the extent of the code change which is used to compute the range of
+	the icache to flush.
+	This defaults to rewriteJumpLongAt:target:; proessors that differentiate
+	between Jump and JumpFull will override. */
+
+static sqInt
+rewriteJumpFullAttarget(AbstractInstruction * self_in_rewriteJumpFullAttarget, sqInt callSiteReturnAddress, sqInt callTargetAddress)
+{
+	return rewriteJumpLongAttarget(self_in_rewriteJumpFullAttarget, callSiteReturnAddress, callTargetAddress);
+}
+
+
 /*	Hack: To arrange that the block method field pushed in a block entry has
 	its MFMethodFlagIsBlockFlag bit set we provide labels with an offset. The
 	offset for the fakeHeader reference is MFMethodFlagIsBlockFlag. See
@@ -2205,11 +2249,13 @@
 		return ((self_in_computeMaximumSize->maxSize) = 6);
 
 	case Call:
+	case CallFull:
 	case MoveCwR:
 	case PushCw:
 		return ((self_in_computeMaximumSize->maxSize) = 5);
 
 	case Jump:
+	case JumpFull:
 	case JumpLong:
 		resolveJumpTarget(self_in_computeMaximumSize);
 		return ((self_in_computeMaximumSize->maxSize) = 5);
@@ -2271,7 +2317,6 @@
 			: 6));
 
 	case LoadEffectiveAddressMwrR:
-	case MoveMbrR:
 	case MoveMwrR:
 		return ((self_in_computeMaximumSize->maxSize) = ((isQuick(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0])
 	? 3
@@ -2316,6 +2361,7 @@
 	? 1
 	: 0)));
 
+	case MoveMbrR:
 	case MoveM16rR:
 		return ((self_in_computeMaximumSize->maxSize) = ((isQuick(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0])
 	? 4
@@ -2337,11 +2383,12 @@
 			: 4));
 
 	case MoveRXbrR:
-	case MoveRXwrR:
 		assert((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[1])) != ESP);
-		return ((self_in_computeMaximumSize->maxSize) = ((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[2])) == EBP
-			? 4
-			: 3));
+		return ((self_in_computeMaximumSize->maxSize) = (((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[2])) == EBP
+	? 4
+	: 3)) + (((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0])) >= 4
+	? 2
+	: 0)));
 
 	case MoveXwrRR:
 		assert((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0])) != ESP);
@@ -2349,6 +2396,12 @@
 			? 4
 			: 3));
 
+	case MoveRXwrR:
+		assert((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[1])) != ESP);
+		return ((self_in_computeMaximumSize->maxSize) = ((concreteRegister(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[2])) == EBP
+			? 4
+			: 3));
+
 	case PushCq:
 		return ((self_in_computeMaximumSize->maxSize) = (isQuick(self_in_computeMaximumSize, ((self_in_computeMaximumSize->operands))[0])
 			? 2
@@ -2660,6 +2713,7 @@
     AbstractInstruction *jumpTarget9;
     unsigned long mask;
     unsigned long mask1;
+    sqInt mcIdx;
     unsigned long offset;
     unsigned long offset1;
     unsigned long offset10;
@@ -2776,6 +2830,7 @@
     sqInt srcReg7;
     sqInt srcReg8;
     sqInt srcReg9;
+    sqInt swapreg;
     unsigned long value;
     unsigned long value1;
     unsigned long value10;
@@ -2793,6 +2848,7 @@
     unsigned long word1;
     unsigned long word2;
 
+	swapreg = 0;
 	
 	switch ((self_in_dispatchConcretize->opcode)) {
 	case Label:
@@ -3040,6 +3096,7 @@
 		return;
 
 	case Call:
+	case CallFull:
 		/* begin concretizeCall */
 		assert((((self_in_dispatchConcretize->operands))[0]) != 0);
 		offset2 = (((sqInt) (((self_in_dispatchConcretize->operands))[0]))) - (((sqInt) (((self_in_dispatchConcretize->address)) + 5)));
@@ -3059,6 +3116,7 @@
 		((self_in_dispatchConcretize->machineCodeSize) = 2);
 		return;
 
+	case JumpFull:
 	case JumpLong:
 		/* begin concretizeJumpLong */
 		jumpTarget = ((AbstractInstruction *) (((self_in_dispatchConcretize->operands))[0]));
@@ -4463,37 +4521,41 @@
 		destReg6 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]);
 		if (srcReg4 != ESP) {
 			if (isQuick(self_in_dispatchConcretize, offset7)) {
-				((self_in_dispatchConcretize->machineCode))[0] = 138;
-				((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp8, srcReg4, destReg6));
-				((self_in_dispatchConcretize->machineCode))[2] = (offset7 & 0xFF);
-				((self_in_dispatchConcretize->machineCodeSize) = 3);
+				((self_in_dispatchConcretize->machineCode))[0] = 15;
+				((self_in_dispatchConcretize->machineCode))[1] = 182;
+				((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp8, srcReg4, destReg6));
+				((self_in_dispatchConcretize->machineCode))[3] = (offset7 & 0xFF);
+				((self_in_dispatchConcretize->machineCodeSize) = 4);
 				return;
 			}
-			((self_in_dispatchConcretize->machineCode))[0] = 138;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp32, srcReg4, destReg6));
-			((self_in_dispatchConcretize->machineCode))[2] = (offset7 & 0xFF);
-			((self_in_dispatchConcretize->machineCode))[3] = ((((usqInt) offset7) >> 8) & 0xFF);
-			((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) offset7) >> 16) & 0xFF);
-			((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) offset7) >> 24) & 0xFF);
-			((self_in_dispatchConcretize->machineCodeSize) = 6);
+			((self_in_dispatchConcretize->machineCode))[0] = 15;
+			((self_in_dispatchConcretize->machineCode))[1] = 182;
+			((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp32, srcReg4, destReg6));
+			((self_in_dispatchConcretize->machineCode))[3] = (offset7 & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) offset7) >> 8) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) offset7) >> 16) & 0xFF);
+			((self_in_dispatchConcretize->machineCode))[6] = ((((usqInt) offset7) >> 24) & 0xFF);
+			((self_in_dispatchConcretize->machineCodeSize) = 7);
 			return;
 		}
 		if (isQuick(self_in_dispatchConcretize, offset7)) {
-			((self_in_dispatchConcretize->machineCode))[0] = 138;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp8, srcReg4, destReg6));
-			((self_in_dispatchConcretize->machineCode))[2] = (sib(self_in_dispatchConcretize, SIB1, 4, srcReg4));
-			((self_in_dispatchConcretize->machineCode))[3] = (offset7 & 0xFF);
-			((self_in_dispatchConcretize->machineCodeSize) = 4);
+			((self_in_dispatchConcretize->machineCode))[0] = 15;
+			((self_in_dispatchConcretize->machineCode))[1] = 182;
+			((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp8, srcReg4, destReg6));
+			((self_in_dispatchConcretize->machineCode))[3] = (sib(self_in_dispatchConcretize, SIB1, 4, srcReg4));
+			((self_in_dispatchConcretize->machineCode))[4] = (offset7 & 0xFF);
+			((self_in_dispatchConcretize->machineCodeSize) = 5);
 			return;
 		}
-		((self_in_dispatchConcretize->machineCode))[0] = 138;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp32, srcReg4, destReg6));
-		((self_in_dispatchConcretize->machineCode))[2] = (sib(self_in_dispatchConcretize, SIB1, 4, srcReg4));
-		((self_in_dispatchConcretize->machineCode))[3] = (offset7 & 0xFF);
-		((self_in_dispatchConcretize->machineCode))[4] = ((((usqInt) offset7) >> 8) & 0xFF);
-		((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) offset7) >> 16) & 0xFF);
-		((self_in_dispatchConcretize->machineCode))[6] = ((((usqInt) offset7) >> 24) & 0xFF);
-		((self_in_dispatchConcretize->machineCodeSize) = 7);
+		((self_in_dispatchConcretize->machineCode))[0] = 15;
+		((self_in_dispatchConcretize->machineCode))[1] = 182;
+		((self_in_dispatchConcretize->machineCode))[2] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp32, srcReg4, destReg6));
+		((self_in_dispatchConcretize->machineCode))[3] = (sib(self_in_dispatchConcretize, SIB1, 4, srcReg4));
+		((self_in_dispatchConcretize->machineCode))[4] = (offset7 & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[5] = ((((usqInt) offset7) >> 8) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[6] = ((((usqInt) offset7) >> 16) & 0xFF);
+		((self_in_dispatchConcretize->machineCode))[7] = ((((usqInt) offset7) >> 24) & 0xFF);
+		((self_in_dispatchConcretize->machineCodeSize) = 8);
 		return;
 
 	case MoveRMbr:
@@ -4703,18 +4765,40 @@
 		src = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[0]);
 		index1 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[1]);
 		base1 = concreteRegister(self_in_dispatchConcretize, ((self_in_dispatchConcretize->operands))[2]);
+		mcIdx = 0;
+		if (src >= 4) {
+
+			/* x86 allows movb %rl, mem only with %al, %bl, %cl, %dl, so swap with the first one that isn't used. */
+
+			swapreg = src;
+			if (index1 == EAX) {
+				index1 = swapreg;
+			}
+			if (base1 == EAX) {
+				base1 = swapreg;
+			}
+			src = EAX;
+			mcIdx = 1;
+			((self_in_dispatchConcretize->machineCode))[0] = (144 + swapreg);
+		}
 		if (base1 != EBP) {
-			((self_in_dispatchConcretize->machineCode))[0] = 136;
-			((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModRegInd, 4, src));
-			((self_in_dispatchConcretize->machineCode))[2] = (sib(self_in_dispatchConcretize, SIB1, index1, base1));
-			((self_in_dispatchConcretize->machineCodeSize) = 3);
+			((self_in_dispatchConcretize->machineCode))[mcIdx + 0] = 136;
+			((self_in_dispatchConcretize->machineCode))[mcIdx + 1] = (modRMRO(self_in_dispatchConcretize, ModRegInd, 4, src));
+			((self_in_dispatchConcretize->machineCode))[mcIdx + 2] = (sib(self_in_dispatchConcretize, SIB1, index1, base1));
+			if (!(swapreg == null)) {
+				((self_in_dispatchConcretize->machineCode))[mcIdx + 3] = (144 + swapreg);
+			}
+			((self_in_dispatchConcretize->machineCodeSize) = 3 + (2 * mcIdx));
 			return;
 		}
-		((self_in_dispatchConcretize->machineCode))[0] = 136;
-		((self_in_dispatchConcretize->machineCode))[1] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp8, 4, src));
-		((self_in_dispatchConcretize->machineCode))[2] = (sib(self_in_dispatchConcretize, SIB1, index1, base1));
-		((self_in_dispatchConcretize->machineCode))[3] = 0;
-		((self_in_dispatchConcretize->machineCodeSize) = 4);
+		((self_in_dispatchConcretize->machineCode))[mcIdx + 0] = 136;
+		((self_in_dispatchConcretize->machineCode))[mcIdx + 1] = (modRMRO(self_in_dispatchConcretize, ModRegRegDisp8, 4, src));
+		((self_in_dispatchConcretize->machineCode))[mcIdx + 2] = (sib(self_in_dispatchConcretize, SIB1, index1, base1));
+		((self_in_dispatchConcretize->machineCode))[mcIdx + 3] = 0;
+		if (!(swapreg == null)) {
+			((self_in_dispatchConcretize->machineCode))[mcIdx + 4] = (144 + swapreg);
+		}
+		((self_in_dispatchConcretize->machineCodeSize) = 4 + (2 * mcIdx));
 		return;
 
 	case MoveXwrRR:
@@ -6045,7 +6129,8 @@
 				: (((self_in_sizePCDependentInstructionAt->opcode)) == Jump
 						? 5
 						: 6))
-		: (((self_in_sizePCDependentInstructionAt->opcode)) == JumpLong
+		: ((((self_in_sizePCDependentInstructionAt->opcode)) == JumpLong)
+			 || (((self_in_sizePCDependentInstructionAt->opcode)) == JumpFull)
 				? 5
 				: 6)));
 }
@@ -6410,6 +6495,7 @@
     sqInt result;
     sqInt targetPC;
 
+	latestContinuation = 0;
 	/* begin mapFor:bcpc:performUntil:arg: */
 	assert(((cogMethod->stackCheckOffset)) > 0);
 	if (((cogMethod->cmType)) == CMMethod) {
@@ -6550,19 +6636,9 @@
 }
 
 static AbstractInstruction *
-CallRT(sqInt callTarget)
+CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved)
 {
     AbstractInstruction *abstractInstruction;
-
-	/* begin annotateCall: */
-	/* begin Call: */
-	abstractInstruction = genoperand(Call, callTarget);
-	return annotatewith(abstractInstruction, IsRelativeCall);
-}
-
-static AbstractInstruction *
-CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved)
-{
     sqInt callerSavedRegsToBeSaved;
     AbstractInstruction *lastInst;
     sqInt reg;
@@ -6575,7 +6651,11 @@
 			genoperand(PushR, reg);
 		}
 	}
-	lastInst = CallRT(callTarget);
+	/* begin CallRT: */
+	/* begin annotateCall: */
+	/* begin Call: */
+	abstractInstruction = genoperand(Call, callTarget);
+	lastInst = annotatewith(abstractInstruction, IsRelativeCall);
 	for (reg = GPRegMin; reg <= GPRegMax; reg += 1) {
 		if ((reg != TempReg)
 		 && (callerSavedRegsToBeSaved & (registerMaskFor(reg)))) {
@@ -7010,20 +7090,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -7116,20 +7190,14 @@
 					sendTable = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						offset1 = cmEntryOffset;
-						sendTable = selfSendTrampolines;
+						sendTable = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							offset1 = cmEntryOffset;
-							sendTable = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							offset1 = cmNoCheckEntryOffset;
-							sendTable = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						offset1 = cmNoCheckEntryOffset;
+						sendTable = superSendTrampolines;
 					}
 				}
 
@@ -7843,6 +7911,7 @@
 static void
 compileBlockEntry(BlockStart *blockStart)
 {
+    AbstractInstruction *abstractInstruction;
     sqInt alignment;
 
 	/* begin AlignmentNops: */
@@ -7872,7 +7941,11 @@
 	if (needsFrame) {
 		compileBlockFrameBuild(blockStart);
 		if (recordBlockTrace()) {
-			CallRT(ceTraceBlockActivationTrampoline);
+			/* begin CallRT: */
+			/* begin annotateCall: */
+			/* begin Call: */
+			abstractInstruction = genoperand(Call, ceTraceBlockActivationTrampoline);
+			annotatewith(abstractInstruction, IsRelativeCall);
 		}
 	}
 	else {
@@ -7890,6 +7963,8 @@
 static void
 compileCallFornumArgsargargargargresultRegsaveRegs(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt resultRegOrNil, sqInt saveRegs)
 {
+    AbstractInstruction *abstractInstruction;
+    sqInt callTarget;
     const int cStackAlignment = STACK_ALIGN_BYTES;
 
 	if (cStackAlignment > BytesPerWord) {
@@ -7930,7 +8005,12 @@
 			genPassConstasArgument(backEnd, regOrConst0, 0);
 		}
 	}
-	CallRT(((usqInt)aRoutine));
+	/* begin CallFullRT: */
+	callTarget = ((usqInt)aRoutine);
+	/* begin annotateCall: */
+	/* begin CallFull: */
+	abstractInstruction = genoperand(CallFull, callTarget);
+	annotatewith(abstractInstruction, IsRelativeCall);
 	if (!(resultRegOrNil == null)) {
 		genWriteCResultIntoReg(backEnd, resultRegOrNil);
 	}
@@ -7967,7 +8047,7 @@
 	/* begin MoveCw:R: */
 	genoperandoperand(MoveCwR, 99282957, SendNumArgsReg);
 	/* begin JumpLong: */
-	genoperand(JumpLong, 1592642142);
+	genoperand(JumpLong, methodZoneBase + 13262352);
 	jmpTarget(jumpNext, (endCPICCase0 = gLabel()));
 	for (h = 1; h < numPICCases; h += 1) {
 		/* begin CmpCw:R: */
@@ -7975,7 +8055,7 @@
 		/* begin MoveCw:R: */
 		genoperandoperand(MoveCwR, 195929424 + h, SendNumArgsReg);
 		/* begin JumpLongZero: */
-		genoperand(JumpLongZero, ((sqInt)3202131424UL));
+		genoperand(JumpLongZero, ((sqInt)(13262352 + (h * 16))));
 		if (h == 1) {
 			/* begin Label */
 			endCPICCase1 = genoperandoperand(Label, (labelCounter += 1), bytecodePC);
@@ -8071,6 +8151,8 @@
 static void
 compileEntry(void)
 {
+    AbstractInstruction *abstractInstruction;
+
 	entry = genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, TempReg, 1);
 	/* begin CmpR:R: */
 	genoperandoperand(CmpRR, ClassReg, TempReg);
@@ -8079,7 +8161,11 @@
 	/* begin Label */
 	noCheckEntry = genoperandoperand(Label, (labelCounter += 1), bytecodePC);
 	if (compileSendTrace()) {
-		CallRT(ceTraceLinkedSendTrampoline);
+		/* begin CallRT: */
+		/* begin annotateCall: */
+		/* begin Call: */
+		abstractInstruction = genoperand(Call, ceTraceLinkedSendTrampoline);
+		annotatewith(abstractInstruction, IsRelativeCall);
 
 	}
 }
@@ -8193,8 +8279,8 @@
 	back in resultRegOrNil.
 	Hack: a negative value indicates an abstract register, a non-negative
 	value indicates a constant. */
-/*	If on a RISC processor, the return address needs to be pushed to the
-	stack so that the interpreter sees the same stack layout as on CISC. */
+/*	If on an ARM-like RISC processor, the return address needs to be pushed to
+	the stack so that the interpreter sees the same stack layout as on CISC. */
 
 static void
 compileTrampolineFornumArgsargargargargsaveRegspushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt saveRegs, sqInt pushLinkReg, sqInt resultRegOrNil)
@@ -8203,9 +8289,9 @@
 	genSmalltalkToCStackSwitch();
 	compileCallFornumArgsargargargargresultRegsaveRegs(aRoutine, numArgs, regOrConst0, regOrConst1, regOrConst2, regOrConst3, resultRegOrNil, saveRegs);
 	genLoadStackPointers(backEnd);
-	
 	/* begin RetN: */
 	genoperand(RetN, 0);
+
 }
 
 
@@ -8594,6 +8680,12 @@
 		}
 		if (mcpc >= targetMcpc) {
 			assert(mcpc == targetMcpc);
+			if (annotation == IsDisplacementX2N) {
+				map -= 1;
+				mapByte = byteAt(map);
+				annotation = ((usqInt) mapByte) >> AnnotationShift;
+				assert(annotation > IsAnnotationExtension);
+			}
 			return map;
 		}
 		map -= 1;
@@ -9372,7 +9464,7 @@
 
 
 	/* write the return address to the coInterpreter instructionPointerAddress;
-	   CISCs will have pushed it on the stack, so pop it first; RISCs will have it in
+	   following the CallRT to this CISCs will have pushed it on the stack, so pop it first; RISCs will have it in
 	   their link register so just write it directly. */
 
 	opcodeIndex = 0;
@@ -9680,20 +9772,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -9713,7 +9799,7 @@
 static sqInt
 initialClosedPICUsageCount(void)
 {
-	return 2;
+	return CMMaxUsageCount / 2;
 }
 
 
@@ -9753,20 +9839,20 @@
 
 
 /*	Answer a usage count that reflects likely long-term usage.
-	Answer 0 for non-primitives or quick primitives (inst var accessors),
-	1 for methods with interpreter primitives, and 2 for compiled primitives. */
+	Answer 1 for non-primitives or quick primitives (inst var accessors),
+	2 for methods with interpreter primitives, and 3 for compiled primitives. */
 
 static sqInt
 initialMethodUsageCount(void)
 {
-	if ((primitiveIndex == 0)
+	if ((primitiveIndex == 1)
 	 || (isQuickPrimitiveIndex(primitiveIndex))) {
-		return 0;
+		return 1;
 	}
 	if ((primitiveGeneratorOrNil()) == null) {
-		return 1;
+		return 2;
 	}
-	return 2;
+	return 3;
 }
 
 
@@ -9775,7 +9861,7 @@
 static sqInt
 initialOpenPICUsageCount(void)
 {
-	return 3;
+	return CMMaxUsageCount - 1;
 }
 
 static sqInt
@@ -9964,22 +10050,7 @@
 	return jumpToTarget;
 }
 
-
-/*	Big assumption here that calls and jumps look the same as regards their
-	displacement. This works on x86 and I think on ARM. */
-
 static AbstractInstruction *
-JumpRT(sqInt callTarget)
-{
-    AbstractInstruction *abstractInstruction;
-
-	/* begin annotateCall: */
-	/* begin JumpLong: */
-	abstractInstruction = genoperand(JumpLong, callTarget);
-	return annotatewith(abstractInstruction, IsRelativeCall);
-}
-
-static AbstractInstruction *
 gLabel(void)
 {
 	return genoperandoperand(Label, (labelCounter += 1), bytecodePC);
@@ -10216,6 +10287,7 @@
     sqInt result;
     sqInt val;
 
+	val = 0;
 	hasYoungObj = 0;
 	hasYoungObjPtr = ((sqInt)((&hasYoungObj)));
 	codeModified = (freedPIC = 0);
@@ -10412,6 +10484,7 @@
     sqInt result;
     sqInt val;
 
+	val = 0;
 	hasYoungObj = 0;
 	hasYoungObjPtr = ((sqInt)((&hasYoungObj)));
 	codeModified = 0;
@@ -10533,6 +10606,8 @@
     sqInt val;
     sqInt val1;
 
+	val = 0;
+	val1 = 0;
 	if (leakCheckFullGC()) {
 		assert(allMachineCodeObjectReferencesValid());
 	}
@@ -10688,6 +10763,7 @@
     sqInt tagCouldBeObj;
     sqInt tagCouldBeObj1;
 
+	literal = 0;
 	if (annotation == IsObjectReference) {
 		literal = literalBeforeFollowingAddress(backEnd, ((usqInt)mcpc));
 		if (markAndTraceLiteralinatpc(literal, ((CogMethod *) cogMethod), ((usqInt)mcpc))) {
@@ -10933,6 +11009,7 @@
     sqInt result;
     sqInt targetPC;
 
+	latestContinuation = 0;
 	/* begin mapFor:bcpc:performUntil:arg: */
 	assert(((cogMethod->stackCheckOffset)) > 0);
 	if (((cogMethod->cmType)) == CMMethod) {
@@ -11145,7 +11222,7 @@
 }
 
 
-/*	Check that no metod is maximally marked. A maximal mark is an indication
+/*	Check that no method is maximally marked. A maximal mark is an indication
 	the method has been scanned to increase the usage count of its referent
 	methods.  */
 
@@ -11852,20 +11929,14 @@
 				sendTable1 = selfSendTrampolines;
 			}
 			else {
-				if (annotation == IsNSSelfSend) {
+				if (annotation == IsNSDynamicSuperSend) {
 					offset1 = cmEntryOffset;
-					sendTable1 = selfSendTrampolines;
+					sendTable1 = dynamicSuperSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
-						offset1 = cmEntryOffset;
-						sendTable1 = selfSendTrampolines;
-					}
-					else {
-						assert(annotation == IsSuperSend);
-						offset1 = cmNoCheckEntryOffset;
-						sendTable1 = superSendTrampolines;
-					}
+					assert(annotation == IsSuperSend);
+					offset1 = cmNoCheckEntryOffset;
+					sendTable1 = superSendTrampolines;
 				}
 			}
 
@@ -12038,20 +12109,14 @@
 						sendTable = selfSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
+						if (annotation == IsNSDynamicSuperSend) {
 							targetMethod1 = ((CogMethod *) (entryPoint2 - cmEntryOffset));
-							sendTable = selfSendTrampolines;
+							sendTable = dynamicSuperSendTrampolines;
 						}
 						else {
-							if (annotation == IsNSSelfSend) {
-								targetMethod1 = ((CogMethod *) (entryPoint2 - cmEntryOffset));
-								sendTable = selfSendTrampolines;
-							}
-							else {
-								assert(annotation == IsSuperSend);
-								targetMethod1 = ((CogMethod *) (entryPoint2 - cmNoCheckEntryOffset));
-								sendTable = superSendTrampolines;
-							}
+							assert(annotation == IsSuperSend);
+							targetMethod1 = ((CogMethod *) (entryPoint2 - cmNoCheckEntryOffset));
+							sendTable = superSendTrampolines;
 						}
 					}
 
@@ -12291,20 +12356,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -12371,20 +12430,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -12460,20 +12513,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -12541,20 +12588,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -12620,20 +12661,14 @@
 					sendTable1 = selfSendTrampolines;
 				}
 				else {
-					if (annotation == IsNSSelfSend) {
+					if (annotation == IsNSDynamicSuperSend) {
 						targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-						sendTable1 = selfSendTrampolines;
+						sendTable1 = dynamicSuperSendTrampolines;
 					}
 					else {
-						if (annotation == IsNSSelfSend) {
-							targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset));
-							sendTable1 = selfSendTrampolines;
-						}
-						else {
-							assert(annotation == IsSuperSend);
-							targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
-							sendTable1 = superSendTrampolines;
-						}
+						assert(annotation == IsSuperSend);
+						targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset));
+						sendTable1 = superSendTrampolines;
 					}
 				}
 
@@ -13303,7 +13338,7 @@
 		cogMethod = ((CogMethod *) baseAddress);
 		while (((((usqInt)cogMethod)) < mzFreeStart)
 		 && (freedSoFar < amountToFree)) {
-			if ((((cogMethod->cmType)) != CMFree)
+			if ((((cogMethod->cmType)) == CMMethod)
 			 && (((cogMethod->cmUsageCount)) <= freeableUsage)) {
 				freeMethod(cogMethod);
 				freedSoFar += (cogMethod->blockSize);
@@ -13773,17 +13808,7 @@
 	return 0;
 }
 
-static sqInt
-genConvertIntegerToSmallIntegerInScratchReg(sqInt scratchReg)
-{
-	/* begin LogicalShiftLeftCq:R: */
-	genoperandoperand(LogicalShiftLeftCqR, 1, scratchReg);
-	/* begin AddCq:R: */
-	genoperandoperand(AddCqR, 1, scratchReg);
-	return 0;
-}
 
-
 /*	Convert the SmallInteger in reg to a Character, assuming
 	the SmallInteger's value is a valid character. */
 /*	self assume: objectMemory smallIntegerTag = 1 */
@@ -13849,10 +13874,12 @@
 static sqInt
 genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock)
 {
+    AbstractInstruction *abstractInstruction;
     sqInt address;
     sqInt address1;
     AbstractInstruction *continuation;
     AbstractInstruction *exit;
+    AbstractInstruction *first;
     usqLong header;
     AbstractInstruction *jumpNeedScavenge;
     AbstractInstruction *jumpSingle;
@@ -13863,15 +13890,21 @@
     sqInt quickConstant2;
     sqInt quickConstant3;
     sqInt quickConstant4;
+    sqInt quickConstant5;
     sqInt slotSize;
     sqInt wordConstant;
 
+
+	/* load the flag; stash it in both TempReg & ClassReg; do the compare (a prime candidated for use of AndCq:R:R:) */
+
 	/* begin MoveMw:r:R: */
-	genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, TempReg);
-	/* begin MoveR:R: */
-	genoperandoperand(MoveRR, TempReg, ClassReg);
-	/* begin AndCq:R: */
+	genoperandoperandoperand(MoveMwrR, FoxMethod, FPReg, ClassReg);
+	/* begin AndCq:R:R: */
+	;
+	first = genoperandoperand(MoveRR, ClassReg, TempReg);
 	genoperandoperand(AndCqR, MFMethodFlagHasContextFlag, TempReg);
+	first;
+l1:	/* end AndCq:R:R: */;
 	/* begin JumpZero: */

@@ Diff output truncated at 50000 characters. @@


More information about the Vm-dev mailing list