From c6c18805f2a5ba03b5ea3e765bb7fec1a2fce248 Mon Sep 17 00:00:00 2001 From: Eliot Miranda Date: Thu, 12 Aug 2021 11:19:59 -0700 Subject: [PATCH] CogVM source as per VMMaker.oscog-eem.3034 CogARMv8Compiler: Make sure the generated cache flush code flushes the range (startAddress to endAddress], i.e. never flush endAddress, only addresses less than endAddress. Flushing endAddress can cause a segmentation violation if the endAddress is on an empty page. --- nsspur64src/vm/cogit.h | 3 +- nsspur64src/vm/cogitARMv8.c | 997 ++++++++++++++------- nsspur64src/vm/cogitX64SysV.c | 979 +++++++++++++------- nsspur64src/vm/cogitX64WIN64.c | 1012 ++++++++++++++------- nsspur64src/vm/cointerp.c | 1440 +++++++++++------------------- nsspur64src/vm/cointerp.h | 9 +- nsspur64src/vm/gcc3x-cointerp.c | 1440 +++++++++++------------------- spur64src/vm/cogit.h | 2 +- spur64src/vm/cogitARMv8.c | 12 +- spurlowcode64src/vm/cogit.h | 2 +- spurlowcode64src/vm/cogitARMv8.c | 16 +- spursista64src/vm/cogit.h | 2 +- spursista64src/vm/cogitARMv8.c | 16 +- 13 files changed, 3124 insertions(+), 2806 deletions(-) diff --git a/nsspur64src/vm/cogit.h b/nsspur64src/vm/cogit.h index 1af5b9d7ab..49387a6559 100644 --- a/nsspur64src/vm/cogit.h +++ b/nsspur64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ @@ -148,6 +148,7 @@ extern sqInt traceStores; #define printOnTrace() (traceFlags & 1) #define recordBlockTrace() (traceFlags & 4) #define recordEventTrace() (traceFlags & 16) +#define recordFastCCallPrimTrace() (traceFlags & 512) #define recordOverflowTrace() (traceFlags & 32) #define recordPrimTrace() (traceFlags & 8) #define recordSendTrace() (traceFlags & 2) diff --git a/nsspur64src/vm/cogitARMv8.c b/nsspur64src/vm/cogitARMv8.c index 3749abb75d..713b946786 100644 --- a/nsspur64src/vm/cogitARMv8.c +++ b/nsspur64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -70,18 +70,18 @@ char *__cogitBuildInfo = __buildInfo; #define CArg1Reg 1 #define CArg2Reg 2 #define CArg3Reg 3 -#define CASAL 174 +#define CASAL 176 #define Call 6 #define CallerSavedRegisterMask 0x1F0 #define CallFull 7 -#define CBNZ 175 -#define CBZ 176 +#define CBNZ 177 +#define CBZ 178 #define CC 3 -#define CCMPNE 177 +#define CCMPNE 179 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLREX 179 +#define CLREX 181 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -112,8 +112,8 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRdR 146 #define ConvertRRd 145 #define CS 2 -#define CSET 178 -#define DC 167 +#define CSET 180 +#define DC 169 #define DC_CIVAC 14 #define DC_CVAC 16 #define DC_CVAU 19 @@ -121,7 +121,7 @@ char *__cogitBuildInfo = __buildInfo; #define DisplacementMask 0x1F #define DisplacementX2N 0 #define DivRdRd 135 -#define DivRRR 161 +#define DivRRR 163 #define DPFPReg0 0 #define DPFPReg1 1 #define DPFPReg2 2 @@ -130,7 +130,7 @@ char *__cogitBuildInfo = __buildInfo; #define DPFPReg5 5 #define DPFPReg6 6 #define DPFPReg7 7 -#define DSB 170 +#define DSB 172 #define DSB_ALL 3 #define DSB_ISH 2 #define EncounteredUnknownBytecode -6 @@ -139,6 +139,7 @@ char *__cogitBuildInfo = __buildInfo; #define Extra1Reg 20 #define Extra2Reg 21 #define Extra8Reg 27 +#define FastCPrimitiveUseCABIFlag 4 #define Fill32 4 #define FirstAnnotation 64 #define FirstJump 12 @@ -159,7 +160,7 @@ char *__cogitBuildInfo = __buildInfo; #define HasBytecodePC 5 #define HeaderIndex 0 #define HI 8 -#define IC 168 +#define IC 170 #define IC_IALLU 0 #define IC_IALLUIS 1 #define IC_IVAU 2 @@ -171,7 +172,7 @@ char *__cogitBuildInfo = __buildInfo; #define InstructionPointerIndex 1 #define InsufficientCodeSpace -2 #define InVanillaBlock 1 -#define ISB 171 +#define ISB 173 #define IsAbsPCReference 3 #define IsAnnotationExtension 1 #define IsDirectedSuperBindingSend 10 @@ -219,7 +220,7 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LDAXR 180 +#define LDAXR 182 #define LE 13 #define LinkReg 30 #define Literal 2 @@ -260,7 +261,7 @@ char *__cogitBuildInfo = __buildInfo; #define MI 4 #define MoveAbR 48 #define MoveAwR 44 -#define MoveAwRR 163 +#define MoveAwRR 165 #define MoveC32R 71 #define MoveCqR 69 #define MoveCwR 70 @@ -269,6 +270,8 @@ char *__cogitBuildInfo = __buildInfo; #define MoveM64rRd 75 #define MoveMbrR 65 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRAb 49 #define MoveRAw 46 #define MoveRdM64r 76 @@ -278,7 +281,7 @@ char *__cogitBuildInfo = __buildInfo; #define MoveRMbr 66 #define MoveRMwr 51 #define MoveRR 43 -#define MoveRRAw 164 +#define MoveRRAw 166 #define MoveRRd 72 #define MoveRX16rR 60 #define MoveRX32rR 64 @@ -288,17 +291,17 @@ char *__cogitBuildInfo = __buildInfo; #define MoveX32rRR 63 #define MoveXbrRR 67 #define MoveXwrRR 52 -#define MRS_CTR_EL0 172 -#define MRS_ID_AA64ISAR0_EL1 173 -#define MSubRRR 162 +#define MRS_CTR_EL0 174 +#define MRS_ID_AA64ISAR0_EL1 175 +#define MSubRRR 164 #define MULTIPLEBYTECODESETS 1 -#define MulOverflowRRR 159 +#define MulOverflowRRR 161 #define MulRdRd 134 -#define MulRRR 158 +#define MulRRR 160 #define NativePopR 84 -#define NativePopRR 166 +#define NativePopRR 168 #define NativePushR 85 -#define NativePushRR 165 +#define NativePushRR 167 #define NativeRetN 86 #define NativeSPReg 31 #define NE 1 @@ -334,6 +337,7 @@ char *__cogitBuildInfo = __buildInfo; #define PrimCallNeedsNewMethod 1 #define PrimCallNeedsPrimitiveFunction 2 #define PrimCallOnSmalltalkStack 64 +#define PrimCallOnSmalltalkStackAlign2x 128 #define PrimErrNoMemory 9 #define PrimNumberExternalCall 117 #define PrimNumberFFICall 120 @@ -369,10 +373,11 @@ char *__cogitBuildInfo = __buildInfo; #define SSConstant 2 #define SSRegister 3 #define SSSpill 4 -#define STLR 182 -#define STLXR 181 +#define STLR 184 +#define STLXR 183 #define StackPointerIndex 2 #define Stop 11 +#define SubbRR 121 #define SubCqR 107 #define SubCwR 115 #define SubRdRd 133 @@ -519,6 +524,8 @@ static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLiteralFrom, AbstractInstruction *existingLiteral); static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); +static sqInt NoDbgRegParms genLoadStackPointerForPrimCall(AbstractInstruction * self_in_genLoadStackPointerForPrimCall, sqInt spareReg); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -549,6 +556,7 @@ static sqInt NoDbgRegParms concretizeLoadEffectiveAddressMwrR(AbstractInstructio static sqInt NoDbgRegParms concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRDest, sqInt op, sqInt destReg); static sqInt NoDbgRegParms concretizeMoveCqR(AbstractInstruction * self_in_concretizeMoveCqR); static sqInt NoDbgRegParms concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitSizeLog2MinusOne); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRMSr(AbstractInstruction * self_in_concretizeMoveRMSr, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveRXSrR(AbstractInstruction * self_in_concretizeMoveRXSrR, sqInt unitSizeLog2MinusOne); static sqInt NoDbgRegParms concretizeMoveXSrRR(AbstractInstruction * self_in_concretizeMoveXSrRR, sqInt unitSizeLog2MinusOne); @@ -580,6 +588,7 @@ static void NoDbgRegParms generateDCacheFlush(AbstractInstruction * self_in_gene static void NoDbgRegParms generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush); static AbstractInstruction * NoDbgRegParms generateLowLevelTryLock(AbstractInstruction * self_in_generateLowLevelTryLock, sqInt vmOwnerLockAddress); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); +static void NoDbgRegParms genLoadNativeSPRegWithAlignedSPReg(AbstractInstruction * self_in_genLoadNativeSPRegWithAlignedSPReg); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); static AbstractInstruction * NoDbgRegParms genMarshallNArgsargargargarg(AbstractInstruction * self_in_genMarshallNArgsargargargarg, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3); static AbstractInstruction * NoDbgRegParms genMulOverflowRR(AbstractInstruction * self_in_genMulOverflowRR, sqInt regSource, sqInt regDest); @@ -591,6 +600,7 @@ static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genResto static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); +static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, sqInt callSiteReturnAddress); static sqInt NoDbgRegParms instructionAddressBefore(AbstractInstruction * self_in_instructionAddressBefore, sqInt mcpc); static unsigned int NoDbgRegParms instructionAt(AbstractInstruction * self_in_instructionAt, sqInt pc); @@ -656,6 +666,7 @@ static CogMethod * NoDbgRegParms cmHomeMethod(CogBlockMethod * self_in_cmHomeMet static sqInt NoDbgRegParms isBranch(BytecodeDescriptor * self_in_isBranch); static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); +static AbstractInstruction * NoDbgRegParms gAddRRR(sqInt addendReg, sqInt badendReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); @@ -687,7 +698,7 @@ static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); extern void ceFree(void *pointer); static void* NoDbgRegParms ceMalloc(size_t size); static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod); +static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); @@ -812,6 +823,8 @@ static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveAwR(sqInt address, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisterMask); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisterMask); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -860,6 +873,7 @@ static void NoDbgRegParms recordGeneratedRunTimeaddress(char *aString, sqInt add extern sqInt recordPrimTraceFunc(void); static void recordRunTimeObjectReferences(void); static sqInt NoDbgRegParms registerMaskFor(sqInt reg); +static sqInt NoDbgRegParms registerMaskForand(sqInt reg1, sqInt reg2); static void NoDbgRegParms relocateCallsAndSelfReferencesInMethod(CogMethod *cogMethod); static void NoDbgRegParms relocateCallsInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms relocateIfCallOrMethodReferencemcpcdelta(sqInt annotation, char *mcpc, CogMethod *refDeltaArg); @@ -1132,7 +1146,7 @@ static sqInt compileBlockDispatch(void); static void compileGetErrorCode(void); static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)); +static sqInt NoDbgRegParms compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); @@ -1212,6 +1226,7 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); @@ -1993,7 +2008,6 @@ static AbstractInstruction * picInterpretAbort; static sqInt picMissTrampolines[4]; static AbstractInstruction * picMNUAbort; static BytecodeDescriptor * prevBCDescriptor; -static AbstractInstruction * primInvokeInstruction; static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { { 0, -1 }, { genPrimitiveAdd, 1 }, @@ -2573,7 +2587,6 @@ static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] { genPrimitiveHighBit, 0 } }; static sqInt primitiveIndex; -static AbstractInstruction * primSetFunctionLabel; static sqInt processorLock; static sqInt receiverTags; static sqInt runtimeObjectRefIndex; @@ -2723,6 +2736,7 @@ void (*realCEEnterCogCodePopReceiverReg)(void); #define print(aString) printf("%s", aString) #define recordBlockTrace() (traceFlags & 4) #define recordEventTrace() (traceFlags & 16) +#define recordFastCCallPrimTrace() (traceFlags & 512) #define recordOverflowTrace() (traceFlags & 32) #define recordPrimTrace() (traceFlags & 8) #define recordSendTrace() (traceFlags & 2) @@ -2779,28 +2793,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2815,19 +2829,19 @@ availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegi static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -2883,6 +2897,40 @@ genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer) } +/* Switch back to the Smalltalk stack where there may be a C return address + on top of stack below + the last primitive argument. Assign SPReg first because typically it is + used immediately afterwards. + */ + + /* CogAbstractInstruction>>#genLoadStackPointerForPrimCall: */ +static sqInt NoDbgRegParms +genLoadStackPointerForPrimCall(AbstractInstruction * self_in_genLoadStackPointerForPrimCall, sqInt spareReg) +{ + sqInt operandOne; + + /* begin gen:literal:operand: */ + operandOne = stackPointerAddress(); + checkLiteralforInstruction(operandOne, genoperandoperand(MoveAwR, operandOne, SPReg)); + return 0; +} + + +/* Switch back to the Smalltalk stack where there may be a C return address + on top of stack below + the last primitive argument. Assign SPReg first because typically it is + used immediately afterwards. + */ + + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ +static sqInt NoDbgRegParms +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) +{ + genLoadStackPointers(self_in_genLoadStackPointersForPrimCall); + return 0; +} + + /* Generic register swap code. Subclasses for processors that have a true exchange operation will override to use it. */ @@ -3171,16 +3219,26 @@ static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) { sqInt constant; + sqInt constant1; sqInt imm; + sqInt imm1; sqInt immediate; sqInt immr1; + sqInt immr2; usqInt mask; + usqInt mask1; usqInt n1; + usqInt n2; usqInt nImms; + usqInt nImms1; sqInt numLeadingOnes; + sqInt numLeadingOnes1; sqInt numTrailingOnes; + sqInt numTrailingOnes1; sqInt rotateCount; + sqInt rotateCount1; sqInt size; + sqInt size1; switch ((self_in_computeMaximumSize->opcode)) { case Label: @@ -3237,7 +3295,6 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) return 8; case AndCqR: - case AndCqRR: case OrCqR: case OrCqRR: case TstCqR: @@ -3289,6 +3346,62 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) assert((decode64Immsimmr(self_in_computeMaximumSize, nImms, immr1)) == (((usqInt) constant))); return 4; + case AndCqRR: + + /* N.B. For three operand logical ops only support AndCqRR with a NativeSPReg target, used for alignment purposes. */ + /* begin isImmNImmSImmREncodableBitmask:ifTrue:ifFalse: */ + constant1 = ((self_in_computeMaximumSize->operands))[0]; + if (((constant1 >= -1) && (constant1 <= 0))) { + return ((((self_in_computeMaximumSize->operands))[2]) == SP + ? 12 + : 8); + } + + /* First, determine the element size. */ + imm1 = constant1; + size1 = 32; + while (1) { + mask1 = (1ULL << size1) - 1; + if (!(((imm1 & mask1) != (((usqInt)(imm1)) >> size1) + ? ((size1 = size1 * 2), + 0) + : size1 > 2))) break; + size1 = size1 / 2; + } + mask1 = ((usqInt)((0xFFFFFFFFFFFFFFFFULL))) >> (64 - size1); + imm1 = imm1 & mask1; + if (isShiftedMask(self_in_computeMaximumSize, imm1)) { + rotateCount1 = countTrailingZeros(self_in_computeMaximumSize, imm1); + numTrailingOnes1 = countTrailingOnes(self_in_computeMaximumSize, ((usqInt)(imm1)) >> rotateCount1); + } + else { + imm1 = imm1 | (~(usqIntptr_t)mask1); + if (!(isShiftedMask(self_in_computeMaximumSize, imm1))) { + return ((((self_in_computeMaximumSize->operands))[2]) == SP + ? 12 + : 8); + } + numLeadingOnes1 = countLeadingOnes(self_in_computeMaximumSize, imm1); + rotateCount1 = 64 - numLeadingOnes1; + numTrailingOnes1 = (numLeadingOnes1 + (countTrailingOnes(self_in_computeMaximumSize, imm1))) - (64 - size1); + } + assert(size1 > rotateCount1); + + /* If size has a 1 in the n'th bit, create a value that has zeroes in bits [0, n] and ones above that. */ + immr2 = (size1 - rotateCount1) & (size1 - 1); + + /* Or the CTO value into the low bits, which must be below the Nth bit mentioned above. */ + nImms1 = ((sqInt)((usqInt)((~(usqIntptr_t)(size1 - 1))) << 1)); + + /* Extract the seventh bit and toggle it to create the N field. */ + nImms1 = nImms1 | (numTrailingOnes1 - 1); + n2 = (((nImms1) >> 6) & 1) ^ 1; + nImms1 = nImms1 & 0x3F; + assert((decode64Immsimmr(self_in_computeMaximumSize, nImms1, immr2)) == (((usqInt) constant1))); + return ((((self_in_computeMaximumSize->operands))[2]) == SP + ? 8 + : 4); + case SubRR: case SubRRR: return ((((self_in_computeMaximumSize->operands))[0]) == SP @@ -3609,6 +3722,7 @@ static sqInt NoDbgRegParms concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRDest, sqInt op, sqInt destReg) { usqInt constant; + sqInt effectiveDestReg; sqInt imm; sqInt immr1; usqInt mask; @@ -3622,7 +3736,13 @@ concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRD usqInt srcReg; constant = ((self_in_concretizeLogicalOpCqRDest->operands))[0]; + + /* N.B. For three operand logical ops only support AndCq: const R: reg R: NativeSPReg, which is used for alignment. */ srcReg = ((self_in_concretizeLogicalOpCqRDest->operands))[1]; + effectiveDestReg = ((((self_in_concretizeLogicalOpCqRDest->opcode)) == AndCqRR) + && (destReg == SP) + ? RISCTempReg + : destReg); /* begin isImmNImmSImmREncodableBitmask:ifTrue:ifFalse: */ if (((constant >= -1) && (constant <= 0))) { @@ -3636,8 +3756,9 @@ concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRD 11 0 ANDS (shifted register) - 64-bit variant on page C6-781 11 0 BICS (shifted register) - 64-bit variant on page C6-810 */ offset = emitMoveCwintoRat(self_in_concretizeLogicalOpCqRDest, constant, RISCTempReg, 0); - ((self_in_concretizeLogicalOpCqRDest->machineCode))[offset / 4] = (((((0x8A000000U) + (((sqInt)((usqInt)(op) << 29)))) + (((sqInt)((usqInt)(RISCTempReg) << 16)))) + (srcReg << 5)) + destReg); - return offset + 4; + ((self_in_concretizeLogicalOpCqRDest->machineCode))[offset / 4] = (((((0x8A000000U) + (((sqInt)((usqInt)(op) << 29)))) + (((sqInt)((usqInt)(RISCTempReg) << 16)))) + (srcReg << 5)) + effectiveDestReg); + offset += 4; + goto l1; } /* First, determine the element size. */ @@ -3671,8 +3792,9 @@ concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRD 11 0 ANDS (shifted register) - 64-bit variant on page C6-781 11 0 BICS (shifted register) - 64-bit variant on page C6-810 */ offset = emitMoveCwintoRat(self_in_concretizeLogicalOpCqRDest, constant, RISCTempReg, 0); - ((self_in_concretizeLogicalOpCqRDest->machineCode))[offset / 4] = (((((0x8A000000U) + (((sqInt)((usqInt)(op) << 29)))) + (((sqInt)((usqInt)(RISCTempReg) << 16)))) + (srcReg << 5)) + destReg); - return offset + 4; + ((self_in_concretizeLogicalOpCqRDest->machineCode))[offset / 4] = (((((0x8A000000U) + (((sqInt)((usqInt)(op) << 29)))) + (((sqInt)((usqInt)(RISCTempReg) << 16)))) + (srcReg << 5)) + effectiveDestReg); + offset += 4; + goto l1; } numLeadingOnes = countLeadingOnes(self_in_concretizeLogicalOpCqRDest, imm); rotateCount = 64 - numLeadingOnes; @@ -3691,8 +3813,15 @@ concretizeLogicalOpCqRDest(AbstractInstruction * self_in_concretizeLogicalOpCqRD n1 = (((nImms) >> 6) & 1) ^ 1; nImms = nImms & 0x3F; assert((decode64Immsimmr(self_in_concretizeLogicalOpCqRDest, nImms, immr1)) == (((usqInt) constant))); - ((self_in_concretizeLogicalOpCqRDest->machineCode))[0] = (((((((0x92000000U) + (((sqInt)((usqInt)(op) << 29)))) + (n1 << 22)) + (((sqInt)((usqInt)(immr1) << 16)))) + (nImms << 10)) + (srcReg << 5)) + destReg); - return 4; + ((self_in_concretizeLogicalOpCqRDest->machineCode))[0] = (((((((0x92000000U) + (((sqInt)((usqInt)(op) << 29)))) + (n1 << 22)) + (((sqInt)((usqInt)(immr1) << 16)))) + (nImms << 10)) + (srcReg << 5)) + effectiveDestReg); + offset = 4; + l1: /* end isImmNImmSImmREncodableBitmask:ifTrue:ifFalse: */; + if (!((((self_in_concretizeLogicalOpCqRDest->opcode)) == AndCqRR) + && (destReg == SP))) { + return offset; + } + ((self_in_concretizeLogicalOpCqRDest->machineCode))[offset / 4] = (movernrd(self_in_concretizeLogicalOpCqRDest, effectiveDestReg, destReg)); + return offset + 4; } @@ -3824,6 +3953,18 @@ concretizeMoveMSrR(AbstractInstruction * self_in_concretizeMoveMSrR, sqInt unitS } +/* D13.8.26 CNTVCT_EL0, Counter-timer Virtual Count register p D13-3774 */ +/* MRS , CNTVCT_EL0 op0:0b11 op1:0b011 CRn:0b1110 CRm:0b0000 op2:0b010 */ + + /* CogARMv8Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = ((3577471040U) + (((self_in_concretizeMovePerfCnt64RL->operands))[0])); + return 4; +} + + /* Mwr/M32r/M16r/Mbr - memory unit whose address is a constant M away from an address in a register */ @@ -4600,7 +4741,7 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[0] = (((0xD6400000U) + (((sqInt)((usqInt)(XZR) << 16)))) + (((sqInt)((usqInt)(LR) << 5)))); return 4; } - ((self_in_dispatchConcretize->machineCode))[0] = (addrnrdimmshiftBy12(self_in_dispatchConcretize, NativeSPReg, NativeSPReg, offset5, 0)); + ((self_in_dispatchConcretize->machineCode))[0] = (addrnrdimmshiftBy12(self_in_dispatchConcretize, SP, SP, offset5, 0)); ((self_in_dispatchConcretize->machineCode))[1] = (((0xD6400000U) + (((sqInt)((usqInt)(XZR) << 16)))) + (((sqInt)((usqInt)(LR) << 5)))); return 8; @@ -5517,6 +5658,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) : 0))) + (((sqInt)((usqInt)((offset9 & (0x1FFFFF))) << 3)))) + reg9); return 4; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -5814,7 +5958,7 @@ generateDCacheFlush(AbstractInstruction * self_in_generateDCacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperand(RetN, 0); # endif // !(__APPLE__ && __MACH__) } @@ -5933,7 +6077,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); } genoperandoperand(DSB, DSB_ISH, DSB_ALL); if (instructionCacheFlushRequired(self_in_generateICacheFlush)) { @@ -5955,7 +6099,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperandoperand(DSB, DSB_ISH, DSB_ALL); } gen(ISB); @@ -6074,7 +6218,7 @@ genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) sqInt operandOne1; if (((cStackPointerAddress()) + 8) == (cFramePointerAddress())) { - genoperandoperandoperand(MoveAwRR, cStackPointerAddress(), NativeSPReg, FPReg); + genoperandoperandoperand(MoveAwRR, cStackPointerAddress(), SP, FP); return 0; } /* begin gen:literal:operand: */ @@ -6086,6 +6230,13 @@ genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) return 0; } + /* CogARMv8Compiler>>#genLoadNativeSPRegWithAlignedSPReg */ +static void NoDbgRegParms +genLoadNativeSPRegWithAlignedSPReg(AbstractInstruction * self_in_genLoadNativeSPRegWithAlignedSPReg) +{ + gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, SP); +} + /* Switch back to the Smalltalk stack. Assign SPReg first because typically it is used immediately afterwards. */ @@ -6352,7 +6503,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); nRegs = 0; for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { nRegs += 1; } } @@ -6360,7 +6511,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) ? NoReg : RISCTempReg); for (reg = R1; reg <= R17; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -6395,7 +6546,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(!((registerisInMask(RISCTempReg, regMask)))); pair = NoReg; for (reg = R17; reg >= R0; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { if (pair == NoReg) { pair = reg; } @@ -6448,6 +6599,17 @@ genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddr return checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); } + +/* Answer if the processor has a dedicated callee-saved register to point to + the base of commonly-accessed variables. On ARMv8 we use R27 for this. */ + + /* CogARMv8Compiler>>#hasVarBaseRegister */ +static sqInt NoDbgRegParms +hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) +{ + return 1; +} + /* CogARMv8Compiler>>#inlineCacheTagAt: */ static usqInt NoDbgRegParms inlineCacheTagAt(AbstractInstruction * self_in_inlineCacheTagAt, sqInt callSiteReturnAddress) @@ -7678,6 +7840,22 @@ gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) return first; } + +/* destReg := addendReg + badendReg */ + + /* Cogit>>#AddR:R:R: */ +static AbstractInstruction * NoDbgRegParms +gAddRRR(sqInt addendReg, sqInt badendReg, sqInt destReg) +{ + AbstractInstruction * first; + + return genoperandoperandoperand(AddRRR, addendReg, badendReg, destReg); + assert(badendReg != destReg); + first = genoperandoperand(MoveRR, addendReg, destReg); + genoperandoperand(AddRR, badendReg, destReg); + return first; +} + /* Cogit>>#AndCq:R: */ static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg) @@ -8609,7 +8787,7 @@ ceSICMiss(sqInt receiver) /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod) +checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) { usqInt cacheAddress; usqInt cacheTag1; @@ -10278,7 +10456,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ } @@ -11846,7 +12024,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -11896,7 +12074,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) operandTwo2 = cStackPointerAddress(); checkLiteralforInstruction(operandTwo2, genoperandoperand(MoveRAw, NativeSPReg, operandTwo2)); } - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -13087,8 +13265,8 @@ initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) null # endif ); - stopsFromto(backEnd, startAddress, endAddress - 1); codeBase = (methodZoneBase = startAddress); + stopsFromto(backEnd, startAddress, endAddress - 1); minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); /* begin manageFrom:to: */ mzFreeStart = (baseAddress = methodZoneBase); @@ -13602,6 +13780,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return checkLiteralforInstruction(wordConstant, genoperandoperand(MoveCwR, wordConstant, reg)); } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisterMask) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisterMask); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisterMask) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisterMask); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -15387,11 +15581,21 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); +} + + /* Cogit>>#registerMaskFor:and: */ +static sqInt NoDbgRegParms +registerMaskForand(sqInt reg1, sqInt reg2) +{ + return (1ULL << reg1) | (1ULL << reg2); } /* Cogit>>#relocateCallsAndSelfReferencesInMethod: */ @@ -17250,6 +17454,13 @@ voidCogCompiledCode(void) unpairedMethodList = null; methodBytesFreedSinceLastCompaction = 0; methodCount = 0; + /* begin ensureExecutableCodeZone */ +# if !DUAL_MAPPED_CODE_ZONE + /* begin makeCodeZoneExecutable */ +# if __APPLE__ && __MACH__ + pthread_jit_write_protect_np(1); +# endif +# endif } /* Cogit>>#XorCw:R: */ @@ -24020,7 +24231,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -25594,7 +25805,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -25610,7 +25821,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -26212,7 +26423,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -26225,7 +26436,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -26638,50 +26849,41 @@ compileGetErrorCode(void) /* Compile a call to an interpreter primitive. Call the C routine with the usual stack-switching dance, test the primFailCode and then either return on success or continue to the method body. */ -/* Save processor fp, sp and return pc in the interpreter's frame stack and - instruction pointers - */ /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { + sqInt address; + sqInt address1; sqInt address10; - sqInt address11; - sqInt address12; - sqInt address13; sqInt address2; - sqInt address3; sqInt address4; + sqInt address6; sqInt address7; sqInt address8; sqInt address9; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jump; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisterMask; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; + AbstractInstruction * skip; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); + assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ if (cFramePointerInUse) { @@ -26690,53 +26892,36 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction)) { - (anInstruction->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction8)) { - (anInstruction8->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction4 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction4)) { + (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveR:Aw: */ - address11 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address11, genoperandoperand(MoveRAw, TempReg, address11)); + checkLiteralforInstruction(address6, genoperandoperand(MoveRAw, TempReg, address6)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); + if (usesOutOfLineLiteral(anInstruction)) { + (anInstruction->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); } } /* begin MoveR:Aw: */ - address12 = argumentCountAddress(); + address7 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address12, genoperandoperand(MoveRAw, TempReg, address12)); + checkLiteralforInstruction(address7, genoperandoperand(MoveRAw, TempReg, address7)); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin MoveCw:R: */ checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); /* begin MoveR:Aw: */ - address3 = primitiveFunctionPointerAddress(); + address = primitiveFunctionPointerAddress(); /* begin gen:operand:literal: */ - primSetFunctionLabel = checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address, genoperandoperand(MoveRAw, TempReg, address)); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -26748,22 +26933,21 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(offset, BytesPerOop)); + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin MoveR:Aw: */ - address4 = newMethodAddress(); + address1 = newMethodAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); } /* begin PrefetchAw: */ - address13 = primFailCodeAddress(); + address8 = primFailCodeAddress(); /* begin gen:literal: */ - checkLiteralforInstruction(address13, genoperand(PrefetchAw, address13)); + checkLiteralforInstruction(address8, genoperand(PrefetchAw, address8)); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -26775,103 +26959,86 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin gen:literal:operand: */ checkLiteralforInstruction(retpc, genoperandoperand(MoveCwR, retpc, LR)); /* begin gen:literal: */ - primInvokeInstruction = checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + checkLiteralforInstruction(((sqInt)(((sqInt)primitiveRoutine))), genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine))))); + return 0; } - else { - - /* Call the C primitive routine. */ - genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); - /* begin gen:literal: */ - primInvokeInstruction = checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 6); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin MoveAw:R: */ - address7 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction3)) { - (anInstruction3->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address8 = instructionPointerAddress(); - reg = LinkReg; - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); - genLoadStackPointers(backEnd); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address2 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, LinkReg)); + /* begin MoveAw:R: */ + address9 = primFailCodeAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + reg = Arg0Reg; /* begin MoveAw:R: */ - address9 = primFailCodeAddress(); + address10 = nextProfileTickAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address9, genoperandoperand(MoveAwR, address9, TempReg)); - flag("ask concrete code gen if move sets condition codes?"); + checkLiteralforInstruction(address10, genoperandoperand(MoveAwR, address10, Arg1Reg)); /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = 0; - /* begin checkQuickConstant:forInstruction: */ - anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction5)) { - (anInstruction5->dependent = locateLiteralsize(offset1, BytesPerOop)); + anInstruction8 = genoperandoperand(CmpCqR, 0, Arg1Reg); + if (usesOutOfLineLiteral(anInstruction8)) { + (anInstruction8->dependent = locateLiteralsize(0, BytesPerOop)); } - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jumpToTakeSample = jump; + goto l35; + l35: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = 0; + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(offset1, BytesPerOop)); + } + continueAfterProfileSample = anInstruction6; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction6)) { - (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin MoveR:Aw: */ - address10 = newMethodAddress(); - /* begin gen:operand:literal: */ - checkLiteralforInstruction(address10, genoperandoperand(MoveRAw, TempReg, address10)); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - checkLiteralforInstruction(operand3, genoperand(CallFull, operand3)); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + genLoadStackPointerForPrimCall(backEnd, ClassReg); + /* begin MoveAw:R: */ + address4 = instructionPointerAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, LinkReg)); /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); - if (usesOutOfLineLiteral(anInstruction7)) { - (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); - } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteralsize(offset2, BytesPerOop)); } return 0; } @@ -26901,7 +27068,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -26958,12 +27125,11 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) depth, assign framePointer and newMethod, do the stack switch, call checkForAndFollowForwardedPrimitiveState, and loop back if forwarders are found. - Fall throguh tio frame build. */ -/* Clear the primFailCode and set argumentCount */ + Fall through to frame build. */ - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive: */ + /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive:flags: */ static sqInt NoDbgRegParms -compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) +compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { sqInt address; sqInt address1; @@ -26971,76 +27137,150 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) sqInt address3; sqInt address4; sqInt address5; + sqInt address6; + sqInt address7; + sqInt address8; AbstractInstruction *anInstruction; AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - sqInt calleeSavedReg; + AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + AbstractInstruction *anInstruction7; + AbstractInstruction *anInstruction8; + AbstractInstruction *anInstruction9; + sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jump; + AbstractInstruction * jumpToTakeSample; + sqInt linkRegSaveRegister; + sqInt liveRegisterMask; sqInt offset; + sqInt offset1; sqInt operand1; + sqInt reg; AbstractInstruction * retry; - + AbstractInstruction * skip; + AbstractInstruction * skip1; + sqInt spRegSaveRegister; + + jumpToTakeSample = ((AbstractInstruction *) 0); + linkRegSaveRegister = 0; + assert(((flags & PrimCallOnSmalltalkStack) != 0)); + assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); + if (recordFastCCallPrimTraceForMethod(methodObj)) { + genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); + } /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(MoveCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction3)) { - (anInstruction3->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction9 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction9)) { + (anInstruction9->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveR:Aw: */ - address2 = primFailCodeAddress(); + address4 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveRAw, TempReg, address2)); + checkLiteralforInstruction(address4, genoperandoperand(MoveRAw, TempReg, address4)); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteralsize(methodOrBlockNumArgs, BytesPerOop)); } } /* begin MoveR:Aw: */ - address3 = argumentCountAddress(); + address5 = argumentCountAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + checkLiteralforInstruction(address5, genoperandoperand(MoveRAw, TempReg, address5)); genExternalizeStackPointerForFastPrimitiveCall(); - /* begin PushR: */ - genoperand(PushR, LinkReg); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); + linkRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); + assert(!((linkRegSaveRegister == NoReg))); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, LinkReg, linkRegSaveRegister); + calleeSavedRegisterMask = ((calleeSavedRegisterMask | (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))) - (((linkRegSaveRegister < 0) ? (((usqInt)(1)) >> (-linkRegSaveRegister)) : (1ULL << linkRegSaveRegister)))); + spRegSaveRegister = NoReg; + if (!(((ABICalleeSavedRegisterMask & ((1U << SPReg))) != 0))) { + spRegSaveRegister = availableRegisterOrNoneIn(calleeSavedRegisterMask); + assert(!((spRegSaveRegister == NoReg))); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SPReg, spRegSaveRegister); + } /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - calleeSavedReg = NoReg; - if (!(((ABICalleeSavedRegisterMask & (1U << SPReg)) != 0))) { - calleeSavedReg = availableRegisterOrNoneIn(ABICalleeSavedRegisterMask); - assert(!((calleeSavedReg == NoReg))); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SPReg, calleeSavedReg); + if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { + gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, NativeSPReg); + } + else { + genLoadNativeSPRegWithAlignedSPReg(backEnd); } + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(primitiveRoutine, genoperand(CallFull, primitiveRoutine)); + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperand(CallFull, ((sqInt)primitiveRoutine))); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 6); /* begin MoveAw:R: */ - address4 = primFailCodeAddress(); + address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address4, genoperandoperand(MoveAwR, address4, TempReg)); - if (calleeSavedReg != NoReg) { + checkLiteralforInstruction(address6, genoperandoperand(MoveAwR, address6, TempReg)); + if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ - genoperandoperand(MoveRR, calleeSavedReg, SPReg); + genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction4)) { - (anInstruction4->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction10 = genoperandoperand(CmpCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction10)) { + (anInstruction10->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin PopR: */ - genoperand(PopR, LinkReg); + genLoadCStackPointer(backEnd); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + reg = Arg0Reg; + /* begin MoveAw:R: */ + address8 = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, Arg1Reg)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction11 = genoperandoperand(CmpCqR, 0, Arg1Reg); + if (usesOutOfLineLiteral(anInstruction11)) { + (anInstruction11->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpZero: */ + skip1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jumpToTakeSample = jump; + goto l37; + l37: /* end genCheckForProfileTimerTick: */; + } /* begin MoveAw:R: */ - address5 = stackPointerAddress(); + address7 = stackPointerAddress(); /* begin gen:literal:operand: */ - checkLiteralforInstruction(address5, genoperandoperand(MoveAwR, address5, SPReg)); - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); + continueAfterProfileSample = checkLiteralforInstruction(address7, genoperandoperand(MoveAwR, address7, TempReg)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); + } + gAddCqRR(BytesPerWord, TempReg, SPReg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -27051,6 +27291,24 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) address = framePointerAddress(); /* begin gen:operand:literal: */ checkLiteralforInstruction(address, genoperandoperand(MoveRAw, FPReg, address)); + /* begin MoveCw:R: */ + checkLiteralforInstruction(((sqInt)primitiveRoutine), genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg)); + /* begin MoveR:Aw: */ + address1 = primitiveFunctionPointerAddress(); + /* begin gen:operand:literal: */ + checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + /* begin MoveMw:r:R: */ + offset = offsetof(CogMethod, methodObject); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + if (usesOutOfLineLiteral(anInstruction5)) { + (anInstruction5->dependent = locateLiteralsize(offset, BytesPerOop)); + } + /* begin MoveR:Aw: */ + address2 = newMethodAddress(); + /* begin gen:operand:literal: */ + checkLiteralforInstruction(address2, genoperandoperand(MoveRAw, TempReg, address2)); /* begin genLoadCStackPointersForPrimCall */ if (cFramePointerInUse) { genLoadCStackPointers(backEnd); @@ -27058,29 +27316,49 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) else { genLoadCStackPointer(backEnd); } - addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); + genMarshallNArgsargargargarg(backEnd, 0, 0, 0, 0, 0); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(offset, BytesPerOop)); + anInstruction6 = genoperandoperand(CmpCqR, 0, ABIResultReg); + if (usesOutOfLineLiteral(anInstruction6)) { + (anInstruction6->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperand(MoveCqR, 0, TempReg); + if (usesOutOfLineLiteral(anInstruction7)) { + (anInstruction7->dependent = locateLiteralsize(0, BytesPerOop)); } /* begin MoveR:Aw: */ - address1 = newMethodAddress(); + address3 = primFailCodeAddress(); /* begin gen:operand:literal: */ - checkLiteralforInstruction(address1, genoperandoperand(MoveRAw, TempReg, address1)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); - checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); - genLoadStackPointers(backEnd); + checkLiteralforInstruction(address3, genoperandoperand(MoveRAw, TempReg, address3)); + /* begin Jump: */ + genoperand(Jump, ((sqInt)retry)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + } + else { + + /* must reload SPReg to undo any alignment change, */ + if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { + genLoadStackPointersForPrimCall(backEnd, ClassReg); + } + } + genLoadCStackPointer(backEnd); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, linkRegSaveRegister, LinkReg); + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { + /* begin MoveMw:r:R: */ + offset1 = (methodOrBlockNumArgs + (0)) * BytesPerWord; /* begin checkQuickConstant:forInstruction: */ - anInstruction2 = genoperandoperand(CmpCqR, 0, ABIResultReg); - if (usesOutOfLineLiteral(anInstruction2)) { - (anInstruction2->dependent = locateLiteralsize(0, BytesPerOop)); + anInstruction8 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + if (usesOutOfLineLiteral(anInstruction8)) { + (anInstruction8->dependent = locateLiteralsize(offset1, BytesPerOop)); } - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)retry)); } return 0; } @@ -27353,18 +27631,18 @@ compilePrimitive(void) if (((flags & PrimCallDoNotJIT) != 0)) { return ShouldNotJIT; } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - - /* TEMPORARY HACK!! */ - return compileOnStackExternalPrimitive(primitiveRoutine); - } - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } if ((primitiveRoutine == 0) || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { return genFastPrimFail(); } + if (((flags & PrimCallOnSmalltalkStack) != 0)) { + assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) + && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); + if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { + return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); + } + return compileOnStackExternalPrimitiveflags(primitiveRoutine, flags); + } minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); return compileInterpreterPrimitiveflags(primitiveRoutine, flags); } @@ -28145,7 +28423,7 @@ genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) static void NoDbgRegParms genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { - sqInt address2; + sqInt address; sqInt address4; sqInt address6; sqInt address7; @@ -28155,13 +28433,16 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction7; - sqInt callTarget; AbstractInstruction *continuePostSample; - AbstractInstruction * inst; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + AbstractInstruction * jump; + sqInt liveRegisterMask; + sqInt operand1; sqInt quickConstant; sqInt reg; + sqInt reg1; + AbstractInstruction * skip; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -28173,24 +28454,6 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) if (usesOutOfLineLiteral(anInstruction)) { (anInstruction->dependent = locateLiteralsize(quickConstant, BytesPerOop)); } - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin MoveAw:R: */ - address2 = nextProfileTickAddress(); - /* begin gen:literal:operand: */ - checkLiteralforInstruction(address2, genoperandoperand(MoveAwR, address2, TempReg)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction1 = genoperandoperand(CmpCqR, 0, TempReg); - if (usesOutOfLineLiteral(anInstruction1)) { - (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); - } - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin MoveAw:R: */ address6 = primFailCodeAddress(); /* begin gen:literal:operand: */ @@ -28203,6 +28466,35 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) } /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + reg = Arg0Reg; + /* begin MoveAw:R: */ + address = nextProfileTickAddress(); + /* begin gen:literal:operand: */ + checkLiteralforInstruction(address, genoperandoperand(MoveAwR, address, Arg1Reg)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); + if (usesOutOfLineLiteral(anInstruction1)) { + (anInstruction1->dependent = locateLiteralsize(0, BytesPerOop)); + } + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jmpSample = jump; + goto l12; + l12: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ anInstruction2 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); @@ -28223,9 +28515,9 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address8 = instructionPointerAddress(); - reg = LinkReg; + reg1 = LinkReg; /* begin gen:literal:operand: */ - checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg)); + checkLiteralforInstruction(address8, genoperandoperand(MoveAwR, address8, reg1)); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, SPReg, ReceiverResultReg); @@ -28234,18 +28526,18 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) } /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { - /* Call ceCheckProfileTick: to record sample and then continue. newMethod + /* Call ceTakeProfileSample: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; + genMarshallNArgsargargargarg(backEnd, 1, 0, 0, 0, 0); /* begin gen:literal: */ - checkLiteralforInstruction(callTarget, genoperand(CallFull, callTarget)); - genoperand(PopR, LinkReg); + operand1 = ((usqInt)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 6); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -28632,6 +28924,23 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), ClassReg))); + genMarshallNArgsargargargarg(backEnd, 1, ClassReg, null, null, null); + genLoadNativeSPRegWithAlignedSPReg(backEnd); + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + checkLiteralforInstruction(operand1, genoperand(CallFull, operand1)); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 6); + genLoadCStackPointer(backEnd); +} + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -28949,7 +29258,7 @@ primitiveGeneratorOrNil(void) static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask) { - return ((mask & (1ULL << reg)) != 0); + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); } /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ @@ -29300,7 +29609,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -30177,7 +30486,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -30309,7 +30618,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -30317,7 +30626,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -30818,13 +31127,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31446,7 +31755,7 @@ genNSSendnumArgsdepthsendTable(sqInt selectorIndex, sqInt numArgs, sqInt depth, (nsSendCache1->depth = depth); (nsSendCache1->classTag = 0 /* illegalClassTag */); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); marshallAbsentReceiverSendArguments(numArgs); /* begin uniqueLiteral:forInstruction: */ anInstruction = genoperandoperand(MoveCwR, nsSendCache, SendNumArgsReg); @@ -31683,7 +31992,7 @@ genPushEnclosingObjectAt(sqInt level) voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, level, SendNumArgsReg); if (usesOutOfLineLiteral(anInstruction)) { @@ -31815,11 +32124,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -31878,7 +32187,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -31954,7 +32263,7 @@ genPushRemoteTempLongBytecode(void) (anInstruction->dependent = locateLiteralsize(offset, BytesPerOop)); } /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -32332,11 +32641,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -32575,7 +32884,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(gMoveCwR(association, ReceiverResultReg), association); @@ -32591,7 +32900,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32605,7 +32914,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -32669,7 +32978,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -32717,7 +33026,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -32731,7 +33040,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -32755,7 +33064,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -32768,7 +33077,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -32959,13 +33268,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -33228,12 +33537,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -33279,7 +33588,7 @@ marshallAbsentReceiverSendArguments(sqInt numArgs) assert(needsFrame); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); /* begin ssFlushTo: */ @@ -33341,13 +33650,13 @@ marshallAbsentReceiverSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -33432,13 +33741,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/nsspur64src/vm/cogitX64SysV.c b/nsspur64src/vm/cogitX64SysV.c index bec0290144..5b0621e7ee 100644 --- a/nsspur64src/vm/cogitX64SysV.c +++ b/nsspur64src/vm/cogitX64SysV.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -38,6 +38,7 @@ char *__cogitBuildInfo = __buildInfo; #define AddcRR 119 #define AddRdRd 132 #define AddRR 100 +#define AddRRR 126 #define AddRsRs 139 #define AlignmentNops 3 #define AltBlockCreationBytecodeSize 3 @@ -55,7 +56,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 7 #define CArg1Reg 6 @@ -65,11 +66,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x2C6 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -90,7 +91,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -105,7 +106,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -126,6 +127,7 @@ char *__cogitBuildInfo = __buildInfo; #define Extra3Reg 13 #define Extra4Reg 14 #define Extra5Reg 15 +#define FastCPrimitiveUseCABIFlag 4 #define Fill32 4 #define FirstAnnotation 64 #define FirstJump 12 @@ -143,11 +145,11 @@ char *__cogitBuildInfo = __buildInfo; #define GCModeNewSpace 2 #define HasBytecodePC 5 #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -198,11 +200,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -228,11 +230,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -251,10 +253,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -310,6 +314,7 @@ char *__cogitBuildInfo = __buildInfo; #define PrimCallNeedsNewMethod 1 #define PrimCallNeedsPrimitiveFunction 2 #define PrimCallOnSmalltalkStack 64 +#define PrimCallOnSmalltalkStackAlign2x 128 #define PrimErrNoMemory 9 #define PrimNumberExternalCall 117 #define PrimNumberFFICall 120 @@ -326,7 +331,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 2 #define RetN 9 @@ -335,12 +340,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 9 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -378,7 +383,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XorCwR 118 #define XorRdRd 137 @@ -510,7 +515,9 @@ static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLi static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); +static sqInt NoDbgRegParms genLoadStackPointerForPrimCall(AbstractInstruction * self_in_genLoadStackPointerForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -535,6 +542,7 @@ static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * s static void NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); +static AbstractInstruction * NoDbgRegParms gAddRRR(sqInt addendReg, sqInt badendReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); @@ -567,7 +575,7 @@ static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); extern void ceFree(void *pointer); static void* NoDbgRegParms ceMalloc(size_t size); static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod); +static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); @@ -690,6 +698,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisterMask); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisterMask); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1007,6 +1017,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1030,6 +1041,7 @@ static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genResto static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); +static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); static sqInt NoDbgRegParms is32BitSignedImmediate(AbstractInstruction * self_in_is32BitSignedImmediate, sqInt a64BitUnsignedOperand); static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); @@ -1076,7 +1088,7 @@ static sqInt compileBlockDispatch(void); static void compileGetErrorCode(void); static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)); +static sqInt NoDbgRegParms compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); @@ -1156,11 +1168,13 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); static PrimitiveDescriptor * primitiveGeneratorOrNil(void); +static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask); static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); @@ -1940,7 +1954,6 @@ static AbstractInstruction * picInterpretAbort; static sqInt picMissTrampolines[4]; static AbstractInstruction * picMNUAbort; static BytecodeDescriptor * prevBCDescriptor; -static AbstractInstruction * primInvokeInstruction; static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { { 0, -1 }, { genPrimitiveAdd, 1 }, @@ -2520,7 +2533,6 @@ static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] { genPrimitiveHighBit, 0 } }; static sqInt primitiveIndex; -static AbstractInstruction * primSetFunctionLabel; static sqInt processorLock; static sqInt receiverTags; static sqInt regArgsHaveBeenPushed; @@ -2647,6 +2659,7 @@ void (*realCEEnterCogCodePopReceiverReg)(void); #define print(aString) printf("%s", aString) #define recordBlockTrace() (traceFlags & 4) #define recordEventTrace() (traceFlags & 16) +#define recordFastCCallPrimTrace() (traceFlags & 512) #define recordOverflowTrace() (traceFlags & 32) #define recordPrimTrace() (traceFlags & 8) #define recordSendTrace() (traceFlags & 2) @@ -2711,28 +2724,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2821,6 +2834,29 @@ genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) } +/* Switch back to the Smalltalk stack where there may be a C return address + on top of stack below + the last primitive argument. Assign SPReg first because typically it is + used immediately afterwards. + */ + + /* CogAbstractInstruction>>#genLoadStackPointerForPrimCall: */ +static sqInt NoDbgRegParms +genLoadStackPointerForPrimCall(AbstractInstruction * self_in_genLoadStackPointerForPrimCall, sqInt spareReg) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + + /* begin checkLiteral:forInstruction: */ + stackPointerAddress(); + anInstruction1 = genoperandoperand(MoveAwR, stackPointerAddress(), spareReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction2 = genoperandoperand(SubCqR, BytesPerWord, spareReg); + genoperandoperand(MoveRR, spareReg, SPReg); + return 0; +} + + /* Switch back to the Smalltalk stack. Assign SPReg first because typically it is used immediately afterwards. */ @@ -2841,6 +2877,33 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) } +/* Switch back to the Smalltalk stack where there may be a C return address + on top of stack below + the last primitive argument. Assign SPReg first because typically it is + used immediately afterwards. + */ + + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ +static sqInt NoDbgRegParms +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) +{ + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + + /* begin checkLiteral:forInstruction: */ + stackPointerAddress(); + anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), spareReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperand(SubCqR, BytesPerWord, spareReg); + genoperandoperand(MoveRR, spareReg, SPReg); + /* begin checkLiteral:forInstruction: */ + framePointerAddress(); + anInstruction2 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); + return 0; +} + + /* Save the frame and stack pointer registers to the framePointer and stackPointer variables. Used to save the machine code frame for use by the run-time when calling into the CoInterpreter run-time. */ @@ -3282,6 +3345,21 @@ gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) return first; } + +/* destReg := addendReg + badendReg */ + + /* Cogit>>#AddR:R:R: */ +static AbstractInstruction * NoDbgRegParms +gAddRRR(sqInt addendReg, sqInt badendReg, sqInt destReg) +{ + AbstractInstruction * first; + + assert(badendReg != destReg); + first = genoperandoperand(MoveRR, addendReg, destReg); + genoperandoperand(AddRR, badendReg, destReg); + return first; +} + /* Cogit>>#AndCq:R: */ static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg) @@ -4154,7 +4232,7 @@ ceSICMiss(sqInt receiver) /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod) +checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) { usqInt cacheAddress; usqInt cacheTag1; @@ -5729,7 +5807,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7298,7 +7376,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7331,7 +7409,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -8426,8 +8504,8 @@ initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) null # endif ); - stopsFromto(backEnd, startAddress, endAddress - 1); codeBase = (methodZoneBase = startAddress); + stopsFromto(backEnd, startAddress, endAddress - 1); minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); /* begin manageFrom:to: */ mzFreeStart = (baseAddress = methodZoneBase); @@ -8820,6 +8898,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisterMask) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisterMask); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisterMask) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisterMask); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -10460,11 +10554,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -12158,6 +12255,10 @@ voidCogCompiledCode(void) unpairedMethodList = null; methodBytesFreedSinceLastCompaction = 0; methodCount = 0; + /* begin ensureExecutableCodeZone */ +# if !DUAL_MAPPED_CODE_ZONE + +# endif } @@ -17993,7 +18094,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -19250,7 +19351,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -19266,7 +19367,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -19824,7 +19925,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19837,7 +19938,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19912,37 +20013,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -20521,6 +20622,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -20612,6 +20718,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisterMask; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisterMask = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisterMask & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisterMask & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RAX, 0, reg)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, reg, RAX)); + offset += 3; + } + if (((liveRegisterMask & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisterMask & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -24014,6 +24179,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -24642,8 +24810,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -24665,7 +24833,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -24687,7 +24855,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -24714,6 +24882,17 @@ genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqI } +/* Answer if the processor has a dedicated callee-saved register to point to + the base of commonly-accessed variables. */ + + /* CogX64Compiler>>#hasVarBaseRegister */ +static sqInt NoDbgRegParms +hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) +{ + return 1; +} + + /* Answer the instruction size at pc. This is used in method disassembly to decode the jumps in block dispatch to discover where block methods occur within a larger method. This is very far from a full decode. */ @@ -25490,61 +25669,51 @@ compileGetErrorCode(void) /* Compile a call to an interpreter primitive. Call the C routine with the usual stack-switching dance, test the primFailCode and then either return on success or continue to the method body. */ -/* Save processor fp, sp and return pc in the interpreter's frame stack and - instruction pointers - */ /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction12; + AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction111; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; - AbstractInstruction *anInstruction24; - AbstractInstruction *anInstruction25; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jump; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisterMask; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; + AbstractInstruction * skip; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); + assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ if (cFramePointerInUse) { @@ -25553,42 +25722,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - primSetFunctionLabel = anInstruction6; + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -25600,26 +25755,25 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l32; + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -25657,111 +25811,95 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - primInvokeInstruction = anInstruction10; - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - primInvokeInstruction = anInstruction15; - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + anInstruction111 = genoperandoperand(CmpCqR, 0, Arg1Reg); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jumpToTakeSample = jump; + goto l62; + l62: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + genLoadStackPointerForPrimCall(backEnd, ClassReg); /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -25791,7 +25929,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -25866,72 +26004,152 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) depth, assign framePointer and newMethod, do the stack switch, call checkForAndFollowForwardedPrimitiveState, and loop back if forwarders are found. - Fall throguh tio frame build. */ -/* Clear the primFailCode and set argumentCount */ + Fall through to frame build. */ - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive: */ + /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive:flags: */ static sqInt NoDbgRegParms -compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) +compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction111; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; + AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction20; + AbstractInstruction *anInstruction22; + AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; - sqInt calleeSavedReg; + sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jump; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisterMask; sqInt offset; + sqInt offset1; sqInt operand1; + sqInt reg; + sqInt retpcOffset; AbstractInstruction * retry; - + AbstractInstruction * skip; + AbstractInstruction * skip1; + sqInt spRegSaveRegister; + + jumpToTakeSample = ((AbstractInstruction *) 0); + assert(((flags & PrimCallOnSmalltalkStack) != 0)); + assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); + if (recordFastCCallPrimTraceForMethod(methodObj)) { + genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); + } /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction10 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); + spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - calleeSavedReg = NoReg; + if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { + gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, NativeSPReg); + } + else { + } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - if (calleeSavedReg != NoReg) { + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ - genoperandoperand(MoveRR, calleeSavedReg, SPReg); + genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin PopR: */ - genoperand(PopR, TempReg); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction111 = genoperandoperand(CmpCqR, 0, Arg1Reg); + /* begin JumpZero: */ + skip1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jumpToTakeSample = jump; + goto l71; + l71: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction14 = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin PushR: */ - genoperand(PushR, TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; + + /* The original retpc is (argumentCount + 1) words below stackPointer. */ + retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); + /* begin checkQuickConstant:forInstruction: */ + anInstruction4 = genoperandoperandoperand(MoveMwrR, retpcOffset, TempReg, ClassReg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, TempReg, SPReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -25940,7 +26158,21 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) This won't be a performance issue since primitive failure should be very rare. */ /* begin checkLiteral:forInstruction: */ framePointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); + anInstruction9 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); + /* begin checkLiteral:forInstruction: */ + ((sqInt)primitiveRoutine); + anInstruction10 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + /* begin checkLiteral:forInstruction: */ + primitiveFunctionPointerAddress(); + anInstruction11 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin MoveMw:r:R: */ + offset = offsetof(CogMethod, methodObject); + /* begin checkQuickConstant:forInstruction: */ + anInstruction12 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + /* begin checkLiteral:forInstruction: */ + newMethodAddress(); + anInstruction13 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); /* begin genLoadCStackPointersForPrimCall */ if (cFramePointerInUse) { genLoadCStackPointers(backEnd); @@ -25948,23 +26180,48 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) else { genLoadCStackPointer(backEnd); } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); - /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction7 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ - anInstruction4 = genoperand(CallFull, operand1); - genLoadStackPointers(backEnd); + anInstruction8 = genoperand(CallFull, operand1); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)retry)); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + /* begin Jump: */ + genoperand(Jump, ((sqInt)retry)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + } + else { + + /* must reload SPReg to undo any alignment change, */ + if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { + genLoadStackPointersForPrimCall(backEnd, ClassReg); + } + } + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { + /* begin MoveMw:r:R: */ + offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -26211,18 +26468,18 @@ compilePrimitive(void) if (((flags & PrimCallDoNotJIT) != 0)) { return ShouldNotJIT; } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - - /* TEMPORARY HACK!! */ - return compileOnStackExternalPrimitive(primitiveRoutine); - } - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } if ((primitiveRoutine == 0) || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { return genFastPrimFail(); } + if (((flags & PrimCallOnSmalltalkStack) != 0)) { + assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) + && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); + if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { + return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); + } + return compileOnStackExternalPrimitiveflags(primitiveRoutine, flags); + } minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); return compileInterpreterPrimitiveflags(primitiveRoutine, flags); } @@ -26997,23 +27254,27 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; - AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction19; + AbstractInstruction *anInstruction20; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; - sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + AbstractInstruction * jump; + sqInt liveRegisterMask; + sqInt operand1; sqInt quickConstant; sqInt reg; + sqInt reg1; + AbstractInstruction * skip; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -27022,28 +27283,40 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction18 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction4 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jmpSample = jump; + goto l22; + l22: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); @@ -27057,13 +27330,13 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction20 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction22 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); @@ -27071,16 +27344,30 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { - /* Call ceCheckProfileTick: to record sample and then continue. newMethod + /* Call ceTakeProfileSample: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + goto l42; + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l42: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqInt)ceTakeProfileSample); /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction14 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -27455,6 +27742,61 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -27768,6 +28110,13 @@ primitiveGeneratorOrNil(void) return null; } + /* SimpleStackBasedCogit>>#register:isInMask: */ +static sqInt NoDbgRegParms +registerisInMask(sqInt reg, sqInt mask) +{ + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); +} + /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) @@ -28106,7 +28455,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -28948,7 +29297,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -29080,7 +29429,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -29088,7 +29437,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -29590,13 +29939,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30169,7 +30518,7 @@ genNSSendnumArgsdepthsendTable(sqInt selectorIndex, sqInt numArgs, sqInt depth, (nsSendCache1->depth = depth); (nsSendCache1->classTag = 0 /* illegalClassTag */); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); marshallAbsentReceiverSendArguments(numArgs); /* begin uniqueLiteral:forInstruction: */ anInstruction = genoperandoperand(MoveCwR, nsSendCache, SendNumArgsReg); @@ -30384,7 +30733,7 @@ genPushEnclosingObjectAt(sqInt level) voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, level, SendNumArgsReg); /* begin CallRT: */ @@ -30510,11 +30859,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -30567,7 +30916,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -30640,7 +30989,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -30990,11 +31339,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -31227,7 +31576,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -31240,7 +31589,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31254,7 +31603,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31315,7 +31664,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -31360,7 +31709,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31374,7 +31723,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -31398,7 +31747,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -31408,7 +31757,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31594,13 +31943,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31854,12 +32203,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -31905,7 +32254,7 @@ marshallAbsentReceiverSendArguments(sqInt numArgs) assert(needsFrame); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); /* begin ssFlushTo: */ @@ -31955,13 +32304,13 @@ marshallAbsentReceiverSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -32046,13 +32395,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/nsspur64src/vm/cogitX64WIN64.c b/nsspur64src/vm/cogitX64WIN64.c index 66cdf88128..21b6aa3d7a 100644 --- a/nsspur64src/vm/cogitX64WIN64.c +++ b/nsspur64src/vm/cogitX64WIN64.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -38,6 +38,7 @@ char *__cogitBuildInfo = __buildInfo; #define AddcRR 119 #define AddRdRd 132 #define AddRR 100 +#define AddRRR 126 #define AddRsRs 139 #define AlignmentNops 3 #define AltBlockCreationBytecodeSize 3 @@ -55,7 +56,7 @@ char *__cogitBuildInfo = __buildInfo; #define ArithmeticShiftRightRR 92 #define BadRegisterSet 1 #define BlockCreationBytecodeSize 4 -#define BSR 167 +#define BSR 169 #define BytecodeSetHasDirectedSuperSend 1 #define CArg0Reg 1 #define CArg1Reg 2 @@ -65,11 +66,11 @@ char *__cogitBuildInfo = __buildInfo; #define CallerSavedRegisterMask 0x706 #define CallFull 7 #define CallR 8 -#define CDQ 159 +#define CDQ 161 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ # define CheckRememberedInTrampoline 0 #endif -#define CLD 163 +#define CLD 165 #define ClassArray 7 #define ClassArrayCompactIndex 51 #define ClassBlockClosureCompactIndex 37 @@ -90,7 +91,7 @@ char *__cogitBuildInfo = __buildInfo; #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPXCHGRMr 172 +#define CMPXCHGRMr 174 #define CmpC32R 113 #define CmpCqR 105 #define CmpCwR 112 @@ -105,7 +106,7 @@ char *__cogitBuildInfo = __buildInfo; #define ConvertRRs 150 #define ConvertRsR 149 #define ConvertRsRd 147 -#define CPUID 158 +#define CPUID 160 #define Debug DEBUGVM #define DisplacementMask 0x1F #define DisplacementX2N 0 @@ -126,6 +127,7 @@ char *__cogitBuildInfo = __buildInfo; #define Extra3Reg 13 #define Extra4Reg 14 #define Extra5Reg 15 +#define FastCPrimitiveUseCABIFlag 4 #define Fill32 4 #define FirstAnnotation 64 #define FirstJump 12 @@ -143,11 +145,11 @@ char *__cogitBuildInfo = __buildInfo; #define GCModeNewSpace 2 #define HasBytecodePC 5 #define HeaderIndex 0 -#define IDIVR 160 +#define IDIVR 162 #if !defined(IMMUTABILITY) /* Allow this to be overridden on the compiler command line */ # define IMMUTABILITY 1 #endif -#define IMULRR 161 +#define IMULRR 163 #define InFullBlock 2 #define InstanceSpecificationIndex 2 #define InstructionPointerIndex 1 @@ -198,11 +200,11 @@ char *__cogitBuildInfo = __buildInfo; #define Label 1 #define LargeContextSlots 62 #define LastJump 42 -#define LFENCE 168 +#define LFENCE 170 #undef LinkReg #define Literal 2 #define LiteralStart 1 -#define LOCK 171 +#define LOCK 173 #define LoadEffectiveAddressMwrR 88 #define LogicalShiftLeftCqR 95 #define LogicalShiftLeftCqRR 129 @@ -228,11 +230,11 @@ char *__cogitBuildInfo = __buildInfo; #define MethodCacheSelector 1 #define MethodIndex 3 #define MethodTooBig -4 -#define MFENCE 169 +#define MFENCE 171 #define MFMethodFlagHasContextFlag 1 #define MFMethodFlagIsBlockFlag 2 -#define MOVSB 165 -#define MOVSQ 166 +#define MOVSB 167 +#define MOVSQ 168 #define ModReg 3 #define ModRegInd 0 #define ModRegRegDisp32 2 @@ -251,10 +253,12 @@ char *__cogitBuildInfo = __buildInfo; #define MoveMbrR 65 #define MoveMs8rR 55 #define MoveMwrR 50 +#define MovePerfCnt64RL 159 +#define MovePerfCnt64RRL 158 #define MoveRA32 47 #define MoveRAb 49 #define MoveRAw 46 -#define MoveRAwNoVBR 174 +#define MoveRAwNoVBR 176 #define MoveRdM64r 76 #define MoveRdR 73 #define MoveRdRd 74 @@ -310,6 +314,7 @@ char *__cogitBuildInfo = __buildInfo; #define PrimCallNeedsNewMethod 1 #define PrimCallNeedsPrimitiveFunction 2 #define PrimCallOnSmalltalkStack 64 +#define PrimCallOnSmalltalkStackAlign2x 128 #define PrimErrNoMemory 9 #define PrimNumberExternalCall 117 #define PrimNumberFFICall 120 @@ -326,7 +331,7 @@ char *__cogitBuildInfo = __buildInfo; #define RCX 1 #define RDI 7 #define RDX 2 -#define REP 164 +#define REP 166 #define ReceiverIndex 5 #define ReceiverResultReg 9 #define RetN 9 @@ -335,12 +340,12 @@ char *__cogitBuildInfo = __buildInfo; #define RotateRightCqR 98 #define RSI 6 #define RSP 4 -#define SETE 173 +#define SETE 175 #define SelectorCannotInterpret 34 #define SelectorDoesNotUnderstand 20 #define SenderIndex 0 #define SendNumArgsReg 10 -#define SFENCE 170 +#define SFENCE 172 #define ShouldNotJIT -8 #define SIB1 0 #define SIB4 2 @@ -378,7 +383,7 @@ char *__cogitBuildInfo = __buildInfo; #define UnimplementedPrimitive -7 #define ValueIndex 1 #define VarBaseReg 3 -#define XCHGRR 162 +#define XCHGRR 164 #define XMM0L 0 #define XorCwR 118 #define XorRdRd 137 @@ -510,7 +515,9 @@ static void NoDbgRegParms cloneLiteralFrom(AbstractInstruction * self_in_cloneLi static sqInt NoDbgRegParms concretizeAt(AbstractInstruction * self_in_concretizeAt, sqInt actualAddress); static sqInt NoDbgRegParms genLoadCStackPointer(AbstractInstruction * self_in_genLoadCStackPointer); static sqInt NoDbgRegParms genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers); +static sqInt NoDbgRegParms genLoadStackPointerForPrimCall(AbstractInstruction * self_in_genLoadStackPointerForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers); +static sqInt NoDbgRegParms genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static void NoDbgRegParms genWriteCResultIntoReg(AbstractInstruction * self_in_genWriteCResultIntoReg, sqInt abstractRegister); static void NoDbgRegParms initializeSharableLiteral(AbstractInstruction * self_in_initializeSharableLiteral, sqInt literal); @@ -535,6 +542,7 @@ static usqInt NoDbgRegParms sizePCDependentInstructionAt(AbstractInstruction * s static void NoDbgRegParms storeLiteralbeforeFollowingAddress(AbstractInstruction * self_in_storeLiteralbeforeFollowingAddress, sqInt literal, sqInt followingAddress); static AbstractInstruction * NoDbgRegParms gAddCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); +static AbstractInstruction * NoDbgRegParms gAddRRR(sqInt addendReg, sqInt badendReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gAndCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gArithmeticShiftRightCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg); @@ -567,7 +575,7 @@ static sqInt NoDbgRegParms ceCPICMissreceiver(CogMethod *cPIC, sqInt receiver); extern void ceFree(void *pointer); static void* NoDbgRegParms ceMalloc(size_t size); static sqInt NoDbgRegParms ceSICMiss(sqInt receiver); -static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod); +static sqInt NoDbgRegParms checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); static sqInt NoDbgRegParms checkIfValidOopRefpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod); extern sqInt checkIntegrityOfObjectReferencesInCode(sqInt gcModes); static sqInt NoDbgRegParms checkMaybeObjRefInClosedPIC(sqInt maybeObject); @@ -690,6 +698,8 @@ extern void linkSendAtintooffsetreceiver(sqInt callSiteReturnAddress, CogMethod static BytecodeDescriptor * loadBytesAndGetDescriptor(void); static void NoDbgRegParms loadSubsequentBytesForDescriptorat(BytecodeDescriptor *descriptor, sqInt pc); static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisterMask); +static AbstractInstruction * NoDbgRegParms gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisterMask); static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, CogMethod *arg), CogMethod *arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); @@ -1007,6 +1017,7 @@ static sqInt NoDbgRegParms computeShiftRRSize(AbstractInstruction * self_in_comp static sqInt NoDbgRegParms computeSizeOfPushCw(AbstractInstruction * self_in_computeSizeOfPushCw); static sqInt NoDbgRegParms concretizeArithCqRWithROraxOpcode(AbstractInstruction * self_in_concretizeArithCqRWithROraxOpcode, sqInt regOpcode, sqInt raxOpcode); static sqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); +static sqInt NoDbgRegParms concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL); static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR); static sqInt NoDbgRegParms concretizeMoveX32rRR(AbstractInstruction * self_in_concretizeMoveX32rRR); static sqInt NoDbgRegParms concretizeOpRR(AbstractInstruction * self_in_concretizeOpRR, sqInt x64opcode); @@ -1030,6 +1041,7 @@ static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genResto static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); static AbstractInstruction * NoDbgRegParms genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqInt regB, sqInt regTmp); +static sqInt NoDbgRegParms hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister); static sqInt NoDbgRegParms instructionSizeAt(AbstractInstruction * self_in_instructionSizeAt, sqInt pc); static sqInt NoDbgRegParms is32BitSignedImmediate(AbstractInstruction * self_in_is32BitSignedImmediate, sqInt a64BitUnsignedOperand); static sqInt NoDbgRegParms isCallPrecedingReturnPC(AbstractInstruction * self_in_isCallPrecedingReturnPC, sqInt mcpc); @@ -1076,7 +1088,7 @@ static sqInt compileBlockDispatch(void); static void compileGetErrorCode(void); static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); static sqInt NoDbgRegParms compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)); -static sqInt NoDbgRegParms compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)); +static sqInt NoDbgRegParms compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags); static AbstractInstruction * NoDbgRegParms compileOpenPICMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selector, sqInt shift, sqInt baseRegOrNone); static void NoDbgRegParms compileOpenPICnumArgs(sqInt selector, sqInt numArgs); static AbstractInstruction * NoDbgRegParms compilePerformMethodCacheProbeForwithShiftbaseRegOrNone(sqInt selectorReg, sqInt shift, sqInt baseRegOrNone); @@ -1156,11 +1168,13 @@ static sqInt genStoreAndPopReceiverVariableBytecode(void); static sqInt genStoreAndPopRemoteTempLongBytecode(void); static sqInt genStoreAndPopTemporaryVariableBytecode(void); static sqInt genStoreRemoteTempLongBytecode(void); +static void genTakeProfileSample(void); extern sqInt mapPCDataForinto(CogMethod *cogMethod, sqInt arrayObj); static sqInt numSpecialSelectors(void); static usqInt NoDbgRegParms pcDataForBlockEntryMethod(sqInt blockEntryMcpc, sqInt cogMethod); static sqInt NoDbgRegParms pcDataForAnnotationMcpcBcpcMethod(BytecodeDescriptor *descriptor, sqInt isBackwardBranchAndAnnotation, char *mcpc, sqInt bcpc, void *cogMethodArg); static PrimitiveDescriptor * primitiveGeneratorOrNil(void); +static sqInt NoDbgRegParms registerisInMask(sqInt reg, sqInt mask); static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); static sqInt NoDbgRegParms v3LongForwardBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); static sqInt NoDbgRegParms v3LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj); @@ -1940,7 +1954,6 @@ static AbstractInstruction * picInterpretAbort; static sqInt picMissTrampolines[4]; static AbstractInstruction * picMNUAbort; static BytecodeDescriptor * prevBCDescriptor; -static AbstractInstruction * primInvokeInstruction; static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] = { { 0, -1 }, { genPrimitiveAdd, 1 }, @@ -2520,7 +2533,6 @@ static PrimitiveDescriptor primitiveGeneratorTable[MaxCompiledPrimitiveIndex+1] { genPrimitiveHighBit, 0 } }; static sqInt primitiveIndex; -static AbstractInstruction * primSetFunctionLabel; static sqInt processorLock; static sqInt receiverTags; static sqInt regArgsHaveBeenPushed; @@ -2647,6 +2659,7 @@ void (*realCEEnterCogCodePopReceiverReg)(void); #define print(aString) printf("%s", aString) #define recordBlockTrace() (traceFlags & 4) #define recordEventTrace() (traceFlags & 16) +#define recordFastCCallPrimTrace() (traceFlags & 512) #define recordOverflowTrace() (traceFlags & 32) #define recordPrimTrace() (traceFlags & 8) #define recordSendTrace() (traceFlags & 2) @@ -2711,28 +2724,28 @@ addDependent(AbstractInstruction * self_in_addDependent, AbstractInstruction *an static sqInt NoDbgRegParms availableFloatRegisterOrNoneFor(AbstractInstruction * self_in_availableFloatRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << DPFPReg0)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg0))) != 0))) { return DPFPReg0; } - if (!(((liveRegsMask & (1U << DPFPReg1)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg1))) != 0))) { return DPFPReg1; } - if (!(((liveRegsMask & (1U << DPFPReg2)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg2))) != 0))) { return DPFPReg2; } - if (!(((liveRegsMask & (1U << DPFPReg3)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg3))) != 0))) { return DPFPReg3; } - if (!(((liveRegsMask & (1U << DPFPReg4)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg4))) != 0))) { return DPFPReg4; } - if (!(((liveRegsMask & (1U << DPFPReg5)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg5))) != 0))) { return DPFPReg5; } - if (!(((liveRegsMask & (1U << DPFPReg6)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg6))) != 0))) { return DPFPReg6; } - if (!(((liveRegsMask & (1U << DPFPReg7)) != 0))) { + if (!(((liveRegsMask & ((1U << DPFPReg7))) != 0))) { return DPFPReg7; } return NoReg; @@ -2821,6 +2834,29 @@ genLoadCStackPointers(AbstractInstruction * self_in_genLoadCStackPointers) } +/* Switch back to the Smalltalk stack where there may be a C return address + on top of stack below + the last primitive argument. Assign SPReg first because typically it is + used immediately afterwards. + */ + + /* CogAbstractInstruction>>#genLoadStackPointerForPrimCall: */ +static sqInt NoDbgRegParms +genLoadStackPointerForPrimCall(AbstractInstruction * self_in_genLoadStackPointerForPrimCall, sqInt spareReg) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + + /* begin checkLiteral:forInstruction: */ + stackPointerAddress(); + anInstruction1 = genoperandoperand(MoveAwR, stackPointerAddress(), spareReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction2 = genoperandoperand(SubCqR, BytesPerWord, spareReg); + genoperandoperand(MoveRR, spareReg, SPReg); + return 0; +} + + /* Switch back to the Smalltalk stack. Assign SPReg first because typically it is used immediately afterwards. */ @@ -2841,6 +2877,33 @@ genLoadStackPointers(AbstractInstruction * self_in_genLoadStackPointers) } +/* Switch back to the Smalltalk stack where there may be a C return address + on top of stack below + the last primitive argument. Assign SPReg first because typically it is + used immediately afterwards. + */ + + /* CogAbstractInstruction>>#genLoadStackPointersForPrimCall: */ +static sqInt NoDbgRegParms +genLoadStackPointersForPrimCall(AbstractInstruction * self_in_genLoadStackPointersForPrimCall, sqInt spareReg) +{ + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + + /* begin checkLiteral:forInstruction: */ + stackPointerAddress(); + anInstruction = genoperandoperand(MoveAwR, stackPointerAddress(), spareReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperand(SubCqR, BytesPerWord, spareReg); + genoperandoperand(MoveRR, spareReg, SPReg); + /* begin checkLiteral:forInstruction: */ + framePointerAddress(); + anInstruction2 = genoperandoperand(MoveAwR, framePointerAddress(), FPReg); + return 0; +} + + /* Save the frame and stack pointer registers to the framePointer and stackPointer variables. Used to save the machine code frame for use by the run-time when calling into the CoInterpreter run-time. */ @@ -3282,6 +3345,21 @@ gAddCqRR(sqInt quickConstant, sqInt srcReg, sqInt destReg) return first; } + +/* destReg := addendReg + badendReg */ + + /* Cogit>>#AddR:R:R: */ +static AbstractInstruction * NoDbgRegParms +gAddRRR(sqInt addendReg, sqInt badendReg, sqInt destReg) +{ + AbstractInstruction * first; + + assert(badendReg != destReg); + first = genoperandoperand(MoveRR, addendReg, destReg); + genoperandoperand(AddRR, badendReg, destReg); + return first; +} + /* Cogit>>#AndCq:R: */ static AbstractInstruction * NoDbgRegParms gAndCqR(sqInt quickConstant, sqInt reg) @@ -4154,7 +4232,7 @@ ceSICMiss(sqInt receiver) /* Cogit>>#checkIfValidOopRefAndTarget:pc:cogMethod: */ static sqInt NoDbgRegParms -checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, sqInt cogMethod) +checkIfValidOopRefAndTargetpccogMethod(sqInt annotation, char *mcpc, CogMethod *cogMethod) { usqInt cacheAddress; usqInt cacheTag1; @@ -5731,7 +5809,7 @@ compileCallFornumArgsargargargargresultRegregsToSave(void *aRoutine, sqInt numAr regsToSave = (resultRegOrNone == NoReg ? regMask - : ((regMask | (1ULL << resultRegOrNone)) - (1ULL << resultRegOrNone))); + : ((regMask | (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone)))) - (((resultRegOrNone < 0) ? (((usqInt)(1)) >> (-resultRegOrNone)) : (1ULL << resultRegOrNone))))); if (cStackAlignment > BytesPerWord) { /* begin genAlignCStackSavingRegisters:numArgs:wordAlignment: */ regMaskCopy = ((usqInt)regsToSave); @@ -7306,7 +7384,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) startAddress = methodZoneBase; callerSavedReg = 0; pushedVarBaseReg = 0; - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { /* VarBaseReg is not caller-saved; must save and restore it, either by using an available caller-saved reg or push/pop. */ @@ -7339,7 +7417,7 @@ generateCaptureCStackPointers(sqInt captureFramePointer) /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); anInstruction3 = genoperandoperand(MoveRAw, TempReg, cStackPointerAddress()); - if (!(((CallerSavedRegisterMask & (1U << VarBaseReg)) != 0))) { + if (!(((CallerSavedRegisterMask & ((1U << VarBaseReg))) != 0))) { if (pushedVarBaseReg) { gNativePopR(VarBaseReg); } @@ -8444,8 +8522,8 @@ initializeCodeZoneFromupTo(sqInt startAddress, sqInt endAddress) null # endif ); - stopsFromto(backEnd, startAddress, endAddress - 1); codeBase = (methodZoneBase = startAddress); + stopsFromto(backEnd, startAddress, endAddress - 1); minValidCallAddress = (((((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) < (primitiveFailAddress())) ? (((codeBase < (interpretAddress())) ? codeBase : (interpretAddress()))) : (primitiveFailAddress())); /* begin manageFrom:to: */ mzFreeStart = (baseAddress = methodZoneBase); @@ -8838,6 +8916,22 @@ gMoveCwR(sqInt wordConstant, sqInt reg) return anInstruction; } + /* Cogit>>#MovePerfCnt64R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RL(sqInt destReg, sqInt liveRegisterMask) +{ + assert(BytesPerWord == 8); + return genoperandoperand(MovePerfCnt64RL, destReg, liveRegisterMask); +} + + /* Cogit>>#MovePerfCnt64R:R:L: */ +static AbstractInstruction * NoDbgRegParms +gMovePerfCnt64RRL(sqInt destRegLo, sqInt destRegHi, sqInt liveRegisterMask) +{ + assert(BytesPerWord == 4); + return genoperandoperandoperand(MovePerfCnt64RRL, destRegLo, destRegHi, liveRegisterMask); +} + /* Answer the address of the null byte at the end of the method map. */ @@ -10478,11 +10572,14 @@ recordRunTimeObjectReferences(void) } } + +/* N.B. (self registerMaskFor: NoReg) = 0 */ + /* Cogit>>#registerMaskFor: */ static sqInt NoDbgRegParms registerMaskFor(sqInt reg) { - return 1ULL << reg; + return ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } /* Cogit>>#registerMaskFor:and: */ @@ -12176,6 +12273,10 @@ voidCogCompiledCode(void) unpairedMethodList = null; methodBytesFreedSinceLastCompaction = 0; methodCount = 0; + /* begin ensureExecutableCodeZone */ +# if !DUAL_MAPPED_CODE_ZONE + +# endif } @@ -18011,7 +18112,7 @@ generateObjectRepresentationTrampolines(void) genoperand(RetN, 0); jmpTarget(jumpSC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1U << ReceiverResultReg)) - (1U << ReceiverResultReg)), 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | ((1U << ReceiverResultReg))) - ((1U << ReceiverResultReg))), 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); @@ -19268,7 +19369,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpRC, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileTrampolineFornumArgsargargargargregsToSavepushLinkRegresultReg(remember, 1, ReceiverResultReg, null, null, null, 0 /* emptyRegisterMask */, 1, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg)); jmpTarget(jumpImmutable, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); @@ -19284,7 +19385,7 @@ genStoreTrampolineCalledinstVarIndex(char *trampolineName, sqInt instVarIndex) /* Store check */ jumpImmutable1 = genJumpImmutablescratchReg(ReceiverResultReg, SendNumArgsReg); - compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0) + compileCallFornumArgsargargargargresultRegregsToSave(remember, 1, ReceiverResultReg, null, null, null, (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0) ? ReceiverResultReg : ABIResultReg), 0 /* emptyRegisterMask */); genLoadStackPointers(backEnd()); @@ -19842,7 +19943,7 @@ registerMask(SimStackEntry * self_in_registerMask) || (((self_in_registerMask->type)) == SSRegister) ? (/* begin registerMaskFor: */ (reg = (self_in_registerMask->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19855,7 +19956,7 @@ registerMaskOrNone(SimStackEntry * self_in_registerMaskOrNone) return (((self_in_registerMaskOrNone->type)) == SSRegister ? (/* begin registerMaskFor: */ (reg = (self_in_registerMaskOrNone->registerr)), - 1ULL << reg) + ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg))) : 0); } @@ -19930,37 +20031,37 @@ isMergeFixup(BytecodeFixup * self_in_isMergeFixup) static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask) { - if (!(((liveRegsMask & (1U << Extra5Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra5Reg))) != 0))) { return Extra5Reg; } - if (!(((liveRegsMask & (1U << Extra4Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra4Reg))) != 0))) { return Extra4Reg; } - if (!(((liveRegsMask & (1U << Extra3Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra3Reg))) != 0))) { return Extra3Reg; } - if (!(((liveRegsMask & (1U << Extra2Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra2Reg))) != 0))) { return Extra2Reg; } - if (!(((liveRegsMask & (1U << Extra1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra1Reg))) != 0))) { return Extra1Reg; } - if (!(((liveRegsMask & (1U << Extra0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Extra0Reg))) != 0))) { return Extra0Reg; } - if (!(((liveRegsMask & (1U << Arg1Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg1Reg))) != 0))) { return Arg1Reg; } - if (!(((liveRegsMask & (1U << Arg0Reg)) != 0))) { + if (!(((liveRegsMask & ((1U << Arg0Reg))) != 0))) { return Arg0Reg; } - if (!(((liveRegsMask & (1U << SendNumArgsReg)) != 0))) { + if (!(((liveRegsMask & ((1U << SendNumArgsReg))) != 0))) { return SendNumArgsReg; } - if (!(((liveRegsMask & (1U << ClassReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ClassReg))) != 0))) { return ClassReg; } - if (!(((liveRegsMask & (1U << ReceiverResultReg)) != 0))) { + if (!(((liveRegsMask & ((1U << ReceiverResultReg))) != 0))) { return ReceiverResultReg; } return NoReg; @@ -20539,6 +20640,11 @@ computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize) ? 1 : 0)); + case MovePerfCnt64RL: + + /* it is easier to calculate the right value by concretizing. We concretize twice, but so what? */ + return concretizeMovePerfCnt64RL(self_in_computeMaximumSize); + default: error("Case not found and no otherwise clause"); } @@ -20630,6 +20736,65 @@ concretizeFill32(AbstractInstruction * self_in_concretizeFill32) return 4; } + +/* Generate code for + 0x0: 50 pushq %rax + 0x1: 52 pushq %rdx + 0x2: 0f 31 rdtsc + 0x4: 48 c1 e2 20 shlq $0x20, %rdx + 0x8: 48 09 d0 orq %rdx, %rax + 0xb: 48 89 f8 movq %rdi, %rax + 0xe: 5a popq %rdx + 0xf: 58 popq %rax + et al */ + + /* CogX64Compiler>>#concretizeMovePerfCnt64RL */ +static sqInt NoDbgRegParms +concretizeMovePerfCnt64RL(AbstractInstruction * self_in_concretizeMovePerfCnt64RL) +{ + usqInt liveRegisterMask; + sqInt offset; + usqInt reg; + + reg = ((self_in_concretizeMovePerfCnt64RL->operands))[0]; + liveRegisterMask = ((self_in_concretizeMovePerfCnt64RL->operands))[1]; + offset = 0; + if (((liveRegisterMask & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[0] = 80; + offset += 1; + } + if (((liveRegisterMask & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 82; + offset += 1; + } + assert(!((reg == RDX))); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 15; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 49; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (rexRxb(self_in_concretizeMovePerfCnt64RL, 0, 0, RDX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 3] = 193; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 4] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RDX, 4)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 5] = 32; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 6] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RDX, 0, RAX)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 7] = 11; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 8] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, RAX, RDX)); + offset += 9; + if (reg != RAX) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = (rexRxb(self_in_concretizeMovePerfCnt64RL, RAX, 0, reg)); + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 1] = 137; + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset + 2] = (modRMRO(self_in_concretizeMovePerfCnt64RL, ModReg, reg, RAX)); + offset += 3; + } + if (((liveRegisterMask & ((1U << RDX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 90; + offset += 1; + } + if (((liveRegisterMask & ((1U << RAX))) != 0)) { + ((self_in_concretizeMovePerfCnt64RL->machineCode))[offset] = 88; + offset += 1; + } + return offset; +} + /* CogX64Compiler>>#concretizeMoveRX32rR */ static sqInt NoDbgRegParms concretizeMoveRX32rR(AbstractInstruction * self_in_concretizeMoveRX32rR) @@ -24032,6 +24197,9 @@ dispatchConcretize(AbstractInstruction * self_in_dispatchConcretize) ((self_in_dispatchConcretize->machineCode))[skip28 + 1] = (modRMRO(self_in_dispatchConcretize, ModReg, srcReg28, destReg29)); return skip28 + 2; + case MovePerfCnt64RL: + return concretizeMovePerfCnt64RL(self_in_dispatchConcretize); + default: error("Case not found and no otherwise clause"); } @@ -24660,8 +24828,8 @@ genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushReg /* This is a no-op on x64 SysV since the ABI passes up to 6 args in registers and trampolines currently observe a limit of 4. - But the WIN64 ABI allways reserve shadow space for saving up to 4 - parameter registers (even if less than 4 args). + But the WIN64 ABI always reserve shadow space for saving up to 4 parameter + registers (even if less than 4 args). */ /* CogX64Compiler>>#genRemoveNArgsFromStack: */ @@ -24687,7 +24855,7 @@ genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask) assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = RAX; reg <= R15; reg += 1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PopR: */ genoperand(PopR, reg); } @@ -24709,7 +24877,7 @@ genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask) assert(((R15 - RAX) + 1) == 16); assert(!((((regMask & (registerMaskForand(RSP, RBP))) != 0)))); for (reg = R15; reg >= RAX; reg += -1) { - if (((regMask & (1ULL << reg)) != 0)) { + if (((regMask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0)) { /* begin PushR: */ genoperand(PushR, reg); } @@ -24736,6 +24904,17 @@ genSwapRRScratch(AbstractInstruction * self_in_genSwapRRScratch, sqInt regA, sqI } +/* Answer if the processor has a dedicated callee-saved register to point to + the base of commonly-accessed variables. */ + + /* CogX64Compiler>>#hasVarBaseRegister */ +static sqInt NoDbgRegParms +hasVarBaseRegister(AbstractInstruction * self_in_hasVarBaseRegister) +{ + return 1; +} + + /* Answer the instruction size at pc. This is used in method disassembly to decode the jumps in block dispatch to discover where block methods occur within a larger method. This is very far from a full decode. */ @@ -25512,64 +25691,54 @@ compileGetErrorCode(void) /* Compile a call to an interpreter primitive. Call the C routine with the usual stack-switching dance, test the primFailCode and then either return on success or continue to the method body. */ -/* Save processor fp, sp and return pc in the interpreter's frame stack and - instruction pointers - */ /* SimpleStackBasedCogit>>#compileInterpreterPrimitive:flags: */ static sqInt NoDbgRegParms compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { - sqInt address2; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; - AbstractInstruction *anInstruction12; + AbstractInstruction *anInstruction111; AbstractInstruction *anInstruction13; - AbstractInstruction *anInstruction15; + AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; AbstractInstruction *anInstruction20; AbstractInstruction *anInstruction21; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction23; - AbstractInstruction *anInstruction24; AbstractInstruction *anInstruction25; AbstractInstruction *anInstruction26; AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; AbstractInstruction *anInstruction29; AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction31; - AbstractInstruction *anInstruction33; - AbstractInstruction *anInstruction34; - AbstractInstruction *anInstruction35; - AbstractInstruction *anInstruction36; - AbstractInstruction *anInstruction37; - AbstractInstruction *anInstruction38; - AbstractInstruction *anInstruction39; AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction40; AbstractInstruction *anInstruction41; - AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; - AbstractInstruction * continuePostSampleNonPrim; - AbstractInstruction * continuePostSamplePrim; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; - AbstractInstruction * jmpSampleNonPrim; - AbstractInstruction * jmpSamplePrim; + AbstractInstruction * jump; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisterMask; sqInt offset; sqInt offset1; sqInt offset2; - sqInt operand1; - sqInt operand3; sqInt reg; sqInt retpc; + AbstractInstruction * skip; - continuePostSampleNonPrim = ((AbstractInstruction *) 0); - continuePostSamplePrim = ((AbstractInstruction *) 0); - jmpSampleNonPrim = ((AbstractInstruction *) 0); - jmpSamplePrim = ((AbstractInstruction *) 0); + jumpToTakeSample = ((AbstractInstruction *) 0); + assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); genExternalizePointersForPrimitiveCall(); /* begin genLoadCStackPointersForPrimCall */ if (cFramePointerInUse) { @@ -25578,42 +25747,28 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) else { genLoadCStackPointer(backEnd); } - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick if so */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction2 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction3 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSampleNonPrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSampleNonPrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } if (recordPrimTraceForMethod(methodObj)) { genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction37 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction18 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction38 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction19 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction39 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction20 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { /* begin checkLiteral:forInstruction: */ ((sqInt)primitiveRoutine); - anInstruction5 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + anInstruction1 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); /* begin checkLiteral:forInstruction: */ primitiveFunctionPointerAddress(); - anInstruction6 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); - primSetFunctionLabel = anInstruction6; + anInstruction2 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); } if (((flags & (PrimCallNeedsNewMethod + PrimCallMayEndureCodeCompaction)) != 0)) { @@ -25625,17 +25780,16 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* begin MoveMw:r:R: */ offset = offsetof(CogMethod, methodObject); /* begin checkQuickConstant:forInstruction: */ - anInstruction7 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); /* begin checkLiteral:forInstruction: */ newMethodAddress(); - anInstruction8 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction4 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction40 = genoperand(PrefetchAw, primFailCodeAddress()); + anInstruction22 = genoperand(PrefetchAw, primFailCodeAddress()); if (((flags & PrimCallMayEndureCodeCompaction) != 0)) { - /* Sideways call the C primitive routine so that we return through cePrimReturnEnterCogCode. */ /* On Spur ceActivateFailingPrimitiveMethod: would like to retry if forwarders are found. So insist on PrimCallNeedsPrimitiveFunction being set too. */ assert(((flags & PrimCallNeedsPrimitiveFunction) != 0)); @@ -25643,12 +25797,12 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ /* begin checkQuickConstant:forInstruction: */ - anInstruction11 = genoperandoperand(SubCqR, 32, RSP); - goto l32; + anInstruction7 = genoperandoperand(SubCqR, 32, RSP); + goto l20; assert(0 <= 4); if (null < NoReg) { /* begin MoveCq:R: */ - anInstruction12 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); + anInstruction11 = genoperandoperand(MoveCqR, -2 - null, CArg0Reg); } else { if (null != CArg0Reg) { @@ -25686,117 +25840,101 @@ compileInterpreterPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) genoperandoperand(MoveRR, null, CArg3Reg); } } - l32: /* end genMarshallNArgs:arg:arg:arg:arg: */; + l20: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin genSubstituteReturnAddress: */ retpc = (((flags & PrimCallCollectsProfileSamples) != 0) ? cePrimReturnEnterCogCodeProfiling : cePrimReturnEnterCogCode); /* begin checkLiteral:forInstruction: */ - anInstruction13 = genoperand(PushCw, retpc); + anInstruction8 = genoperand(PushCw, retpc); /* begin gen:literal: */ - anInstruction10 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); - primInvokeInstruction = anInstruction10; - jmp = (jmpSamplePrim = (continuePostSamplePrim = null)); + anInstruction6 = genoperand(JumpFull, ((sqInt)(((sqInt)primitiveRoutine)))); + return 0; } - else { - - /* Call the C primitive routine. */ - /* begin genMarshallNArgs:arg:arg:arg:arg: */ - - /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ - /* begin checkQuickConstant:forInstruction: */ - anInstruction20 = genoperandoperand(SubCqR, 32, RSP); - goto l49; - assert(0 <= 4); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg0Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg1Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg2Reg); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, 0, CArg3Reg); - l49: /* end genMarshallNArgs:arg:arg:arg:arg: */; - /* begin gen:literal: */ - anInstruction15 = genoperand(CallFull, ((sqInt)primitiveRoutine)); - primInvokeInstruction = anInstruction15; - /* begin genRemoveNArgsFromStack: */ - assert(0 <= 4); - /* begin checkQuickConstant:forInstruction: */ - anInstruction23 = genoperandoperand(AddCqR, 32, RSP); - if (((flags & PrimCallCollectsProfileSamples) != 0)) { - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction18 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSamplePrim = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSamplePrim = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } - maybeCompileRetryOnPrimitiveFail(primitiveIndex); - /* begin MoveAw:R: */ - address2 = instructionPointerAddress(); - reg = ClassReg; - /* begin checkLiteral:forInstruction: */ - anInstruction24 = genoperandoperand(MoveAwR, address2, reg); - genLoadStackPointers(backEnd); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction23 = genoperandoperand(SubCqR, 32, RSP); + goto l43; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l43: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + anInstruction10 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction25 = genoperandoperand(AddCqR, 32, RSP); + maybeCompileRetryOnPrimitiveFail(primitiveIndex); + genLoadStackPointersForPrimCall(backEnd, ClassReg); + /* begin checkLiteral:forInstruction: */ + instructionPointerAddress(); + anInstruction13 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction14 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction26 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + flag("ask concrete code gen if move sets condition codes?"); + /* begin checkQuickConstant:forInstruction: */ + anInstruction27 = genoperandoperand(CmpCqR, 0, TempReg); + /* begin JumpNonZero: */ + jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; /* begin checkLiteral:forInstruction: */ - primFailCodeAddress(); - anInstruction25 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - /* begin PushR: */ - genoperand(PushR, ClassReg); - flag("ask concrete code gen if move sets condition codes?"); - /* begin checkQuickConstant:forInstruction: */ - anInstruction26 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = BytesPerWord; + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); /* begin checkQuickConstant:forInstruction: */ - anInstruction27 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); - /* begin RetN: */ - genoperand(RetN, BytesPerWord); + anInstruction111 = genoperandoperand(CmpCqR, 0, Arg1Reg); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jumpToTakeSample = jump; + goto l62; + l62: /* end genCheckForProfileTimerTick: */; } + /* begin MoveMw:r:R: */ + offset1 = BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction28 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); + continueAfterProfileSample = anInstruction28; + /* begin RetN: */ + genoperand(RetN, BytesPerWord); if (((flags & PrimCallCollectsProfileSamples) != 0)) { - - /* The sample is collected by cePrimReturnEnterCogCode for external calls */ - if (!(jmpSamplePrim == null)) { - - /* Call ceCheckProfileTick: to record sample and then continue. */ - jmpTarget(jmpSamplePrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - assert(((flags & PrimCallNeedsNewMethod) != 0)); - /* begin gen:literal: */ - operand1 = ((usqIntptr_t)ceCheckProfileTick); - /* begin checkLiteral:forInstruction: */ - anInstruction29 = genoperand(CallFull, operand1); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSamplePrim)); - } - jmpTarget(jmpSampleNonPrim, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin checkQuickConstant:forInstruction: */ - anInstruction34 = genoperandoperand(MoveCqR, 0, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction35 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); - /* begin gen:literal: */ - operand3 = ((usqIntptr_t)ceCheckProfileTick); + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + genLoadStackPointerForPrimCall(backEnd, ClassReg); /* begin checkLiteral:forInstruction: */ - anInstruction33 = genoperand(CallFull, operand3); - /* begin Jump: */ - genoperand(Jump, ((sqInt)continuePostSampleNonPrim)); - } - if (!(jmp == null)) { - - /* Jump to restore of receiver reg and proceed to frame build for failure. */ - jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin MoveMw:r:R: */ - offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + instructionPointerAddress(); + anInstruction16 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction36 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); + anInstruction17 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, SPReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); } + jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + /* begin MoveMw:r:R: */ + offset2 = BytesPerWord * (methodOrBlockNumArgs + (1)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction29 = genoperandoperandoperand(MoveMwrR, offset2, SPReg, ReceiverResultReg); return 0; } @@ -25828,7 +25966,7 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) if ((methodOrBlockNumArgs > 2 /* numRegArgs */) || (methodOrBlockNumArgs == 0)) { /* begin registerMaskFor: */ - liveRegsMask = 1U << ReceiverResultReg; + liveRegsMask = (1U << ReceiverResultReg); } else { if (methodOrBlockNumArgs > 1) { @@ -25909,72 +26047,161 @@ compileMachineCodeInterpreterPrimitive(void (*primitiveRoutine)(void)) depth, assign framePointer and newMethod, do the stack switch, call checkForAndFollowForwardedPrimitiveState, and loop back if forwarders are found. - Fall throguh tio frame build. */ -/* Clear the primFailCode and set argumentCount */ + Fall through to frame build. */ - /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive: */ + /* SimpleStackBasedCogit>>#compileOnStackExternalPrimitive:flags: */ static sqInt NoDbgRegParms -compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) +compileOnStackExternalPrimitiveflags(void (*primitiveRoutine)(void), sqInt flags) { AbstractInstruction *anInstruction; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction11; + AbstractInstruction *anInstruction111; AbstractInstruction *anInstruction12; AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; + AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; + AbstractInstruction *anInstruction18; + AbstractInstruction *anInstruction19; AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction20; + AbstractInstruction *anInstruction22; + AbstractInstruction *anInstruction23; + AbstractInstruction *anInstruction24; + AbstractInstruction *anInstruction26; + AbstractInstruction *anInstruction27; + AbstractInstruction *anInstruction28; + AbstractInstruction *anInstruction29; + AbstractInstruction *anInstruction30; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction5; AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; - sqInt calleeSavedReg; + sqInt calleeSavedRegisterMask; + AbstractInstruction * continueAfterProfileSample; AbstractInstruction * jmp; + AbstractInstruction * jump; + AbstractInstruction * jumpToTakeSample; + sqInt liveRegisterMask; sqInt offset; + sqInt offset1; sqInt operand1; + sqInt reg; + sqInt retpcOffset; AbstractInstruction * retry; - + AbstractInstruction * skip; + AbstractInstruction * skip1; + sqInt spRegSaveRegister; + + jumpToTakeSample = ((AbstractInstruction *) 0); + assert(((flags & PrimCallOnSmalltalkStack) != 0)); + assert(!((registerisInMask(VarBaseReg, ABICallerSavedRegisterMask)))); + if (recordFastCCallPrimTraceForMethod(methodObj)) { + genFastPrimTraceUsingand(ClassReg, SendNumArgsReg); + } /* begin checkQuickConstant:forInstruction: */ - anInstruction9 = genoperandoperand(MoveCqR, 0, TempReg); + anInstruction20 = genoperandoperand(MoveCqR, 0, TempReg); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction10 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + anInstruction22 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); if (methodOrBlockNumArgs != 0) { /* begin checkQuickConstant:forInstruction: */ - anInstruction = genoperandoperand(MoveCqR, methodOrBlockNumArgs, TempReg); + anInstruction = genoperandoperand(AddCqR, methodOrBlockNumArgs, TempReg); } /* begin checkLiteral:forInstruction: */ argumentCountAddress(); - anInstruction11 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); + anInstruction23 = genoperandoperand(MoveRAw, TempReg, argumentCountAddress()); genExternalizeStackPointerForFastPrimitiveCall(); + calleeSavedRegisterMask = ((ABICalleeSavedRegisterMask | ((1U << ClassReg))) - ((1U << ClassReg))); + spRegSaveRegister = NoReg; /* begin Label */ retry = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - calleeSavedReg = NoReg; + if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { + gAndCqRR((-1 - (((BytesPerWord * 2) - 1))), SPReg, NativeSPReg); + } + else { + } + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction24 = genoperandoperand(SubCqR, 32, RSP); + goto l53; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l53: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ - anInstruction2 = genoperand(CallFull, primitiveRoutine); + anInstruction2 = genoperand(CallFull, ((sqInt)primitiveRoutine)); + /* begin genRemoveNArgsFromStack: */ + assert(0 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction26 = genoperandoperand(AddCqR, 32, RSP); /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction12 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); - if (calleeSavedReg != NoReg) { + anInstruction27 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + if (spRegSaveRegister != NoReg) { /* begin MoveR:R: */ - genoperandoperand(MoveRR, calleeSavedReg, SPReg); + genoperandoperand(MoveRR, spRegSaveRegister, SPReg); } /* begin checkQuickConstant:forInstruction: */ - anInstruction13 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction28 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmp = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin PopR: */ - genoperand(PopR, TempReg); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction30 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction111 = genoperandoperand(CmpCqR, 0, Arg1Reg); + /* begin JumpZero: */ + skip1 = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip1, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jumpToTakeSample = jump; + goto l71; + l71: /* end genCheckForProfileTimerTick: */; + } /* begin checkLiteral:forInstruction: */ stackPointerAddress(); - anInstruction14 = genoperandoperand(MoveAwR, stackPointerAddress(), SPReg); - /* begin PopR: */ - genoperand(PopR, ReceiverResultReg); - /* begin PushR: */ - genoperand(PushR, TempReg); + anInstruction29 = genoperandoperand(MoveAwR, stackPointerAddress(), TempReg); + continueAfterProfileSample = anInstruction29; + + /* The original retpc is (argumentCount + 1) words below stackPointer. */ + retpcOffset = -((methodOrBlockNumArgs + 1) * BytesPerWord); + /* begin checkQuickConstant:forInstruction: */ + anInstruction4 = genoperandoperandoperand(MoveMwrR, retpcOffset, TempReg, ClassReg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, TempReg, SPReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperandoperand(MoveMwrR, 0, TempReg, ReceiverResultReg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveRMwr, ClassReg, 0, TempReg); /* begin RetN: */ genoperand(RetN, 0); + if (((flags & PrimCallCollectsProfileSamples) != 0)) { + jmpTarget(jumpToTakeSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + genTakeProfileSample(); + /* begin Jump: */ + genoperand(Jump, ((sqInt)continueAfterProfileSample)); + } jmpTarget(jmp, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); if ((accessorDepthForExternalPrimitiveMethod(methodObj)) >= 0) { @@ -25983,7 +26210,21 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) This won't be a performance issue since primitive failure should be very rare. */ /* begin checkLiteral:forInstruction: */ framePointerAddress(); - anInstruction5 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); + anInstruction9 = genoperandoperand(MoveRAw, FPReg, framePointerAddress()); + /* begin checkLiteral:forInstruction: */ + ((sqInt)primitiveRoutine); + anInstruction10 = genoperandoperand(MoveCwR, ((sqInt)primitiveRoutine), TempReg); + /* begin checkLiteral:forInstruction: */ + primitiveFunctionPointerAddress(); + anInstruction11 = genoperandoperand(MoveRAw, TempReg, primitiveFunctionPointerAddress()); + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin MoveMw:r:R: */ + offset = offsetof(CogMethod, methodObject); + /* begin checkQuickConstant:forInstruction: */ + anInstruction12 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + /* begin checkLiteral:forInstruction: */ + newMethodAddress(); + anInstruction13 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); /* begin genLoadCStackPointersForPrimCall */ if (cFramePointerInUse) { genLoadCStackPointers(backEnd); @@ -25991,23 +26232,52 @@ compileOnStackExternalPrimitive(void (*primitiveRoutine)(void)) else { genLoadCStackPointer(backEnd); } - addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); - /* begin MoveMw:r:R: */ - offset = offsetof(CogMethod, methodObject); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ /* begin checkQuickConstant:forInstruction: */ - anInstruction6 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); - /* begin checkLiteral:forInstruction: */ - newMethodAddress(); - anInstruction7 = genoperandoperand(MoveRAw, TempReg, newMethodAddress()); + anInstruction14 = genoperandoperand(SubCqR, 32, RSP); + goto l36; + assert(0 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l36: /* end genMarshallNArgs:arg:arg:arg:arg: */; /* begin gen:literal: */ operand1 = ((usqIntptr_t)checkForAndFollowForwardedPrimitiveState); /* begin checkLiteral:forInstruction: */ - anInstruction4 = genoperand(CallFull, operand1); - genLoadStackPointers(backEnd); + anInstruction8 = genoperand(CallFull, operand1); + genLoadStackPointersForPrimCall(backEnd, ClassReg); /* begin checkQuickConstant:forInstruction: */ - anInstruction8 = genoperandoperand(CmpCqR, 0, ABIResultReg); - /* begin JumpNonZero: */ - genConditionalBranchoperand(JumpNonZero, ((sqInt)retry)); + anInstruction16 = genoperandoperand(CmpCqR, 0, ABIResultReg); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + /* begin checkQuickConstant:forInstruction: */ + anInstruction17 = genoperandoperand(MoveCqR, 0, TempReg); + /* begin checkLiteral:forInstruction: */ + primFailCodeAddress(); + anInstruction18 = genoperandoperand(MoveRAw, TempReg, primFailCodeAddress()); + /* begin Jump: */ + genoperand(Jump, ((sqInt)retry)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + } + else { + + /* must reload SPReg to undo any alignment change, */ + if (((flags & PrimCallOnSmalltalkStackAlign2x) != 0)) { + genLoadStackPointersForPrimCall(backEnd, ClassReg); + } + } + if (((ABICallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { + /* begin MoveMw:r:R: */ + offset1 = (methodOrBlockNumArgs + (1)) * BytesPerWord; + /* begin checkQuickConstant:forInstruction: */ + anInstruction19 = genoperandoperandoperand(MoveMwrR, offset1, SPReg, ReceiverResultReg); } return 0; } @@ -26254,18 +26524,18 @@ compilePrimitive(void) if (((flags & PrimCallDoNotJIT) != 0)) { return ShouldNotJIT; } - if (((flags & PrimCallOnSmalltalkStack) != 0)) { - if (((flags & PrimCallNeedsPrimitiveFunction) != 0)) { - - /* TEMPORARY HACK!! */ - return compileOnStackExternalPrimitive(primitiveRoutine); - } - return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); - } if ((primitiveRoutine == 0) || (primitiveRoutine == (((void (*)(void)) primitiveFail)))) { return genFastPrimFail(); } + if (((flags & PrimCallOnSmalltalkStack) != 0)) { + assert(!(((((flags & FastCPrimitiveUseCABIFlag) != 0)) + && (((flags & PrimCallOnSmalltalkStackAlign2x) != 0))))); + if (((flags & FastCPrimitiveUseCABIFlag) != 0)) { + return compileMachineCodeInterpreterPrimitive(((void (*)(void)) (mcprimFunctionForPrimitiveIndex(primitiveIndex)))); + } + return compileOnStackExternalPrimitiveflags(primitiveRoutine, flags); + } minValidCallAddress = ((minValidCallAddress < (((usqInt)primitiveRoutine))) ? minValidCallAddress : (((usqInt)primitiveRoutine))); return compileInterpreterPrimitiveflags(primitiveRoutine, flags); } @@ -27040,23 +27310,29 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) { sqInt address1; AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; AbstractInstruction *anInstruction10; AbstractInstruction *anInstruction12; - AbstractInstruction *anInstruction13; AbstractInstruction *anInstruction14; AbstractInstruction *anInstruction15; - AbstractInstruction *anInstruction16; + AbstractInstruction *anInstruction17; AbstractInstruction *anInstruction18; - AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction19; + AbstractInstruction *anInstruction20; + AbstractInstruction *anInstruction22; AbstractInstruction *anInstruction4; AbstractInstruction *anInstruction8; AbstractInstruction *anInstruction9; - sqInt callTarget; AbstractInstruction *continuePostSample; AbstractInstruction *jmpFail; AbstractInstruction *jmpSample; + AbstractInstruction * jump; + sqInt liveRegisterMask; + sqInt operand1; sqInt quickConstant; sqInt reg; + sqInt reg1; + AbstractInstruction * skip; continuePostSample = ((AbstractInstruction *) 0); jmpSample = ((AbstractInstruction *) 0); @@ -27065,28 +27341,40 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) quickConstant = varBaseAddress(); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, quickConstant, VarBaseReg); - if (profiling) { - - /* Test nextProfileTick for being non-zero and call checkProfileTick: if so. - N.B. nextProfileTick is 64-bits so 32-bit systems need to test both halves. */ - /* begin checkLiteral:forInstruction: */ - nextProfileTickAddress(); - anInstruction3 = genoperandoperand(MoveAwR, nextProfileTickAddress(), TempReg); - /* begin checkQuickConstant:forInstruction: */ - anInstruction4 = genoperandoperand(CmpCqR, 0, TempReg); - /* begin JumpNonZero: */ - jmpSample = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - } /* begin checkLiteral:forInstruction: */ primFailCodeAddress(); - anInstruction13 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); + anInstruction18 = genoperandoperand(MoveAwR, primFailCodeAddress(), TempReg); flag("ask concrete code gen if move sets condition codes?"); /* begin checkQuickConstant:forInstruction: */ - anInstruction14 = genoperandoperand(CmpCqR, 0, TempReg); + anInstruction19 = genoperandoperand(CmpCqR, 0, TempReg); /* begin JumpNonZero: */ jmpFail = genConditionalBranchoperand(JumpNonZero, ((sqInt)0)); + if (profiling + && (1)) { + /* begin genCheckForProfileTimerTick: */ + liveRegisterMask = (0); + /* begin preferredRegisterForMovePerfCnt64RL */ + reg = RAX; + /* begin checkLiteral:forInstruction: */ + nextProfileTickAddress(); + anInstruction4 = genoperandoperand(MoveAwR, nextProfileTickAddress(), Arg1Reg); + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperand(CmpCqR, 0, Arg1Reg); + /* begin JumpZero: */ + skip = genConditionalBranchoperand(JumpZero, ((sqInt)0)); + gMovePerfCnt64RL(reg, liveRegisterMask); + /* begin CmpR:R: */ + assert(!((Arg1Reg == SPReg))); + genoperandoperand(CmpRR, Arg1Reg, reg); + /* begin JumpAboveOrEqual: */ + jump = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + jmpTarget(skip, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); + jmpSample = jump; + goto l22; + l22: /* end genCheckForProfileTimerTick: */; + /* begin Label */ + continuePostSample = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } /* begin checkLiteral:forInstruction: */ instructionPointerAddress(); anInstruction8 = genoperandoperand(MoveAwR, instructionPointerAddress(), ClassReg); @@ -27100,13 +27388,13 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) jmpTarget(jmpFail, checkLiteralforInstruction(newMethodAddress(), genoperandoperand(MoveAwR, newMethodAddress(), SendNumArgsReg))); /* begin checkLiteral:forInstruction: */ cStackPointerAddress(); - anInstruction15 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); + anInstruction20 = genoperandoperand(MoveAwR, cStackPointerAddress(), SPReg); compileCallFornumArgsargargargargresultRegregsToSave(ceActivateFailingPrimitiveMethod, 1, SendNumArgsReg, null, null, null, NoReg, 0 /* emptyRegisterMask */); /* begin MoveAw:R: */ address1 = instructionPointerAddress(); - reg = ClassReg; + reg1 = ClassReg; /* begin checkLiteral:forInstruction: */ - anInstruction16 = genoperandoperand(MoveAwR, address1, reg); + anInstruction22 = genoperandoperand(MoveAwR, address1, reg1); genLoadStackPointers(backEnd); /* begin checkQuickConstant:forInstruction: */ anInstruction12 = genoperandoperandoperand(MoveMwrR, BytesPerWord, SPReg, ReceiverResultReg); @@ -27114,16 +27402,36 @@ genPrimReturnEnterCogCodeEnilopmart(sqInt profiling) genoperand(PushR, ClassReg); /* begin RetN: */ genoperand(RetN, BytesPerWord); - if (profiling) { + if (profiling + && (1)) { - /* Call ceCheckProfileTick: to record sample and then continue. newMethod + /* Call ceTakeProfileSample: to record sample and then continue. newMethod should be up-to-date. Need to save and restore the link reg around this call. */ jmpTarget(jmpSample, genoperandoperand(Label, (labelCounter += 1), bytecodePC)); - /* begin saveAndRestoreLinkRegAround: */ - /* begin CallFullRT: */ - callTarget = (usqIntptr_t)ceCheckProfileTick; + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction15 = genoperandoperand(SubCqR, 32, RSP); + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg0Reg); + goto l42; + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg1Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg2Reg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, 0, CArg3Reg); + l42: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqInt)ceTakeProfileSample); /* begin checkLiteral:forInstruction: */ - anInstruction18 = genoperand(CallFull, callTarget); + anInstruction14 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction17 = genoperandoperand(AddCqR, 32, RSP); /* begin Jump: */ genoperand(Jump, ((sqInt)continuePostSample)); } @@ -27498,6 +27806,69 @@ genStoreRemoteTempLongBytecode(void) && (shouldAnnotateObjectReference(((ssTop())->constant))))); } + /* SimpleStackBasedCogit>>#genTakeProfileSample */ +static void +genTakeProfileSample(void) +{ + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + sqInt operand1; + + addDependent(methodLabel, annotateAbsolutePCRef(checkLiteralforInstruction(((sqInt)methodLabel), genoperandoperand(MoveCwR, ((sqInt)methodLabel), ClassReg)))); + /* begin genMarshallNArgs:arg:arg:arg:arg: */ + + /* WIN64 ABI allways reserve shadow space on the stack for callee to save up to 4 register parameters */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperand(SubCqR, 32, RSP); + assert(1 <= 4); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, CArg0Reg); + goto l12; + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction2 = genoperandoperand(MoveCqR, -2 - null, CArg1Reg); + } + else { + if (null != CArg1Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg1Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction3 = genoperandoperand(MoveCqR, -2 - null, CArg2Reg); + } + else { + if (null != CArg2Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg2Reg); + } + } + if (null < NoReg) { + /* begin MoveCq:R: */ + anInstruction4 = genoperandoperand(MoveCqR, -2 - null, CArg3Reg); + } + else { + if (null != CArg3Reg) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, null, CArg3Reg); + } + } + l12: /* end genMarshallNArgs:arg:arg:arg:arg: */; + /* begin gen:literal: */ + operand1 = ((usqIntptr_t)ceTakeProfileSample); + /* begin checkLiteral:forInstruction: */ + anInstruction1 = genoperand(CallFull, operand1); + /* begin genRemoveNArgsFromStack: */ + assert(1 <= 4); + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperand(AddCqR, 32, RSP); + } + /* Collect the branch and send data for cogMethod, storing it into arrayObj. */ @@ -27811,6 +28182,13 @@ primitiveGeneratorOrNil(void) return null; } + /* SimpleStackBasedCogit>>#register:isInMask: */ +static sqInt NoDbgRegParms +registerisInMask(sqInt reg, sqInt mask) +{ + return ((mask & (((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)))) != 0); +} + /* SimpleStackBasedCogit>>#v3:Block:Code:Size: */ static sqInt NoDbgRegParms v3BlockCodeSize(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) @@ -28149,7 +28527,7 @@ anyReferencesToRegisterinTopNItems(sqInt reg, sqInt n) sqInt regMask; /* begin registerMaskFor: */ - regMask = 1ULL << reg; + regMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); for (i = simStackPtr; i >= ((simStackPtr - n) + 1); i += -1) { if ((((registerMask(simStackAt(i))) & regMask) != 0)) { return 1; @@ -28991,7 +29369,7 @@ ensureReceiverResultRegContainsSelf(void) if (needsFrame) { if (!((((simSelf())->liveRegister)) == ReceiverResultReg)) { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); ((simSelf())->liveRegister = ReceiverResultReg); @@ -29123,7 +29501,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) && (index < simStackPtr)) { desc = simStackAt(index); if (((desc->type)) == SSRegister) { - if (!(((regMask & (1ULL << ((desc->registerr)))) != 0))) { + if (!(((regMask & (((((desc->registerr)) < 0) ? (((usqInt)(1)) >> (-((desc->registerr)))) : (1ULL << ((desc->registerr)))))) != 0))) { reg = (desc->registerr); } } @@ -29131,7 +29509,7 @@ freeAnyRegNotConflictingWith(sqInt regMask) } assert(!((reg == NoReg))); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1ULL << reg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)), simStackPtr, simNativeStackPtr); return reg; } @@ -29633,13 +30011,13 @@ genForwardersInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -30212,7 +30590,7 @@ genNSSendnumArgsdepthsendTable(sqInt selectorIndex, sqInt numArgs, sqInt depth, (nsSendCache1->depth = depth); (nsSendCache1->classTag = 0 /* illegalClassTag */); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << SendNumArgsReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); marshallAbsentReceiverSendArguments(numArgs); /* begin uniqueLiteral:forInstruction: */ anInstruction = genoperandoperand(MoveCwR, nsSendCache, SendNumArgsReg); @@ -30427,7 +30805,7 @@ genPushEnclosingObjectAt(sqInt level) voidReceiverResultRegContainsSelf(); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperand(MoveCqR, level, SendNumArgsReg); /* begin CallRT: */ @@ -30553,11 +30931,11 @@ genPushMaybeContextReceiverVariable(sqInt slotIndex) AbstractInstruction *jmpSingle; /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ReceiverResultReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (((CallerSavedRegisterMask & (1U << ReceiverResultReg)) != 0)) { + if (((CallerSavedRegisterMask & ((1U << ReceiverResultReg))) != 0)) { /* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ voidReceiverResultRegContainsSelf(); @@ -30610,7 +30988,7 @@ genPushNewArrayBytecode(void) } else { /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << SendNumArgsReg) | (1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << SendNumArgsReg)) | ((1U << ReceiverResultReg))), simStackPtr, simNativeStackPtr); } size = byte1 & 0x7F; if (!popValues) { @@ -30683,7 +31061,7 @@ genPushRemoteTempLongBytecode(void) /* begin checkQuickConstant:forInstruction: */ anInstruction = genoperandoperandoperand(MoveMwrR, offset, FPReg, tempVectReg); /* begin availableRegOrNoneNotConflictingWith: */ - regMask = 1ULL << tempVectReg; + regMask = ((tempVectReg < 0) ? (((usqInt)(1)) >> (-tempVectReg)) : (1ULL << tempVectReg)); remoteTempReg = availableRegisterOrNoneFor(backEnd, (liveRegisters()) | regMask); if (remoteTempReg == NoReg) { remoteTempReg = tempVectReg; @@ -31033,11 +31411,11 @@ genSpecialSelectorClass(void) || (topReg == ClassReg)) { /* begin ssAllocateRequiredReg:and: */ requiredReg1 = (topReg = SendNumArgsReg); - ssAllocateRequiredRegMaskupThroughupThroughNative((1ULL << requiredReg1) | (1U << ClassReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((((requiredReg1 < 0) ? (((usqInt)(1)) >> (-requiredReg1)) : (1ULL << requiredReg1))) | ((1U << ClassReg)), simStackPtr, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr, simNativeStackPtr); } ssPush(1); popToReg(ssTop(), topReg); @@ -31270,7 +31648,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean association = getLiteral(litVarIndex); voidReceiverResultRegContainsSelf(); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); /* begin genMoveConstant:R: */ if (shouldAnnotateObjectReference(association)) { annotateobjRef(checkLiteralforInstruction(association, genoperandoperand(MoveCwR, association, ReceiverResultReg)), association); @@ -31283,7 +31661,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean # if IMMUTABILITY if (needsImmCheck) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31297,7 +31675,7 @@ genStorePopLiteralVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolean return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31358,7 +31736,7 @@ genStorePopMaybeContextReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqI # endif // IMMUTABILITY ssPop(1); /* begin ssAllocateCallReg:and: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ClassReg) | (1U << SendNumArgsReg)), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (((1U << ClassReg)) | ((1U << SendNumArgsReg))), simStackPtr, simNativeStackPtr); ssPush(1); genLoadSlotsourceRegdestReg(SenderIndex, ReceiverResultReg, TempReg); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); @@ -31403,7 +31781,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea # if IMMUTABILITY if (needsImmCheck1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ClassReg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ClassReg), simStackPtr - 1, simNativeStackPtr); ssStoreAndReplacePoptoReg(popBoolean, ClassReg); /* begin ssFlushTo: */ assert(tempsValidAndVolatileEntriesSpilled()); @@ -31417,7 +31795,7 @@ genStorePopReceiverVariableneedsStoreCheckneedsImmutabilityCheck(sqInt popBoolea return genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck1, 1); } # endif // IMMUTABILITY - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck1); } @@ -31441,7 +31819,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt assert(needsFrame); /* begin ssAllocateRequiredReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << ReceiverResultReg, simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); voidReceiverResultRegContainsSelf(); /* begin MoveMw:r:R: */ offset = frameOffsetOfTemporary(remoteTempIndex); @@ -31451,7 +31829,7 @@ genStorePopRemoteTempAtneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt # if IMMUTABILITY # endif - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1U << ReceiverResultReg); + topReg = allocateRegForStackEntryAtnotConflictingWith(0, (1U << ReceiverResultReg)); ssStorePoptoReg(popBoolean, topReg); return genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); } @@ -31637,13 +32015,13 @@ genVanillaInlinedIdenticalOrNotIf(sqInt orNot) if ((registerOrNone(ssValue(1))) != NoReg) { /* begin registerMaskFor: */ reg = (rNext1 = registerOrNone(ssValue(1))); - topRegistersMask = 1ULL << reg; + topRegistersMask = ((reg < 0) ? (((usqInt)(1)) >> (-reg)) : (1ULL << reg)); } if (rTop1 == NoReg) { rTop1 = allocateRegNotConflictingWith(topRegistersMask); } if (rNext1 == NoReg) { - rNext1 = allocateRegNotConflictingWith(1ULL << rTop1); + rNext1 = allocateRegNotConflictingWith(((rTop1 < 0) ? (((usqInt)(1)) >> (-rTop1)) : (1ULL << rTop1))); } assert(!(((rTop1 == NoReg) || (rNext1 == NoReg)))); @@ -31897,12 +32275,12 @@ liveRegisters(void) } else { /* begin registerMaskFor: */ - regsSet = 1U << ReceiverResultReg; + regsSet = (1U << ReceiverResultReg); if ((methodOrBlockNumArgs <= 2 /* numRegArgs */) && (methodOrBlockNumArgs > 0)) { - regsSet = regsSet | (1U << Arg0Reg); + regsSet = regsSet | ((1U << Arg0Reg)); if (methodOrBlockNumArgs > 1) { - regsSet = regsSet | (1U << Arg1Reg); + regsSet = regsSet | ((1U << Arg1Reg)); } } } @@ -31948,7 +32326,7 @@ marshallAbsentReceiverSendArguments(sqInt numArgs) assert(needsFrame); /* begin ssAllocateCallReg: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | (1U << ReceiverResultReg), simStackPtr, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative(CallerSavedRegisterMask | ((1U << ReceiverResultReg)), simStackPtr, simNativeStackPtr); /* begin putSelfInReceiverResultReg */ storeToReg(simSelf(), ReceiverResultReg); /* begin ssFlushTo: */ @@ -31998,13 +32376,13 @@ marshallAbsentReceiverSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { @@ -32089,13 +32467,13 @@ marshallSendArguments(sqInt numArgs) if (numArgs > 0) { if (numArgs > 1) { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 2, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 2, simNativeStackPtr); /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg1Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg1Reg), simStackPtr - 1, simNativeStackPtr); } else { /* begin ssAllocateRequiredReg:upThrough: */ - ssAllocateRequiredRegMaskupThroughupThroughNative(1U << Arg0Reg, simStackPtr - 1, simNativeStackPtr); + ssAllocateRequiredRegMaskupThroughupThroughNative((1U << Arg0Reg), simStackPtr - 1, simNativeStackPtr); } } if (numArgs > 1) { diff --git a/nsspur64src/vm/cointerp.c b/nsspur64src/vm/cointerp.c index 72ff7ee1a5..30a8b316ec 100644 --- a/nsspur64src/vm/cointerp.c +++ b/nsspur64src/vm/cointerp.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - CoInterpreter VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CoInterpreter VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -155,6 +155,7 @@ warningat(const char *s, int l) { /* ditto with line number. */ #define ExtraRootsSize 2048 #define FailImbalancedPrimitives 1 #define FalseObject 1 +#define FastCPrimitiveUseCABIFlag 4 #define FirstLinkIndex 0 #define FoxCallerSavedIP 8 #define FoxIFReceiver -40 @@ -288,12 +289,14 @@ warningat(const char *s, int l) { /* ditto with line number. */ #define PrimNumberDoPrimitive 118 #define PrimNumberExternalCall 117 #define PrimNumberFFICall 120 +#define PrimNumberFlushExternalPrimitives 570 #define PrimNumberHandlerMarker 199 #define PrimNumberHashMultiply 159 #define PrimNumberInstVarAt 73 #define PrimNumberNoContextSwitchMarker 123 #define PrimNumberShallowCopy 148 #define PrimNumberSlotAt 173 +#define PrimNumberUnoadModule 571 #define PrimNumberUnwindMarker 198 #define PrimTraceLogSize 256 #define PriorityIndex 2 @@ -323,6 +326,8 @@ warningat(const char *s, int l) { /* ditto with line number. */ #define SmallContextSlots 22 #define SPURVM 1 #define SpecialSelectors 23 +#define SpurPrimitiveAccessorDepthShift 8 +#define SpurPrimitiveFlagsMask 0xFF #define StackPageReachedButUntraced 1 #define StackPageTraced 2 #define StackPageTraceInvalid -1 @@ -479,7 +484,6 @@ extern sqInt ceCannotAssignTowithIndexvalueToAssign(sqInt immutableObject, sqInt extern sqInt ceCannotResume(void); extern void ceCheckAndMaybeRetryPrimitive(sqInt primIndex); extern void ceCheckForInterrupt(void); -extern void ceCheckProfileTick(void); extern sqInt ceContextinstVar(sqInt maybeContext, sqInt slotIndex); extern sqInt ceContextinstVarvalue(sqInt maybeMarriedContext, sqInt slotIndex, sqInt anOop); extern void ceDynamicSuperSendreceiver(sqInt cacheAddress, sqInt methodReceiver); @@ -500,6 +504,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethodOrNil); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -598,7 +603,7 @@ extern CogMethod * mframeHomeMethodExport(void); extern CogMethod * mframeHomeMethod(char *theFP); static sqInt NoDbgRegParms mframeIsBlockActivation(char *theFP); static sqInt NoDbgRegParms mframeReceiver(char *theFP); -static sqInt minimumUnusedHeadroom(void); +static sqInt NeverInline minimumUnusedHeadroom(void); extern sqInt mMethodClass(void); extern void mnuCompilationBreakpointFor(sqInt selectorOop); static sqInt NoDbgRegParms mnuMethodOrNilFor(sqInt rcvr); @@ -637,6 +642,7 @@ extern sqInt quickPrimitiveInstVarIndexFor(sqInt primIndex); extern sqInt rawHeaderOf(sqInt methodPointer); extern void rawHeaderOfput(sqInt methodOop, sqInt cogMethodOrMethodHeader); extern size_t readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squeakFileOffsetType imageOffset); +extern sqInt recordFastCCallPrimTraceForMethod(sqInt aMethodObj); extern sqInt recordPrimTraceForMethod(sqInt aMethodObj); extern void reportMinimumUnusedHeadroom(void); static sqInt NoDbgRegParms resumepreemptedYieldingIffrom(sqInt aProcess, sqInt yieldImplicitly, sqInt sourceCode); @@ -678,7 +684,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1219,7 +1224,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1283,7 +1287,7 @@ static sqInt noUnscannedEphemerons(void); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1447,7 +1451,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1604,6 +1607,8 @@ static sqInt NoDbgRegParms noMarkedContextsOnPage(StackPage *thePage); static sqInt NoDbgRegParms numSlotsOfMarriedContext(sqInt aContext); static sqInt numStkPages(void); extern sqInt objCouldBeClassObj(sqInt objOop); +static sqInt NoDbgRegParms objectequalsString(sqInt anOop, sqInt aCString); +static sqInt NoDbgRegParms objectequalsStringofSize(sqInt anOop, sqInt aCString, sqInt aCStringStrlen); extern sqInt ownVM(sqInt threadIndexAndFlags); extern sqInt penultimateLiteralOf(sqInt aMethodOop); extern sqInt popStack(void); @@ -1729,18 +1734,19 @@ extern sqInt superclassOf(sqInt classPointer); extern sqInt tempCountOf(sqInt methodPointer); extern sqInt temporaryCountOfMethodHeader(sqInt header); extern sqInt ultimateLiteralOf(sqInt aMethodOop); +static sqInt NoDbgRegParms unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(sqInt methodObj, sqInt primIndex); static sqInt NoDbgRegParms NeverInline unfollowatIndex(sqInt litVar, sqInt literalIndex); static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqInt r, sqInt b); static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); static sqInt NoDbgRegParms fieldOrSenderFPofContext(sqInt index, sqInt contextObj); static sqInt NoDbgRegParms fieldofFrame(sqInt index, char *theFP); static sqInt NoDbgRegParms isAppropriateForCopyObject(sqInt oop); +static void (*linkExternalCallerrInto(sqInt externalCallLiteral, sqInt *failPtr))() ; static double NoDbgRegParms NeverInline noInlineLoadFloatOrIntFrom(sqInt floatOrInt); static void primitiveClone(void); static void primitiveContextAt(void); @@ -1756,7 +1762,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1834,21 +1839,19 @@ _iss sqInt classTableIndex; _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt profileSemaphore; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1866,7 +1869,6 @@ _iss sqInt methodDictLinearSearchLimit; _iss sqInt pendingFinalizationSignals; _iss sqInt validatedIntegerClassFlags; _iss usqInt firstMobileObject; -_iss sqInt externalPrimitiveTableFirstFreeIndex; _iss sqInt lastCoggableInterpretedBlockMethod; _iss sqInt lastUncoggableInterpretedBlockMethod; _iss sqInt numSegInfos; @@ -1876,21 +1878,18 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; +_iss sqInt externalPrimitiveTableFirstFreeIndex; _iss sqInt firstFieldOfRememberedSet; _iss sqInt firstSegmentSize; _iss usqInt lowSpaceThreshold; @@ -1902,6 +1901,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1916,9 +1916,9 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1939,7 +1939,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1953,7 +1952,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1972,6 +1970,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2044,7 +2045,6 @@ static signed char primitiveAccessorDepthTable[MaxPrimitiveIndex + 2 /* 578 */] }; static void (*interruptCheckChain)(void) = 0; static int (*sHEAFn)() = 0; -static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); static void (*primitiveTable[MaxPrimitiveIndex + 2 /* 578 */])(void) = { /* 0 */ (void (*)(void))0, /* 1 */ primitiveAdd, @@ -2624,12 +2624,13 @@ static void (*primitiveTable[MaxPrimitiveIndex + 2 /* 578 */])(void) = { /* 575 */ primitiveHighBit, /* 576 */ (void (*)(void))0, 0 }; +static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); sqInt maxLiteralCountForCompile = MaxLiteralCountForCompile /* 60 */; sqInt checkForLeaks; sqInt breakLookupClassTag; sqInt breakSelectorLength = MinSmallInteger; -sqInt debugCallbackPath; char * primTracePluginName; +sqInt debugCallbackPath; void * displayBits; sqInt desiredEdenBytes; sqInt desiredNumStackPages; @@ -2648,7 +2649,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Newspeak Virtual Machine [ Open Smalltalk, Spur] CoInterpreterPrimitives_VMMaker.oscog-eem.2997"; +const char *interpreterVersion = "Newspeak Virtual Machine [ Open Smalltalk, Spur] CoInterpreterPrimitives_VMMaker.oscog-eem.3034"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -2693,7 +2694,7 @@ volatile int sendTrace; compilationBreakpointFor(sel); \ } \ } while (0) -#define primNumberExternalCall() null +#define primNumberExternalCall() 117 #define primTraceLogIndex(aValue) (GIV(primTraceLogIndex) = (aValue)) #define pageIndexForstackBasePlus1bytesPerPage(pointer,stkBasePlus1,pageByteSize) (((char *)(pointer) - (stkBasePlus1)) / (pageByteSize)) #define startOfMemory() heapBase @@ -14499,7 +14500,7 @@ accessorDepthForExternalPrimitiveMethod(sqInt methodObj) /* begin fetchPointer:ofObject: */ lit = longAt((methodObj + BaseHeaderSize) + (((sqInt)((usqInt)((0 + LiteralStart)) << (shiftForWord()))))); flags = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord()))))); - return (((usqInt)(((flags >> 3)))) >> 8); + return (((flags >> 3))) >> SpurPrimitiveAccessorDepthShift; } /* CoInterpreter>>#accessorDepthForPrimitiveIndex: */ @@ -15304,6 +15305,10 @@ ceActivateFailingPrimitiveMethod(sqInt aPrimitiveMethod) assert(GIV(newMethod) == aPrimitiveMethod); retryPrimitiveOnFailure(); if (!GIV(primFailCode)) { + if ((GIV(profileSemaphore) != GIV(nilObj)) + && ((ioHighResClock()) >= GIV(nextProfileTick))) { + ceTakeProfileSample(null); + } result = longAt(GIV(stackPointer)); longAtPointerput(GIV(stackPointer), GIV(instructionPointer)); /* begin push: */ @@ -15582,21 +15587,6 @@ ceCheckForInterrupt(void) returnToExecutivepostContextSwitch(0, switched); } - -/* Check if the profile timer has expired and if so take a sample. - If the primitive has failed sample the profileMethod as nil. - As a courtesy to compileInterpreterPrimitive: map NULL to nilObj. */ - - /* CoInterpreter>>#ceCheckProfileTick */ -void -ceCheckProfileTick(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if (!GIV(newMethod)) { - GIV(newMethod) = GIV(nilObj); - } - checkProfileTick(GIV(newMethod)); -} - /* CoInterpreter>>#ceContext:instVar: */ sqInt ceContextinstVar(sqInt maybeContext, sqInt slotIndex) @@ -17714,6 +17704,35 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + If aCogMethodOrNil is not nil then it is the cog method containing the + primitive call. + If aCogMethodOrNil is nil then this has been called from + primReturnEnterCogCode and newMethod + Now take a sample. c.f. checkProfileTick: */ +/* Slang type inferrence can't deal with self ceTakeProfileSample: nil... */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethodOrNil) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethodOrNil == null + ? GIV(newMethod) + : (aCogMethodOrNil->methodObject)); + forceInterruptCheck(); + /* begin zeroNextProfileTick */ + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -17820,9 +17839,10 @@ checkCodeIntegrity(sqInt gcModes) /* In Spur a primitive may fail due to encountering a forwarder. On failure, - check the accessorDepth for the primitive and if non-negative scan the - args to the depth, following any forwarders. Answer if any are found so - the prim can be retried. The primitive index is derived from newMethod. + check the accessorDepth for the + primitive and if non-negative scan the args to the depth, following any + forwarders. Answer if any are found + so the prim can be retried. The primitive index is derived from newMethod. See http://www.mirandabanda.org/cogblog/2014/02/08/primitives-and-the-partial-read-barrier/ @@ -17852,7 +17872,7 @@ checkForAndFollowForwardedPrimitiveState(void) primTraceLogIndex(GIV(primTraceLogIndex) + 1); } assert(failed()); - found1 = (scannedStackFrame = 0); + found1 = 0; /* begin primitiveIndexOfMethod:header: */ assert(isCompiledMethod(GIV(newMethod))); header = longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)(HeaderIndex) << (shiftForWord()))))); @@ -17874,6 +17894,11 @@ checkForAndFollowForwardedPrimitiveState(void) } assert((GIV(argumentCount) == (argumentCountOf(GIV(newMethod)))) || (isMetaPrimitiveIndex(primIndex))); + if (((isCalloutPrimitiveIndex(primIndex)) + || (primIndex == PrimNumberDoExternalCall)) + && (unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(GIV(newMethod), primIndex))) { + found1 = 1; + } if ((isMetaPrimitiveIndex(primIndex)) && (GIV(metaAccessorDepth) > -2)) { accessorDepth = GIV(metaAccessorDepth); @@ -17881,7 +17906,7 @@ checkForAndFollowForwardedPrimitiveState(void) else { if ((primIndex == PrimNumberExternalCall) && (primitiveFunctionPointer != primitiveExternalCall)) { - accessorDepth = (((usqInt)((((fetchPointerofObject(2, literalofMethod(0, GIV(newMethod)))) >> 3)))) >> 8); + accessorDepth = ((((fetchPointerofObject(ExternalCallLiteralFlagsIndex, literalofMethod(0, GIV(newMethod)))) >> 3))) >> SpurPrimitiveAccessorDepthShift; } else { accessorDepth = primitiveAccessorDepthTable[primIndex]; @@ -17890,11 +17915,7 @@ checkForAndFollowForwardedPrimitiveState(void) assert(saneFunctionPointerForFailureOfPrimIndex(primIndex)); assert(((accessorDepth >= -1) && (accessorDepth <= 5))); if (accessorDepth >= 0) { - if (isCalloutPrimitiveIndex(primIndex)) { - if (followForwardedObjectFieldstoDepth(longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)((0 + LiteralStart)) << (shiftForWord()))))), accessorDepth)) { - found1 = 1; - } - } + scannedStackFrame = 0; for (index = 0; index <= GIV(argumentCount); index += 1) { oop = longAt(GIV(stackPointer) + (index * BytesPerWord)); if ((!(oop & (tagMask())))) { @@ -19065,10 +19086,12 @@ flushExternalPrimitives(void) sqInt prevObj; sqInt prevPrevObj; sqInt senderOop; + sqInt senderOop1; char *sp; char *sp1; sqInt startObject; - char *theFP; + char * theFP; + char *theFP1; char * theFrame; StackPage * thePage; char *theSP; @@ -19076,17 +19099,17 @@ flushExternalPrimitives(void) sqInt top1; /* begin divorceAllFramesSuchThat: */ - theFP = GIV(framePointer); + theFP1 = GIV(framePointer); theSP = GIV(stackPointer); - if (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory()) - ? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0 - : (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) { - assert(isContext(frameContext(theFP))); - activeContext1 = longAt(theFP + FoxThisContext); - goto l12; - } - activeContext1 = marryFrameSP(theFP, theSP); - l12: /* end ensureFrameIsMarried:SP: */; + if (((((usqInt)(longAt(theFP1 + FoxMethod)))) < (startOfMemory()) + ? ((longAt(theFP1 + FoxMethod)) & MFMethodFlagHasContextFlag) != 0 + : (byteAt((theFP1 + FoxIFrameFlags) + 2)) != 0)) { + assert(isContext(frameContext(theFP1))); + activeContext1 = longAt(theFP1 + FoxThisContext); + goto l14; + } + activeContext1 = marryFrameSP(theFP1, theSP); + l14: /* end ensureFrameIsMarried:SP: */; /* begin ensurePushedInstructionPointer */ if ((((usqInt)GIV(instructionPointer))) >= (startOfMemory())) { @@ -19175,13 +19198,20 @@ flushExternalPrimitives(void) /* begin mapToBytecodePCIfActivationOfExternalMethod: */ if (isExternalMethodInPlugin(longAt((obj + BaseHeaderSize) + (((sqInt)((usqInt)(MethodIndex) << (shiftForWord()))))))) { if (((((longAt((obj + BaseHeaderSize) + (((sqInt)((usqInt)(SenderIndex) << (shiftForWord()))))))) & 7) == 1)) { - if (asserta(isWidowedContext(obj))) { - goto l15; + if (isWidowedContext(obj)) { + goto l17; + } + /* begin frameOfMarriedContext: */ + senderOop1 = longAt((obj + BaseHeaderSize) + (((sqInt)((usqInt)(SenderIndex) << (shiftForWord()))))); + assert((((senderOop1) & 7) == 1)); + theFP = pointerForOop(senderOop1 - 1); + if (!((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory()))) { + goto l17; } } ensureContextHasBytecodePC(obj); } - l15: /* end mapToBytecodePCIfActivationOfExternalMethod: */; + l17: /* end mapToBytecodePCIfActivationOfExternalMethod: */; } } } @@ -19693,24 +19723,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -19810,38 +19822,25 @@ frameReceiver(char *theFP) void (*functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(sqInt methodObj, sqInt primitiveIndex, sqInt *flagsPtr))(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - void (*addr)(); sqInt firstBytecode; sqInt firstLiteral; sqInt flags; - sqInt fmt; - sqInt fmt1; static void *function = (void *)-1; - sqInt functionLength; - sqInt functionName; void (*functionPointer)(void); void (*functionPointer1)(void); sqInt header; sqInt header1; - sqInt i; sqInt index; - sqInt index1; sqInt lit; sqInt lit1; - sqInt metadata; - sqInt moduleLength; - sqInt moduleName; - usqInt numSlots; - usqInt numSlots1; - usqInt numSlots11; - usqInt numSlots2; + sqInt metadataFlags; sqInt primIdx; sqInt shiftedMetadataFlags; sqInt targetFunctionIndex; - metadata = 0; + flags = 0; if (!(flagsPtr == null)) { - flagsPtr[0] = (primitivePropertyFlags(primitiveIndex)); + flagsPtr[0] = ((flags = primitivePropertyFlags(primitiveIndex))); } /* begin functionPointerFor:inClass: */ functionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex @@ -19883,120 +19882,25 @@ void (*functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto( targetFunctionIndex = longAt((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))); assert((((targetFunctionIndex) & 7) == 1)); if (((targetFunctionIndex >> 3)) == 0) { - /* begin linkExternalCall:ifFail: */ - moduleName = longAt((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralModuleNameIndex) << (shiftForWord()))))); - if (moduleName == GIV(nilObj)) { - moduleLength = 0; - } - else { - if (!(((!(moduleName & (tagMask())))) - && (((((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - goto l14; - } - /* begin lengthOf:format: */ - fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots1 = byteAt(moduleName + 7); - numSlots = (numSlots1 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(moduleName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots1); - if (fmt <= 5 /* ephemeronFormat */) { - moduleLength = numSlots; - goto l8; - } - if (fmt >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - moduleLength = (numSlots << (shiftForWord())) - (fmt & 7); - goto l8; - } - if (fmt >= (firstShortFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 1)) - (fmt & 3); - goto l8; - } - if (fmt >= (firstLongFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 2)) - (fmt & 1); - goto l8; - } - if (fmt == (sixtyFourBitIndexableFormat())) { - moduleLength = numSlots; - goto l8; - } - moduleLength = 0; - l8: /* end lengthOf:format: */; - } - /* begin fetchPointer:ofObject: */ - functionName = longAt((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFunctionNameIndex) << (shiftForWord()))))); - if (!(((!(functionName & (tagMask())))) - && (((((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - goto l14; - } - /* begin lengthOf:format: */ - fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots11 = byteAt(functionName + 7); - numSlots2 = (numSlots11 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(functionName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots11); - if (fmt1 <= 5 /* ephemeronFormat */) { - functionLength = numSlots2; - goto l10; - } - if (fmt1 >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - functionLength = (numSlots2 << (shiftForWord())) - (fmt1 & 7); - goto l10; - } - if (fmt1 >= (firstShortFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 1)) - (fmt1 & 3); - goto l10; - } - if (fmt1 >= (firstLongFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 2)) - (fmt1 & 1); - goto l10; - } - if (fmt1 == (sixtyFourBitIndexableFormat())) { - functionLength = numSlots2; - goto l10; - } - functionLength = 0; - l10: /* end lengthOf:format: */; - addr = ioLoadExternalFunctionOfLengthFromModuleOfLengthMetadataInto(functionName + BaseHeaderSize, functionLength, moduleName + BaseHeaderSize, moduleLength, (&metadata)); - if (addr == 0) { - index = -1; - } - else { + linkExternalCallerrInto(firstLiteral, null); + } + lit = firstLiteral; + metadataFlags = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord()))))); + if ((((metadataFlags) & 7) == 1)) { + shiftedMetadataFlags = (((sqInt)((usqInt)((((metadataFlags >> 3)) & SpurPrimitiveFlagsMask)) << PrimitiveMetadataFlagsShift))); + if (shiftedMetadataFlags > 0) { - /* add the function to the external primitive table */ - /* begin addToExternalPrimitiveTable: */ - for (i = GIV(externalPrimitiveTableFirstFreeIndex); i < MaxExternalPrimitiveTableSize; i += 1) { - if ((externalPrimitiveTable[i]) == 0) { - externalPrimitiveTable[i] = (((void *) addr)); - index = (GIV(externalPrimitiveTableFirstFreeIndex) = i + 1); - goto l13; - } - } - index = 0; - l13: /* end addToExternalPrimitiveTable: */; - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(firstLiteral))); - longAtput((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord())))), (((usqInt)metadata << 3) | 1)); + /* Intentionally clear all other flags if there are Spur metadata flags... */ + flags = shiftedMetadataFlags; } - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(firstLiteral))); - longAtput((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), (((usqInt)index << 3) | 1)); - rewriteMethodCacheEntryForExternalPrimitiveToFunction((index >= 0 - ? addr - : 0)); - l14: /* end linkExternalCall:ifFail: */; } - lit = firstLiteral; - flags = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord()))))); - if ((((flags) & 7) == 1)) { - shiftedMetadataFlags = (((sqInt)((usqInt)((((flags >> 3)) & 0xFF)) << PrimitiveMetadataFlagsShift))); - flagsPtr[0] = ((flagsPtr[0]) | shiftedMetadataFlags); + if (objectequalsString(longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))), primitiveProfileSemaphore)) { + flags = flags | PrimCallMayEndureCodeCompaction; + } + if (GIV(profileSemaphore) != GIV(nilObj)) { + flags = flags | PrimCallCollectsProfileSamples; } + flagsPtr[0] = flags; /* begin functionForPrimitiveExternalCall: */ if (!((literalCountOfMethodHeader(methodHeaderOf(methodObj))) > 0)) { return ((void (*)(void)) primitiveExternalCall); @@ -20008,13 +19912,13 @@ void (*functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto( && ((lengthOfformat(lit1, (((usqInt)((longAt(lit1)))) >> (formatShift())) & (formatMask()))) == 4))) { return ((void (*)(void)) primitiveExternalCall); } - index1 = longAt((lit1 + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))); - if (!(((((index1) & 7) == 1)) - && ((((index1 = (index1 >> 3))) > 0) - && (index1 <= MaxExternalPrimitiveTableSize)))) { + index = longAt((lit1 + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))); + if (!(((((index) & 7) == 1)) + && ((((index = (index >> 3))) > 0) + && (index <= MaxExternalPrimitiveTableSize)))) { return ((void (*)(void)) primitiveExternalCall); } - functionPointer1 = externalPrimitiveTable[index1 - 1]; + functionPointer1 = externalPrimitiveTable[index - 1]; if (functionPointer1 == 0) { return ((void (*)(void)) primitiveExternalCall); } @@ -20441,8 +20345,13 @@ interpretMethodFromMachineCode(void) compute a bytecode pc and hence may provoke a code compaction. Hence primitive invocation from these primitives must use a static return address - (cePrimReturnEnterCogCode:). - */ + (cePrimReturnEnterCogCode:). Note that the process switch primitives may + also provoke a code compaction, which + happens when switching to a process whose top context has a machine code + pc but + the method is no longer in the code cache. However, in this case they are + switching process and don't go through the normal return. So we don't + include them here. */ /* CoInterpreter>>#isCodeCompactingPrimitiveIndex: */ static sqInt NoDbgRegParms @@ -20450,7 +20359,9 @@ isCodeCompactingPrimitiveIndex(sqInt primIndex) { return (primIndex == PrimNumberInstVarAt) || ((primIndex == PrimNumberShallowCopy) - || (primIndex == PrimNumberSlotAt)); + || ((primIndex == PrimNumberSlotAt) + || ((primIndex == PrimNumberFlushExternalPrimitives) + || (primIndex == PrimNumberUnoadModule)))); } /* CoInterpreter>>#isCogMethodReference: */ @@ -21765,10 +21676,11 @@ methodHasCogMethod(sqInt aMethodOop) static sqInt NoDbgRegParms NeverInline methodHasPrimitiveInPrimTracePlugin(sqInt aMethodObj) { - sqInt fmt; + sqInt aCStringStrlen; sqInt lit; - sqInt nameLength; + sqInt ok; sqInt pluginName; + sqInt size; if (!(((primitiveIndexOf(aMethodObj)) == PrimNumberExternalCall) && ((literalCountOfMethodHeader(methodHeaderOf(aMethodObj))) > 0))) { @@ -21787,12 +21699,13 @@ methodHasPrimitiveInPrimTracePlugin(sqInt aMethodObj) && (((((usqInt)((longAt(pluginName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { return 0; } - /* begin numBytesOfBytes: */ - fmt = (((usqInt)((longAt(pluginName)))) >> (formatShift())) & (formatMask()); - assert(fmt >= (firstByteFormat())); - nameLength = ((numSlotsOf(pluginName)) << (shiftForWord())) - (fmt & 7); - return ((strncmp(primTracePluginName, firstIndexableField(pluginName), nameLength)) == 0) - && ((strlen(primTracePluginName)) == nameLength); + /* begin object:equalsString:ofSize: */ + aCStringStrlen = strlen(primTracePluginName); + ok = (((!(pluginName & (tagMask())))) + && (((((usqInt)((longAt(pluginName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(pluginName))) == aCStringStrlen) + && ((strncmp(primTracePluginName, firstIndexableField(pluginName), aCStringStrlen)) == 0)); + return ok; } /* CoInterpreter>>#methodNeedsLargeContext: */ @@ -21935,13 +21848,13 @@ mframeReceiver(char *theFP) checking that there is enough headroom allocated in stack pages. */ /* CoInterpreter>>#minimumUnusedHeadroom */ -static sqInt +static sqInt NeverInline minimumUnusedHeadroom(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt i; int minUnused; char *p; - StackPage *page; + StackPage * page; int unused; minUnused = (((stackPageAt(0))->baseAddress)) - (((stackPageAt(0))->lastAddress)); @@ -22827,7 +22740,7 @@ primitivePropertyFlags(sqInt primIndex) /* begin primitivePropertyFlagsForSpur: */ if (primIndex == PrimNumberHashMultiply) { - return PrimCallOnSmalltalkStack; + return PrimCallOnSmalltalkStack + FastCPrimitiveUseCABIFlag; } baseFlags = PrimCallNeedsPrimitiveFunction + PrimCallNeedsNewMethod; if (GIV(profileSemaphore) != GIV(nilObj)) { @@ -23947,7 +23860,7 @@ readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squea /* default */ GIV(thisClassIndex) = 5; - for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (lengthOfformat(classArrayClass, (((usqInt)((longAt(classArrayClass)))) >> (formatShift())) & (formatMask()))); i1 <= iLimiT; i1 += 1) { + for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (numSlotsOf(classArrayClass)); i1 <= iLimiT; i1 += 1) { if ((longAt((classArrayClass + BaseHeaderSize) + (((sqInt)((usqInt)((i1 - 1)) << (shiftForWord())))))) == classArrayObj) { GIV(thisClassIndex) = i1 - 1; } @@ -23955,13 +23868,10 @@ readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squea /* default */ GIV(classNameIndex) = 6; - for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (lengthOfformat(classArrayObj, (((usqInt)((longAt(classArrayObj)))) >> (formatShift())) & (formatMask()))); i1 <= iLimiT; i1 += 1) { + for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (numSlotsOf(classArrayObj)); i1 <= iLimiT; i1 += 1) { /* begin fetchPointer:ofObject: */ oop = longAt((classArrayObj + BaseHeaderSize) + (((sqInt)((usqInt)((i1 - 1)) << (shiftForWord()))))); - if ((((!(oop & (tagMask())))) - && (((((usqInt)((longAt(oop)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) - && (((lengthOfformat(oop, (((usqInt)((longAt(oop)))) >> (formatShift())) & (formatMask()))) == 5) - && ((strncmp("Array", firstFixedField(oop), 5)) == 0))) { + if (objectequalsStringofSize(oop, "Array", strlen("Array"))) { GIV(classNameIndex) = i1 - 1; } } @@ -23988,6 +23898,23 @@ readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squea } +/* This is a little elaborate. The primTraceLog is only useful if it is not + full of noise. + To reduce noise when debugging a specific plugin we allow a plugin name to + be specified and will only generate the primTraceLog code for primitives + in that plugin. */ + + /* CoInterpreter>>#recordFastCCallPrimTraceForMethod: */ +sqInt +recordFastCCallPrimTraceForMethod(sqInt aMethodObj) +{ + return (recordFastCCallPrimTrace()) + && ((primTracePluginName == null + ? 1 + : methodHasPrimitiveInPrimTracePlugin(aMethodObj))); +} + + /* This is a little elaborate. The primTraceLog is only useful if it is not full of noise. To reduce noise when debugging a specific plugin we allow a plugin name to @@ -26457,56 +26384,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26819,14 +26696,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26838,28 +26710,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -30432,7 +30297,7 @@ primitiveCalloutToFFI(void) } } else { - primitiveCallout(); + dispatchFunctionPointer(primitiveCallout); } } @@ -34439,26 +34304,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -37115,15 +36982,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -37141,15 +37003,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -37173,39 +37030,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -41696,7 +41532,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -49133,7 +48969,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -50295,17 +50131,18 @@ findLargestFreeChunk(void) void findStringBeginningWith(char *aCString) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt aCStringStrlen; sqInt address; - sqInt cssz; sqInt followingWord; usqInt followingWordAddress; usqInt numSlots; sqInt obj1; sqInt prevObj; sqInt prevPrevObj; + sqInt size; sqInt startObject; - cssz = strlen(aCString); + aCStringStrlen = strlen(aCString); /* begin allObjectsDo: */ address = (GIV(pastSpaceStart) > (((pastSpace()).start)) ? ((pastSpace()).start) @@ -50326,9 +50163,10 @@ findStringBeginningWith(char *aCString) if (!(oopisLessThan(obj1, GIV(endOfMemory)))) break; assert((long64At(obj1)) != 0); if (isEnumerableObject(obj1)) { - if ((((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())) - && (((lengthOfformat(obj1, (((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask()))) >= cssz) - && ((strncmp(aCString, pointerForOop(obj1 + BaseHeaderSize), cssz)) == 0))) { + if ((((!(obj1 & (tagMask())))) + && (((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(obj1))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(obj1), aCStringStrlen)) == 0))) { printHex(obj1); /* begin space */ putchar(' '); @@ -50370,17 +50208,18 @@ findStringBeginningWith(char *aCString) void findString(char *aCString) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt aCStringStrlen; sqInt address; - sqInt cssz; sqInt followingWord; usqInt followingWordAddress; usqInt numSlots; sqInt obj1; sqInt prevObj; sqInt prevPrevObj; + sqInt size; sqInt startObject; - cssz = strlen(aCString); + aCStringStrlen = strlen(aCString); /* begin allObjectsDo: */ address = (GIV(pastSpaceStart) > (((pastSpace()).start)) ? ((pastSpace()).start) @@ -50401,9 +50240,10 @@ findString(char *aCString) if (!(oopisLessThan(obj1, GIV(endOfMemory)))) break; assert((long64At(obj1)) != 0); if (isEnumerableObject(obj1)) { - if ((((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())) - && (((lengthOfformat(obj1, (((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask()))) == cssz) - && ((strncmp(aCString, pointerForOop(obj1 + BaseHeaderSize), cssz)) == 0))) { + if ((((!(obj1 & (tagMask())))) + && (((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(obj1))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(obj1), aCStringStrlen)) == 0))) { printHex(obj1); /* begin space */ putchar(' '); @@ -52572,14 +52412,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -54859,8 +54691,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -54999,38 +54829,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -55683,7 +55481,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -56518,8 +56316,8 @@ outOfPlaceBecomeandcopyHashFlag(sqInt obj1, sqInt obj2, sqInt copyHashFlag) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; sqInt classIndex1; - usqInt clone1; - usqInt clone2; + sqInt clone1; + sqInt clone2; sqInt format; sqInt format1; sqInt hash; @@ -58693,7 +58491,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj1))); contextSize = (sp >> 3); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -58726,7 +58524,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -61919,10 +61717,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -64013,33 +63811,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -64112,10 +63883,7 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) if ((GIV(profileProcess) != GIV(nilObj)) || ((GIV(nextProfileTick) > 0) && ((ioHighResClock()) >= GIV(nextProfileTick)))) { - - /* Take a sample (if not already done so) for the profiler if it is active. This - must be done before any of the synchronousSignals below or else we will - attribute a pause in ioRelinquishProcessor to the newly activated process. */ + /* begin zeroNextProfileTick */ GIV(nextProfileTick) = 0; if (GIV(profileProcess) == GIV(nilObj)) { /* begin activeProcess */ @@ -64130,9 +63898,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -64538,6 +64303,7 @@ checkProfileTick(sqInt aPrimitiveMethod) GIV(profileMethod) = GIV(nilObj); } forceInterruptCheck(); + /* begin zeroNextProfileTick */ GIV(nextProfileTick) = 0; } } @@ -64665,12 +64431,13 @@ checkStackPointerIndexForFrame(char *theFP) static sqInt NoDbgRegParms classNameOfIs(sqInt aClass, char *className) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt fmt; sqInt i; sqInt length; sqInt name; char *srcName; - if ((lengthOfformat(aClass, (((usqInt)((longAt(aClass)))) >> (formatShift())) & (formatMask()))) <= GIV(classNameIndex)) { + if ((numSlotsOf(aClass)) <= GIV(classNameIndex)) { return 0; } /* begin fetchPointer:ofObject: */ @@ -64679,7 +64446,10 @@ classNameOfIs(sqInt aClass, char *className) && (((((usqInt)((longAt(name)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { return 0; } - length = stSizeOf(name); + /* begin numBytesOfBytes: */ + fmt = (((usqInt)((longAt(name)))) >> (formatShift())) & (formatMask()); + assert(fmt >= (firstByteFormat())); + length = ((numSlotsOf(name)) << (shiftForWord())) - (fmt & 7); srcName = ((char *) (arrayValueOf(name))); for (i = 0; i < length; i += 1) { if (!((srcName[i]) == (className[i]))) { @@ -69896,23 +69666,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -70789,6 +70542,33 @@ objCouldBeClassObj(sqInt objOop) && (((((longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(InstanceSpecificationIndex) << (shiftForWord()))))))) & 7) == 1))))))); } + /* StackInterpreter>>#object:equalsString: */ +static sqInt NoDbgRegParms +objectequalsString(sqInt anOop, sqInt aCString) +{ + sqInt aCStringStrlen; + sqInt size; + + /* begin object:equalsString:ofSize: */ + aCStringStrlen = strlen(aCString); + return (((!(anOop & (tagMask())))) + && (((((usqInt)((longAt(anOop)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(anOop))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(anOop), aCStringStrlen)) == 0)); +} + + /* StackInterpreter>>#object:equalsString:ofSize: */ +static sqInt NoDbgRegParms +objectequalsStringofSize(sqInt anOop, sqInt aCString, sqInt aCStringStrlen) +{ + sqInt size; + + return (((!(anOop & (tagMask())))) + && (((((usqInt)((longAt(anOop)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(anOop))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(anOop), aCStringStrlen)) == 0)); +} + /* This is the entry-point for plugins and primitives that wish to reacquire the VM after having @@ -74017,8 +73797,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -74047,18 +73827,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -74637,7 +74419,7 @@ retryPrimitiveOnFailure(void) primTraceLogIndex(GIV(primTraceLogIndex) + 1); } assert(failed()); - found1 = (scannedStackFrame = 0); + found1 = 0; /* begin primitiveIndexOfMethod:header: */ assert(isCompiledMethod(GIV(newMethod))); header = longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)(HeaderIndex) << (shiftForWord()))))); @@ -74659,6 +74441,11 @@ retryPrimitiveOnFailure(void) } assert((GIV(argumentCount) == (argumentCountOf(GIV(newMethod)))) || (isMetaPrimitiveIndex(primIndex))); + if (((isCalloutPrimitiveIndex(primIndex)) + || (primIndex == PrimNumberDoExternalCall)) + && (unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(GIV(newMethod), primIndex))) { + found1 = 1; + } if ((isMetaPrimitiveIndex(primIndex)) && (GIV(metaAccessorDepth) > -2)) { accessorDepth = GIV(metaAccessorDepth); @@ -74666,7 +74453,7 @@ retryPrimitiveOnFailure(void) else { if ((primIndex == PrimNumberExternalCall) && (primitiveFunctionPointer != primitiveExternalCall)) { - accessorDepth = (((usqInt)((((fetchPointerofObject(2, literalofMethod(0, GIV(newMethod)))) >> 3)))) >> 8); + accessorDepth = ((((fetchPointerofObject(ExternalCallLiteralFlagsIndex, literalofMethod(0, GIV(newMethod)))) >> 3))) >> SpurPrimitiveAccessorDepthShift; } else { accessorDepth = primitiveAccessorDepthTable[primIndex]; @@ -74675,11 +74462,7 @@ retryPrimitiveOnFailure(void) assert(saneFunctionPointerForFailureOfPrimIndex(primIndex)); assert(((accessorDepth >= -1) && (accessorDepth <= 5))); if (accessorDepth >= 0) { - if (isCalloutPrimitiveIndex(primIndex)) { - if (followForwardedObjectFieldstoDepth(longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)((0 + LiteralStart)) << (shiftForWord()))))), accessorDepth)) { - found1 = 1; - } - } + scannedStackFrame = 0; for (index = 0; index <= GIV(argumentCount); index += 1) { oop = longAt(GIV(stackPointer) + (index * BytesPerWord)); if ((!(oop & (tagMask())))) { @@ -77037,6 +76820,42 @@ ultimateLiteralOf(sqInt aMethodOop) } +/* Follow the first literal of either a primitiveCallout or + primitiveExternalCall primitive method. This + will be an ExternalFunction for primitiveCallout or a four element Array + for primitiveExternalCall. + This is here to avoid following all the literals in a method, which would + be slow. Remember + forwarders are unlikely, so we only want to follow what is necessary, and + for an FFI call or + external primitive only the first literal is salient. */ + + /* StackInterpreter>>#unfollowFirstLiteralOfMaybeCalloutMethod:primitiveIndex: */ +static sqInt NoDbgRegParms +unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(sqInt methodObj, sqInt primIndex) +{ + sqInt firstLiteral; + sqInt found; + + + /* inlined self literal: 0 ofMethod: methodObj for clarity... */ + found = 0; + /* begin fetchPointer:ofObject: */ + firstLiteral = longAt((methodObj + BaseHeaderSize) + (((sqInt)((usqInt)(LiteralStart) << (shiftForWord()))))); + if (((!(firstLiteral & (tagMask())))) + && ((!((longAt(firstLiteral)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { + found = 1; + firstLiteral = fixFollowedFieldofObjectwithInitialValue(LiteralStart, methodObj, firstLiteral); + } + if (followForwardedObjectFieldstoDepth(firstLiteral, (primIndex == PrimNumberFFICall + ? (primitiveAccessorDepthTable[primIndex]) - 1 + : 0))) { + found = 1; + } + return found; +} + + /* So rare it mustn't bulk up the common path */ /* StackInterpreter>>#unfollow:atIndex: */ @@ -77172,22 +76991,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -77570,6 +77373,87 @@ isAppropriateForCopyObject(sqInt oop) return 1; } + +/* The function has not been loaded yet. Fetch module and function name. */ + + /* StackInterpreterPrimitives>>#linkExternalCall:errInto: */ +static void (*linkExternalCallerrInto(sqInt externalCallLiteral, sqInt *failPtr))() + +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + void (*addr)(); + sqInt fmt; + sqInt fmt1; + sqInt functionLength; + sqInt functionName; + sqInt i; + sqInt index; + sqInt metadata; + sqInt moduleLength; + sqInt moduleName; + + metadata = 0; + /* begin fetchPointer:ofObject: */ + moduleName = longAt((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralModuleNameIndex) << (shiftForWord()))))); + if (moduleName == GIV(nilObj)) { + moduleLength = 0; + } + else { + if (!(((!(moduleName & (tagMask())))) + && (((((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { + if (!(failPtr == null)) { + failPtr[0] = PrimErrBadMethod; + } + return 0; + } + /* begin numBytesOfBytes: */ + fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); + assert(fmt >= (firstByteFormat())); + moduleLength = ((numSlotsOf(moduleName)) << (shiftForWord())) - (fmt & 7); + } + /* begin fetchPointer:ofObject: */ + functionName = longAt((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFunctionNameIndex) << (shiftForWord()))))); + if (!(((!(functionName & (tagMask())))) + && (((((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { + if (!(failPtr == null)) { + failPtr[0] = PrimErrBadMethod; + } + return 0; + } + /* begin numBytesOfBytes: */ + fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); + assert(fmt1 >= (firstByteFormat())); + functionLength = ((numSlotsOf(functionName)) << (shiftForWord())) - (fmt1 & 7); + addr = ioLoadExternalFunctionOfLengthFromModuleOfLengthMetadataInto(functionName + BaseHeaderSize, functionLength, moduleName + BaseHeaderSize, moduleLength, (&metadata)); + if (addr == 0) { + index = -1; + } + else { + + /* add the function to the external primitive table */ + assert(((((metadata) >> SpurPrimitiveAccessorDepthShift) >= -1) && (((metadata) >> SpurPrimitiveAccessorDepthShift) <= 5))); + /* begin addToExternalPrimitiveTable: */ + for (i = GIV(externalPrimitiveTableFirstFreeIndex); i < MaxExternalPrimitiveTableSize; i += 1) { + if ((externalPrimitiveTable[i]) == 0) { + externalPrimitiveTable[i] = (((void *) addr)); + index = (GIV(externalPrimitiveTableFirstFreeIndex) = i + 1); + goto l1; + } + } + index = 0; + l1: /* end addToExternalPrimitiveTable: */; + /* begin storePointerUnchecked:ofObject:withValue: */ + assert(!(isOopForwarded(externalCallLiteral))); + longAtput((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord())))), (((usqInt)metadata << 3) | 1)); + } + /* begin storePointerUnchecked:ofObject:withValue: */ + assert(!(isOopForwarded(externalCallLiteral))); + longAtput((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), (((usqInt)index << 3) | 1)); + rewriteMethodCacheEntryForExternalPrimitiveToFunction((index >= 0 + ? addr + : 0)); + return addr; +} + /* StackInterpreterPrimitives>>#noInlineLoadFloatOrIntFrom: */ static double NoDbgRegParms NeverInline noInlineLoadFloatOrIntFrom(sqInt floatOrInt) @@ -78532,10 +78416,6 @@ primitiveDoNamedPrimitiveWithArgs(void) sqInt moduleName; sqInt nItems; usqInt numSlots; - usqInt numSlots1; - usqInt numSlots11; - usqInt numSlots2; - usqInt numSlots3; sqInt object; sqInt object1; sqInt object2; @@ -78647,37 +78527,10 @@ primitiveDoNamedPrimitiveWithArgs(void) GIV(primFailCode) = 1; } } - /* begin lengthOf:format: */ + /* begin numBytesOfBytes: */ fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots1 = byteAt(moduleName + 7); - numSlots2 = (numSlots1 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(moduleName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots1); - if (fmt <= 5 /* ephemeronFormat */) { - moduleLength = numSlots2; - goto l15; - } - if (fmt >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - moduleLength = (numSlots2 << (shiftForWord())) - (fmt & 7); - goto l15; - } - if (fmt >= (firstShortFormat())) { - moduleLength = (numSlots2 << ((shiftForWord()) - 1)) - (fmt & 3); - goto l15; - } - if (fmt >= (firstLongFormat())) { - moduleLength = (numSlots2 << ((shiftForWord()) - 2)) - (fmt & 1); - goto l15; - } - if (fmt == (sixtyFourBitIndexableFormat())) { - moduleLength = numSlots2; - goto l15; - } - moduleLength = 0; - l15: /* end lengthOf:format: */; + assert(fmt >= (firstByteFormat())); + moduleLength = ((numSlotsOf(moduleName)) << (shiftForWord())) - (fmt & 7); } /* begin fetchPointer:ofObject: */ functionName = longAt((spec + BaseHeaderSize) + (1U << (shiftForWord()))); @@ -78691,37 +78544,10 @@ primitiveDoNamedPrimitiveWithArgs(void) GIV(primFailCode) = 1; } } - /* begin lengthOf:format: */ + /* begin numBytesOfBytes: */ fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots11 = byteAt(functionName + 7); - numSlots3 = (numSlots11 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(functionName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots11); - if (fmt1 <= 5 /* ephemeronFormat */) { - functionLength = numSlots3; - goto l20; - } - if (fmt1 >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - functionLength = (numSlots3 << (shiftForWord())) - (fmt1 & 7); - goto l20; - } - if (fmt1 >= (firstShortFormat())) { - functionLength = (numSlots3 << ((shiftForWord()) - 1)) - (fmt1 & 3); - goto l20; - } - if (fmt1 >= (firstLongFormat())) { - functionLength = (numSlots3 << ((shiftForWord()) - 2)) - (fmt1 & 1); - goto l20; - } - if (fmt1 == (sixtyFourBitIndexableFormat())) { - functionLength = numSlots3; - goto l20; - } - functionLength = 0; - l20: /* end lengthOf:format: */; + assert(fmt1 >= (firstByteFormat())); + functionLength = ((numSlotsOf(functionName)) << (shiftForWord())) - (fmt1 & 7); if (GIV(primFailCode)) { /* begin primitiveFailFor: */ (GIV(primFailCode) = -3); @@ -79029,24 +78855,10 @@ static void primitiveExternalCall(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt addr; - void (*addr1)(); - sqInt fmt; - sqInt fmt1; - sqInt functionLength; - sqInt functionName; - sqInt i; sqInt index; - sqInt index1; sqInt lit; - sqInt metadata; - sqInt moduleLength; - sqInt moduleName; - usqInt numSlots; - usqInt numSlots1; - usqInt numSlots11; - usqInt numSlots2; + sqInt reasonCode; - metadata = 0; if (!((((!(GIV(newMethod) & (tagMask())))) && (((((usqInt)((longAt(GIV(newMethod))))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat()))) && (((literalCountOf(GIV(newMethod))) > 0) @@ -79096,126 +78908,14 @@ primitiveExternalCall(void) /* begin storePointerUnchecked:ofObject:withValue: */ assert(!(isOopForwarded(lit))); longAtput((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), ConstZero); - /* begin linkExternalCall:ifFail: */ - moduleName = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralModuleNameIndex) << (shiftForWord()))))); - if (moduleName == GIV(nilObj)) { - moduleLength = 0; - } - else { - if (!(((!(moduleName & (tagMask())))) - && (((((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - /* begin primitiveFailFor: */ - (GIV(primFailCode) = PrimErrBadMethod); - return; - addr = ((void (*)()) 0); - goto l13; - } - /* begin lengthOf:format: */ - fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots1 = byteAt(moduleName + 7); - numSlots = (numSlots1 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(moduleName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots1); - if (fmt <= 5 /* ephemeronFormat */) { - moduleLength = numSlots; - goto l8; - } - if (fmt >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - moduleLength = (numSlots << (shiftForWord())) - (fmt & 7); - goto l8; - } - if (fmt >= (firstShortFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 1)) - (fmt & 3); - goto l8; - } - if (fmt >= (firstLongFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 2)) - (fmt & 1); - goto l8; - } - if (fmt == (sixtyFourBitIndexableFormat())) { - moduleLength = numSlots; - goto l8; - } - moduleLength = 0; - l8: /* end lengthOf:format: */; - } - /* begin fetchPointer:ofObject: */ - functionName = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFunctionNameIndex) << (shiftForWord()))))); - if (!(((!(functionName & (tagMask())))) - && (((((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - /* begin primitiveFailFor: */ - (GIV(primFailCode) = PrimErrBadMethod); - return; - addr = ((void (*)()) 0); - goto l13; - } - /* begin lengthOf:format: */ - fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots11 = byteAt(functionName + 7); - numSlots2 = (numSlots11 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(functionName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots11); - if (fmt1 <= 5 /* ephemeronFormat */) { - functionLength = numSlots2; - goto l10; - } - if (fmt1 >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - functionLength = (numSlots2 << (shiftForWord())) - (fmt1 & 7); - goto l10; - } - if (fmt1 >= (firstShortFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 1)) - (fmt1 & 3); - goto l10; - } - if (fmt1 >= (firstLongFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 2)) - (fmt1 & 1); - goto l10; - } - if (fmt1 == (sixtyFourBitIndexableFormat())) { - functionLength = numSlots2; - goto l10; - } - functionLength = 0; - l10: /* end lengthOf:format: */; - addr1 = ioLoadExternalFunctionOfLengthFromModuleOfLengthMetadataInto(functionName + BaseHeaderSize, functionLength, moduleName + BaseHeaderSize, moduleLength, (&metadata)); - if (addr1 == 0) { - index1 = -1; - } - else { - - /* add the function to the external primitive table */ - /* begin addToExternalPrimitiveTable: */ - for (i = GIV(externalPrimitiveTableFirstFreeIndex); i < MaxExternalPrimitiveTableSize; i += 1) { - if ((externalPrimitiveTable[i]) == 0) { - externalPrimitiveTable[i] = (((void *) addr1)); - index1 = (GIV(externalPrimitiveTableFirstFreeIndex) = i + 1); - goto l12; - } - } - index1 = 0; - l12: /* end addToExternalPrimitiveTable: */; - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(lit))); - longAtput((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord())))), (((usqInt)metadata << 3) | 1)); - } - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(lit))); - longAtput((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), (((usqInt)index1 << 3) | 1)); - rewriteMethodCacheEntryForExternalPrimitiveToFunction((index1 >= 0 - ? addr1 - : 0)); - addr = addr1; - l13: /* end linkExternalCall:ifFail: */; + addr = linkExternalCallerrInto(lit, (&GIV(primFailCode))); if (addr == 0) { assert((fetchPointerofObject(ExternalCallLiteralFlagsIndex, lit)) == ConstZero); /* begin primitiveFailFor: */ - (GIV(primFailCode) = PrimErrNotFound); + reasonCode = (GIV(primFailCode) == 0 + ? PrimErrNotFound + : GIV(primFailCode)); + (GIV(primFailCode) = reasonCode); return; } /* begin callExternalPrimitive: */ @@ -79801,74 +79501,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -80907,6 +80539,7 @@ primitiveStoreStackp(void) 74 maximum pause time due to segment allocation 75 whether the arithmetic primitives perform conversion in case of mixed SmallInteger/Float (true) or fail (false) + 76 the minimum unused headroom in all stack pages; Cog VMs only Note: Thanks to Ian Piumarta for this primitive. */ @@ -81002,11 +80635,12 @@ primitiveVMParameter(void) sqInt valuePointer61; sqInt valuePointer62; sqInt valuePointer63; + sqInt valuePointer64; sqInt valuePointer7; sqInt valuePointer8; sqInt valuePointer9; - paramsArraySize = 75; + paramsArraySize = 76; if (GIV(argumentCount) == 0) { /* begin primitiveAllVMParameters: */ result1 = instantiateClassindexableSize(splObj(ClassArray), paramsArraySize); @@ -81324,6 +80958,10 @@ primitiveVMParameter(void) : GIV(falseObj)); assert(!(isOopForwarded(result1))); longAtput((result1 + BaseHeaderSize) + (74U << (shiftForWord())), valuePointer63); + /* begin storePointerUnchecked:ofObject:withValue: */ + valuePointer64 = (((usqInt)(minimumUnusedHeadroom()) << 3) | 1); + assert(!(isOopForwarded(result1))); + longAtput((result1 + BaseHeaderSize) + (75U << (shiftForWord())), valuePointer64); beRootIfOld(result1); /* begin methodReturnValue: */ assert(!((failed()))); @@ -81361,43 +80999,43 @@ primitiveVMParameter(void) switch (index) { case 1: result = positiveMachineIntegerFor(totalBytesInSegments()); - goto l86; + goto l87; break; case 2: result = (((usqInt)((GIV(freeStart) - (((eden()).start))) + (GIV(pastSpaceStart) - (((pastSpace()).start)))) << 3) | 1); - goto l86; + goto l87; break; case 3: result = positiveMachineIntegerFor((newSpaceCapacity()) + (totalBytesInSegments())); - goto l86; + goto l87; break; case 6: result = (((usqInt)(((sqInt)(((scavengerTenuringThreshold()) * (((GIV(pastSpace).limit)) - ((GIV(pastSpace).start)))) / (8 * BytesPerOop)))) << 3) | 1); - goto l86; + goto l87; break; case 7: result = (((usqInt)GIV(statFullGCs) << 3) | 1); - goto l86; + goto l87; break; case 8: result = ((((GIV(statFullGCUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 9: result = (((usqInt)(/* begin statScavenges */ GIV(statScavenges)) << 3) | 1); - goto l86; + goto l87; break; case 10: result = (((((/* begin statScavengeGCUsecs */ GIV(statScavengeGCUsecs)) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 11: result = (((usqInt)GIV(statTenures) << 3) | 1); - goto l86; + goto l87; break; case 12: result = (((usqInt)eventTraceMask << 3) | 1); - goto l86; + goto l87; break; case 13: result = @@ -81407,7 +81045,7 @@ primitiveVMParameter(void) ConstZero # endif ; - goto l86; + goto l87; break; case 14: /* begin getVMTickerCount */ @@ -81418,7 +81056,7 @@ primitiveVMParameter(void) ConstZero # endif ; - goto l86; + goto l87; break; case 15: /* begin getVMTickeeCallCount */ @@ -81429,196 +81067,196 @@ primitiveVMParameter(void) ConstZero # endif ; - goto l86; + goto l87; break; case 16: result = positive64BitIntegerFor(GIV(statIdleUsecs)); - goto l86; + goto l87; break; case 17: result = ConstZero; - goto l86; + goto l87; break; case 18: result = ((((GIV(statCompactionUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 19: result = (((usqInt)(GIV(scavengeThreshold) - (((eden()).start))) << 3) | 1); - goto l86; + goto l87; break; case 20: result = positive64BitIntegerFor(ioUTCStartMicroseconds()); - goto l86; + goto l87; break; case 21: result = (((usqInt)(rootTableCount()) << 3) | 1); - goto l86; + goto l87; break; case 22: result = (((usqInt)GIV(statRootTableOverflows) << 3) | 1); - goto l86; + goto l87; break; case 23: result = (((usqInt)extraVMMemory << 3) | 1); - goto l86; + goto l87; break; case 24: result = (((usqInt)GIV(shrinkThreshold) << 3) | 1); - goto l86; + goto l87; break; case 25: result = (((usqInt)GIV(growHeadroom) << 3) | 1); - goto l86; + goto l87; break; case 26: result = (((usqInt)(ioHeartbeatMilliseconds()) << 3) | 1); - goto l86; + goto l87; break; case 27: result = (((usqInt)GIV(statMarkCount) << 3) | 1); - goto l86; + goto l87; break; case 28: result = (((usqInt)0 /* statSweepCount */ << 3) | 1); - goto l86; + goto l87; break; case 29: result = (((usqInt)0 /* statMkFwdCount */ << 3) | 1); - goto l86; + goto l87; break; case 30: result = (((usqInt)GIV(statCompactPassCount) << 3) | 1); - goto l86; + goto l87; break; case 0x1F: result = (((usqInt)GIV(statGrowMemory) << 3) | 1); - goto l86; + goto l87; break; case 32: result = (((usqInt)GIV(statShrinkMemory) << 3) | 1); - goto l86; + goto l87; break; case 33: result = (((usqInt)GIV(statRootTableCount) << 3) | 1); - goto l86; + goto l87; break; case 34: result = positive64BitIntegerFor(currentAllocatedBytes()); - goto l86; + goto l87; break; case 35: result = (((usqInt)GIV(statSurvivorCount) << 3) | 1); - goto l86; + goto l87; break; case 36: result = ((((GIV(statGCEndUsecs) / 1000) & MillisecondClockMask) << 3) | 1); - goto l86; + goto l87; break; case 37: result = (((usqInt)0 /* statSpecialMarkCount */ << 3) | 1); - goto l86; + goto l87; break; case 38: result = ((((GIV(statIGCDeltaUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 39: result = (((usqInt)GIV(statPendingFinalizationSignals) << 3) | 1); - goto l86; + goto l87; break; case 40: result = (((usqInt)BytesPerWord << 3) | 1); - goto l86; + goto l87; break; case 41: result = (((usqInt)68021 /* imageFormatVersion */ << 3) | 1); - goto l86; + goto l87; break; case 42: result = (((usqInt)GIV(numStackPages) << 3) | 1); - goto l86; + goto l87; break; case 43: result = (((usqInt)desiredNumStackPages << 3) | 1); - goto l86; + goto l87; break; case 44: result = (((usqInt)(((GIV(eden).limit)) - ((GIV(eden).start))) << 3) | 1); - goto l86; + goto l87; break; case 45: result = (((usqInt)desiredEdenBytes << 3) | 1); - goto l86; + goto l87; break; case 46: result = getCogCodeSize(); - goto l86; + goto l87; break; case 47: result = getDesiredCogCodeSize(); - goto l86; + goto l87; break; case 48: /* begin getImageHeaderFlagsParameter */ result = (((usqInt)(((usqInt)((getImageHeaderFlags()))) >> 2) << 3) | 1); - goto l86; + goto l87; break; case 49: result = (((usqInt)(ioGetMaxExtSemTableSize()) << 3) | 1); - goto l86; + goto l87; break; case 52: result = (((usqInt)(rootTableCapacity()) << 3) | 1); - goto l86; + goto l87; break; case 53: result = (((usqInt)(numSegments()) << 3) | 1); - goto l86; + goto l87; break; case 54: result = ((GIV(totalFreeOldSpace) << 3) | 1); - goto l86; + goto l87; break; case 55: result = floatObjectOf(getHeapGrowthToSizeGCRatio()); - goto l86; + goto l87; break; case 56: result = positive64BitIntegerFor(GIV(statProcessSwitch)); - goto l86; + goto l87; break; case 57: result = positive64BitIntegerFor(GIV(statIOProcessEvents)); - goto l86; + goto l87; break; case 58: result = positive64BitIntegerFor(GIV(statForceInterruptCheck)); - goto l86; + goto l87; break; case 59: result = positive64BitIntegerFor(GIV(statCheckForEvents)); - goto l86; + goto l87; break; case 60: result = positive64BitIntegerFor(GIV(statStackOverflow)); - goto l86; + goto l87; break; case 61: result = positive64BitIntegerFor(GIV(statStackPageDivorce)); - goto l86; + goto l87; break; case 0x3E: result = getCodeCompactionCount(); - goto l86; + goto l87; break; case 0x3F: result = getCodeCompactionMSecs(); - goto l86; + goto l87; break; case 64: result = (((usqInt)(numMethodsOfType(CMMethod)) << 3) | 1); - goto l86; + goto l87; break; case 65: /* begin getCogVMFeatureFlags */ @@ -81637,43 +81275,43 @@ primitiveVMParameter(void) 0 #endif )) << 3) | 1); - goto l86; + goto l87; break; case 66: result = (((usqInt)(stackPageByteSize()) << 3) | 1); - goto l86; + goto l87; break; case 67: result = positiveMachineIntegerFor(maxOldSpaceSize()); - goto l86; + goto l87; break; case 68: result = floatObjectOf(statAverageLivePagesWhenMapping()); - goto l86; + goto l87; break; case 69: result = (((usqInt)(statMaxPageCountWhenMapping()) << 3) | 1); - goto l86; + goto l87; break; case 70: result = (((usqInt)VM_PROXY_MAJOR << 3) | 1); - goto l86; + goto l87; break; case 71: result = (((usqInt)VM_PROXY_MINOR << 3) | 1); - goto l86; + goto l87; break; case 72: result = ((((GIV(statMarkUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 73: result = ((((GIV(statSweepUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 74: result = (((usqInt)((GIV(statMaxAllocSegmentTime) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 75: /* begin booleanObjectOf: */ @@ -81681,14 +81319,18 @@ primitiveVMParameter(void) result = (aBool1 ? GIV(trueObj) : GIV(falseObj)); - goto l86; + goto l87; + break; + case 76: + result = (((usqInt)(minimumUnusedHeadroom()) << 3) | 1); + goto l87; break; default: result = null; - goto l86; + goto l87; } - l86: /* end primitiveGetVMParameter: */; + l87: /* end primitiveGetVMParameter: */; /* begin methodReturnValue: */ oop = (!(result) ? /* begin nilObject */ GIV(nilObj) @@ -81722,10 +81364,10 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = ((usqIntptr_t) null); - goto l90; + goto l91; } arg = ((usqIntptr_t) value); - goto l90; + goto l91; } if (((argOop & (tagMask())) != 0)) { /* begin primitiveFail */ @@ -81733,22 +81375,22 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = 0; - goto l90; + goto l91; } /* begin isClassOfNonImm:equalTo:compactClassIndex: */ assert(!(isImmediate(argOop))); /* begin classIndexOf: */ ccIndex = (longAt(argOop)) & (classIndexMask()); ok = ClassLargePositiveIntegerCompactIndex == ccIndex; - goto l101; - l101: /* end isClassOfNonImm:equalTo:compactClassIndex: */; + goto l102; + l102: /* end isClassOfNonImm:equalTo:compactClassIndex: */; if (!ok) { /* begin primitiveFail */ if (!GIV(primFailCode)) { GIV(primFailCode) = 1; } arg = 0; - goto l90; + goto l91; } /* begin numBytesOfBytes: */ fmt = (((usqInt)((longAt(argOop)))) >> (formatShift())) & (formatMask()); @@ -81760,25 +81402,25 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = 0; - goto l90; + goto l91; } if (((sizeof(usqIntptr_t)) == 8) && (bs > 4)) { arg = ((usqIntptr_t) (SQ_SWAP_8_BYTES_IF_BIGENDIAN((long64At((argOop + BaseHeaderSize)))))); - goto l90; + goto l91; } arg = ((usqIntptr_t) (((unsigned int) (SQ_SWAP_4_BYTES_IF_BIGENDIAN((long32At((argOop + BaseHeaderSize)))))))); - l90: /* end positiveMachineIntegerValueOf: */; + l91: /* end positiveMachineIntegerValueOf: */; break; case 75: /* begin booleanValueOf: */ if (argOop == GIV(trueObj)) { arg = 1; - goto l102; + goto l103; } if (argOop == GIV(falseObj)) { arg = 0; - goto l102; + goto l103; } /* begin success: */ @@ -81787,7 +81429,7 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = null; - l102: /* end booleanValueOf: */; + l103: /* end booleanValueOf: */; break; default: arg = (argOop >> 3); @@ -81796,7 +81438,7 @@ primitiveVMParameter(void) if (GIV(primFailCode)) { /* begin primitiveFailFor: */ GIV(primFailCode) = PrimErrBadArgument; - goto l104; + goto l105; } /* begin primitiveFailFor: */ GIV(primFailCode) = PrimErrBadArgument; @@ -81808,7 +81450,7 @@ primitiveVMParameter(void) /* begin tenuringThreshold: */ if (arg < 0) { GIV(primFailCode) = PrimErrBadArgument; - goto l96; + goto l97; } /* begin scavengerTenuringThreshold: */ aProportion = (((double) (arg * (8 * BytesPerOop)) )) / (((double) (((GIV(pastSpace).limit)) - ((GIV(pastSpace).start))) )); @@ -81817,7 +81459,7 @@ primitiveVMParameter(void) ? 0 : (round(((((GIV(pastSpace).limit)) - ((GIV(pastSpace).start))) * (1.0 - aProportion)))) + ((GIV(pastSpace).start))); GIV(primFailCode) = 0; - l96: /* end tenuringThreshold: */; + l97: /* end tenuringThreshold: */; break; case 12: result2 = (((usqInt)eventTraceMask << 3) | 1); @@ -81917,7 +81559,7 @@ primitiveVMParameter(void) /* begin setImageHeaderFlags: */ if ((((usqInt)arg)) > 0xFF) { GIV(primFailCode) = PrimErrUnsupported; - goto l98; + goto l99; } GIV(imageHeaderFlags) = (((arg & 1) != 0) ? GIV(imageHeaderFlags) | 4 @@ -81935,7 +81577,7 @@ primitiveVMParameter(void) GIV(imageHeaderFlags) = (((arg & 128) != 0) ? GIV(imageHeaderFlags) | 0x200 : ((GIV(imageHeaderFlags) | 0x200) - 0x200)); - l98: /* end setImageHeaderFlags: */; + l99: /* end setImageHeaderFlags: */; if ((GIV(primFailCode) == 0) && (oldPrimitiveDoMixedArithmetic != primitiveDoMixedArithmetic)) { flushMethodCache(); @@ -82030,7 +81672,7 @@ primitiveVMParameter(void) /* begin primitiveFailFor: */ GIV(primFailCode) = PrimErrInappropriate; } - l104: /* end primitiveSetVMParameter:arg: */; + l105: /* end primitiveSetVMParameter:arg: */; } @@ -82306,20 +81948,20 @@ void* vm_exports[][3] = { {(void*)_m, "longPrintOop", (void*)longPrintOop}, {(void*)_m, "longPrintReferencesTo", (void*)longPrintReferencesTo}, {(void*)_m, "moduleUnloaded", (void*)moduleUnloaded}, - {(void*)_m, "primitiveAddLargeIntegers\000\377\000", (void*)primitiveAddLargeIntegers}, + {(void*)_m, "primitiveAddLargeIntegers\000\000\000", (void*)primitiveAddLargeIntegers}, {(void*)_m, "primitiveAllInstances\000\377\000", (void*)primitiveAllInstances}, {(void*)_m, "primitiveAllObjects\000\377\000", (void*)primitiveAllObjects}, {(void*)_m, "primitiveBitAndLargeIntegers\000\377\000", (void*)primitiveBitAndLargeIntegers}, {(void*)_m, "primitiveBitOrLargeIntegers\000\377\000", (void*)primitiveBitOrLargeIntegers}, - {(void*)_m, "primitiveBitShiftLargeIntegers\000\377\000", (void*)primitiveBitShiftLargeIntegers}, + {(void*)_m, "primitiveBitShiftLargeIntegers\000\000\000", (void*)primitiveBitShiftLargeIntegers}, {(void*)_m, "primitiveBitXorLargeIntegers\000\377\000", (void*)primitiveBitXorLargeIntegers}, {(void*)_m, "primitiveClockLogAddresses\000\377\000", (void*)primitiveClockLogAddresses}, - {(void*)_m, "primitiveCompareBytes\000\377\000", (void*)primitiveCompareBytes}, - {(void*)_m, "primitiveCompareWith\000\377\000", (void*)primitiveCompareWith}, + {(void*)_m, "primitiveCompareBytes\000\000\000", (void*)primitiveCompareBytes}, + {(void*)_m, "primitiveCompareWith\000\001\000", (void*)primitiveCompareWith}, {(void*)_m, "primitiveCrashVM\000\377\000", (void*)primitiveCrashVM}, - {(void*)_m, "primitiveDisablePowerManager\000\377\000", (void*)primitiveDisablePowerManager}, - {(void*)_m, "primitiveDivideLargeIntegers\000\377\000", (void*)primitiveDivideLargeIntegers}, - {(void*)_m, "primitiveDivLargeIntegers\000\377\000", (void*)primitiveDivLargeIntegers}, + {(void*)_m, "primitiveDisablePowerManager\000\000\000", (void*)primitiveDisablePowerManager}, + {(void*)_m, "primitiveDivideLargeIntegers\000\000\000", (void*)primitiveDivideLargeIntegers}, + {(void*)_m, "primitiveDivLargeIntegers\000\000\000", (void*)primitiveDivLargeIntegers}, {(void*)_m, "primitiveEqualLargeIntegers\000\377\000", (void*)primitiveEqualLargeIntegers}, {(void*)_m, "primitiveEventProcessingControl\000\377\000", (void*)primitiveEventProcessingControl}, {(void*)_m, "primitiveGetenv\000\377\000", (void*)primitiveGetenv}, @@ -82329,39 +81971,37 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\377\000", (void*)primitiveLongRunningPrimitiveSemaphore}, - {(void*)_m, "primitiveMethodPCData\000\377\000", (void*)primitiveMethodPCData}, + {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, - {(void*)_m, "primitiveModLargeIntegers\000\377\000", (void*)primitiveModLargeIntegers}, - {(void*)_m, "primitiveMultiplyLargeIntegers\000\377\000", (void*)primitiveMultiplyLargeIntegers}, + {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, + {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, - {(void*)_m, "primitivePathToUsing\000\377\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, - {(void*)_m, "primitiveProfileSemaphore\000\377\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\377\000", (void*)primitiveProfileStart}, - {(void*)_m, "primitiveQuoLargeIntegers\000\377\000", (void*)primitiveQuoLargeIntegers}, - {(void*)_m, "primitiveRemLargeIntegers\000\377\000", (void*)primitiveRemLargeIntegers}, + {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, + {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, {(void*)_m, "primitiveScreenScaleFactor\000\377\000", (void*)primitiveScreenScaleFactor}, - {(void*)_m, "primitiveSetGCSemaphore\000\377\000", (void*)primitiveSetGCSemaphore}, - {(void*)_m, "primitiveSetLogDirectory\000\377\000", (void*)primitiveSetLogDirectory}, - {(void*)_m, "primitiveSetWindowLabel\000\377\000", (void*)primitiveSetWindowLabel}, - {(void*)_m, "primitiveSetWindowSize\000\377\000", (void*)primitiveSetWindowSize}, - {(void*)_m, "primitiveSubtractLargeIntegers\000\377\000", (void*)primitiveSubtractLargeIntegers}, + {(void*)_m, "primitiveSetGCSemaphore\000\000\000", (void*)primitiveSetGCSemaphore}, + {(void*)_m, "primitiveSetLogDirectory\000\000\000", (void*)primitiveSetLogDirectory}, + {(void*)_m, "primitiveSetWindowLabel\000\000\000", (void*)primitiveSetWindowLabel}, + {(void*)_m, "primitiveSetWindowSize\000\000\000", (void*)primitiveSetWindowSize}, + {(void*)_m, "primitiveSubtractLargeIntegers\000\000\000", (void*)primitiveSubtractLargeIntegers}, #if TestingPrimitives - {(void*)_m, "primitiveTestShortenIndexableSize\000\377\000", (void*)primitiveTestShortenIndexableSize}, + {(void*)_m, "primitiveTestShortenIndexableSize\000\000\000", (void*)primitiveTestShortenIndexableSize}, #endif /* TestingPrimitives */ - {(void*)_m, "primitiveUtcWithOffset\000\377\000", (void*)primitiveUtcWithOffset}, + {(void*)_m, "primitiveUtcWithOffset\000\000\000", (void*)primitiveUtcWithOffset}, {(void*)_m, "primitiveVoidReceiver\000\377\000", (void*)primitiveVoidReceiver}, {(void*)_m, "printActivationsOf", (void*)printActivationsOf}, {(void*)_m, "printAllStacks", (void*)printAllStacks}, diff --git a/nsspur64src/vm/cointerp.h b/nsspur64src/vm/cointerp.h index ec91849ae0..d60f89d1c0 100644 --- a/nsspur64src/vm/cointerp.h +++ b/nsspur64src/vm/cointerp.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ @@ -33,7 +33,6 @@ extern sqInt ceCannotAssignTowithIndexvalueToAssign(sqInt immutableObject, sqInt extern sqInt ceCannotResume(void); extern void ceCheckAndMaybeRetryPrimitive(sqInt primIndex); extern void ceCheckForInterrupt(void); -extern void ceCheckProfileTick(void); extern sqInt ceContextinstVar(sqInt maybeContext, sqInt slotIndex); extern sqInt ceContextinstVarvalue(sqInt maybeMarriedContext, sqInt slotIndex, sqInt anOop); extern void ceDynamicSuperSendreceiver(sqInt cacheAddress, sqInt methodReceiver); @@ -54,6 +53,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethodOrNil); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -112,6 +112,7 @@ extern sqInt (*quickPrimitiveGeneratorFor(sqInt aQuickPrimitiveIndex))(void) ; extern sqInt quickPrimitiveInstVarIndexFor(sqInt primIndex); extern sqInt rawHeaderOf(sqInt methodPointer); extern void rawHeaderOfput(sqInt methodOop, sqInt cogMethodOrMethodHeader); +extern sqInt recordFastCCallPrimTraceForMethod(sqInt aMethodObj); extern sqInt recordPrimTraceForMethod(sqInt aMethodObj); extern void reportMinimumUnusedHeadroom(void); extern sqInt signed32BitIntegerFor(sqInt integerValue); @@ -251,7 +252,7 @@ extern sqInt minSlotsForShortening(void); extern sqInt nilObject(void); extern sqInt nonIndexablePointerFormat(void); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); extern sqInt numStrongSlotsOfWeakling(sqInt objOop); extern sqInt objectAfter(sqInt objOop); @@ -390,7 +391,7 @@ extern sqInt suppressHeartbeatFlag; compilationBreakpointFor(sel); \ } \ } while (0) -#define primNumberExternalCall() null +#define primNumberExternalCall() 117 #define startOfMemory() heapBase #define numTagBits() 3 #define shiftForWord() 3 diff --git a/nsspur64src/vm/gcc3x-cointerp.c b/nsspur64src/vm/gcc3x-cointerp.c index d3f939a1bd..1d0433096c 100644 --- a/nsspur64src/vm/gcc3x-cointerp.c +++ b/nsspur64src/vm/gcc3x-cointerp.c @@ -2,11 +2,11 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - CoInterpreter VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 + CoInterpreter VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.2997 uuid: 2d21044e-f2db-40ea-91da-ba273faf9093 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__interpBuildInfo = __buildInfo; @@ -158,6 +158,7 @@ warningat(const char *s, int l) { /* ditto with line number. */ #define ExtraRootsSize 2048 #define FailImbalancedPrimitives 1 #define FalseObject 1 +#define FastCPrimitiveUseCABIFlag 4 #define FirstLinkIndex 0 #define FoxCallerSavedIP 8 #define FoxIFReceiver -40 @@ -291,12 +292,14 @@ warningat(const char *s, int l) { /* ditto with line number. */ #define PrimNumberDoPrimitive 118 #define PrimNumberExternalCall 117 #define PrimNumberFFICall 120 +#define PrimNumberFlushExternalPrimitives 570 #define PrimNumberHandlerMarker 199 #define PrimNumberHashMultiply 159 #define PrimNumberInstVarAt 73 #define PrimNumberNoContextSwitchMarker 123 #define PrimNumberShallowCopy 148 #define PrimNumberSlotAt 173 +#define PrimNumberUnoadModule 571 #define PrimNumberUnwindMarker 198 #define PrimTraceLogSize 256 #define PriorityIndex 2 @@ -326,6 +329,8 @@ warningat(const char *s, int l) { /* ditto with line number. */ #define SmallContextSlots 22 #define SPURVM 1 #define SpecialSelectors 23 +#define SpurPrimitiveAccessorDepthShift 8 +#define SpurPrimitiveFlagsMask 0xFF #define StackPageReachedButUntraced 1 #define StackPageTraced 2 #define StackPageTraceInvalid -1 @@ -482,7 +487,6 @@ extern sqInt ceCannotAssignTowithIndexvalueToAssign(sqInt immutableObject, sqInt extern sqInt ceCannotResume(void); extern void ceCheckAndMaybeRetryPrimitive(sqInt primIndex); extern void ceCheckForInterrupt(void); -extern void ceCheckProfileTick(void); extern sqInt ceContextinstVar(sqInt maybeContext, sqInt slotIndex); extern sqInt ceContextinstVarvalue(sqInt maybeMarriedContext, sqInt slotIndex, sqInt anOop); extern void ceDynamicSuperSendreceiver(sqInt cacheAddress, sqInt methodReceiver); @@ -503,6 +507,7 @@ extern void ceSendaboveClassBindingtonumArgs(sqInt selector, sqInt methodClassBi extern sqInt ceSendabovetonumArgs(sqInt selector, sqInt methodClass, sqInt rcvr, sqInt numArgs); extern sqInt ceSendsupertonumArgs(sqInt selector, sqInt superNormalBar, sqInt rcvr, sqInt numArgs); extern void ceStackOverflow(sqInt contextSwitchIfNotNil); +extern void ceTakeProfileSample(CogMethod *aCogMethodOrNil); extern void ceTraceBlockActivation(void); extern void ceTraceLinkedSend(sqInt theReceiver); extern void ceTraceStoreOfinto(sqInt aValue, sqInt anObject); @@ -601,7 +606,7 @@ extern CogMethod * mframeHomeMethodExport(void); extern CogMethod * mframeHomeMethod(char *theFP); static sqInt NoDbgRegParms mframeIsBlockActivation(char *theFP); static sqInt NoDbgRegParms mframeReceiver(char *theFP); -static sqInt minimumUnusedHeadroom(void); +static sqInt NeverInline minimumUnusedHeadroom(void); extern sqInt mMethodClass(void); extern void mnuCompilationBreakpointFor(sqInt selectorOop); static sqInt NoDbgRegParms mnuMethodOrNilFor(sqInt rcvr); @@ -640,6 +645,7 @@ extern sqInt quickPrimitiveInstVarIndexFor(sqInt primIndex); extern sqInt rawHeaderOf(sqInt methodPointer); extern void rawHeaderOfput(sqInt methodOop, sqInt cogMethodOrMethodHeader); extern size_t readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squeakFileOffsetType imageOffset); +extern sqInt recordFastCCallPrimTraceForMethod(sqInt aMethodObj); extern sqInt recordPrimTraceForMethod(sqInt aMethodObj); extern void reportMinimumUnusedHeadroom(void); static sqInt NoDbgRegParms resumepreemptedYieldingIffrom(sqInt aProcess, sqInt yieldImplicitly, sqInt sourceCode); @@ -681,7 +687,6 @@ static void primitiveExitCriticalSection(void); static void primitiveFlushCacheByMethod(void); static void primitiveFlushCacheBySelector(void); extern usqInt primitiveFunctionPointerAddress(void); -EXPORT(sqInt) primitiveLongRunningPrimitiveSemaphore(void); EXPORT(sqInt) primitiveMethodPCData(void); static void primitiveMethodXray(void); EXPORT(void) primitiveMinimumUnusedHeadroom(void); @@ -1222,7 +1227,6 @@ static sqInt NoDbgRegParms isPureBitsFormat(sqInt format); extern sqInt isReallyYoung(sqInt oop); static sqInt NoDbgRegParms isRemembered(sqInt objOop); static sqInt NoDbgRegParms isSegmentBridge(sqInt objOop); -static sqInt NoDbgRegParms isSemaphoreOop(sqInt anOop); extern sqInt isShorts(sqInt oop); extern sqInt isUnambiguouslyForwarder(sqInt objOop); extern sqInt isUnmarked(sqInt objOop); @@ -1286,7 +1290,7 @@ static sqInt noUnscannedEphemerons(void); static sqInt NoDbgRegParms numBytesOfBitsformat(sqInt objOop, sqInt format); static sqInt NoDbgRegParms numBytesOfBytes(sqInt objOop); extern sqInt numBytesOf(sqInt objOop); -extern sqInt numPointerSlotsOf(sqInt objOop); +extern usqInt numPointerSlotsOf(sqInt objOop); static usqInt NoDbgRegParms numSlotsOfAny(sqInt objOop); extern usqInt numSlotsOf(sqInt objOop); static sqInt NoDbgRegParms numStrongSlotsOfInephemeral(sqInt objOop); @@ -1450,7 +1454,6 @@ EXPORT(sqInt) callbackLeave(sqInt cbID); extern sqInt canContextSwitchIfActivatingheader(sqInt theMethod, sqInt methodHeader); extern sqInt characterForAscii(sqInt ascii); EXPORT(sqInt) checkAllAccessibleObjectsOkay(void); -static sqInt checkDeliveryOfLongRunningPrimitiveSignal(void); extern sqInt checkedIntegerValueOf(sqInt intOop); static sqInt NoDbgRegParms checkForEventsMayContextSwitch(sqInt mayContextSwitch); static sqInt NoDbgRegParms checkImageVersionFromstartingAt(sqImageFile f, squeakFileOffsetType imageOffset); @@ -1607,6 +1610,8 @@ static sqInt NoDbgRegParms noMarkedContextsOnPage(StackPage *thePage); static sqInt NoDbgRegParms numSlotsOfMarriedContext(sqInt aContext); static sqInt numStkPages(void); extern sqInt objCouldBeClassObj(sqInt objOop); +static sqInt NoDbgRegParms objectequalsString(sqInt anOop, sqInt aCString); +static sqInt NoDbgRegParms objectequalsStringofSize(sqInt anOop, sqInt aCString, sqInt aCStringStrlen); extern sqInt ownVM(sqInt threadIndexAndFlags); extern sqInt penultimateLiteralOf(sqInt aMethodOop); extern sqInt popStack(void); @@ -1732,18 +1737,19 @@ extern sqInt superclassOf(sqInt classPointer); extern sqInt tempCountOf(sqInt methodPointer); extern sqInt temporaryCountOfMethodHeader(sqInt header); extern sqInt ultimateLiteralOf(sqInt aMethodOop); +static sqInt NoDbgRegParms unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(sqInt methodObj, sqInt primIndex); static sqInt NoDbgRegParms NeverInline unfollowatIndex(sqInt litVar, sqInt literalIndex); static sqInt NoDbgRegParms updateDisplayLeftTopRightBottom(sqInt l, sqInt t, sqInt r, sqInt b); static sqInt NoDbgRegParms validBCPCinMethod(sqInt thePC, usqInt aMethod); static sqInt NoDbgRegParms validInstructionPointerinFrame(usqInt anInstrPointer, char *fp); static sqInt validStackPageBaseFrames(void); -static void NoDbgRegParms NeverInline voidLongRunningPrimitive(char *reason); static sqInt wakeHighestPriority(void); static sqInt NeverInline writeImageFileIO(void); static usqInt NoDbgRegParms cloneContext(sqInt aContext); static sqInt NoDbgRegParms fieldOrSenderFPofContext(sqInt index, sqInt contextObj); static sqInt NoDbgRegParms fieldofFrame(sqInt index, char *theFP); static sqInt NoDbgRegParms isAppropriateForCopyObject(sqInt oop); +static void (*linkExternalCallerrInto(sqInt externalCallLiteral, sqInt *failPtr))() ; static double NoDbgRegParms NeverInline noInlineLoadFloatOrIntFrom(sqInt floatOrInt); static void primitiveClone(void); static void primitiveContextAt(void); @@ -1759,7 +1765,6 @@ static void primitiveFullGC(void); static void primitiveIncrementalGC(void); static void primitiveInstVarAt(void); static void primitiveInstVarAtPut(void); -EXPORT(sqInt) primitiveLongRunningPrimitive(void); static void primitiveObjectPointsTo(void); static void primitivePerform(void); static void primitivePin(void); @@ -1837,21 +1842,19 @@ _iss sqInt classTableIndex; _iss usqInt lastMobileObject; _iss sqInt tempOop; _iss sqInt numClassTablePages; -_iss sqInt futureSurvivorStart; _iss sqInt profileProcess; +_iss sqInt futureSurvivorStart; _iss sqInt mournQueue; _iss sqInt numRememberedEphemerons; +_iss sqInt profileMethod; _iss sqInt profileSemaphore; _iss sqInt jmpDepth; _iss sqInt mobileStart; -_iss sqInt profileMethod; -_iss sqInt longRunningPrimitiveCheckSemaphore; _iss sqInt growHeadroom; _iss sqInt tenureThreshold; _iss char * objStackInvalidBecause; _iss sqInt sweepIndex; _iss sqInt ephemeronList; -_iss sqInt longRunningPrimitiveCheckMethod; _iss sqInt tenureCriterion; _iss usqInt totalHeapSizeIncludingBridges; _iss sqInt becomeEffectsFlags; @@ -1869,7 +1872,6 @@ _iss sqInt methodDictLinearSearchLimit; _iss sqInt pendingFinalizationSignals; _iss sqInt validatedIntegerClassFlags; _iss usqInt firstMobileObject; -_iss sqInt externalPrimitiveTableFirstFreeIndex; _iss sqInt lastCoggableInterpretedBlockMethod; _iss sqInt lastUncoggableInterpretedBlockMethod; _iss sqInt numSegInfos; @@ -1879,21 +1881,18 @@ _iss sqInt gcMode; _iss sqInt highestRunnableProcessPriority; _iss sqInt metaclassNumSlots; _iss usqLong nextWakeupUsecs; -_iss usqLong statGCEndUsecs; -_iss usqLong longRunningPrimitiveStartUsecs; -_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt shrinkThreshold; -_iss usqLong statCheckForEvents; _iss sqInt statTenures; _iss sqInt weakList; _iss usqInt cogCodeSize; -_iss usqLong gcStartUsecs; _iss sqInt marking; _iss sqLong oldSpaceUsePriorToScavenge; _iss sqInt preemptionYields; _iss sqInt rememberedSetLimit; +_iss usqLong statGCEndUsecs; _iss sqInt statSurvivorCount; _iss sqInt thisClassIndex; +_iss sqInt externalPrimitiveTableFirstFreeIndex; _iss sqInt firstFieldOfRememberedSet; _iss sqInt firstSegmentSize; _iss usqInt lowSpaceThreshold; @@ -1905,6 +1904,7 @@ _iss sqInt statShrinkMemory; _iss sqInt biasForGC; _iss sqInt edenBytes; _iss sqInt fullScreenFlag; +_iss usqLong gcStartUsecs; _iss usqInt lastHash; _iss sqInt lastMethodCacheProbeWrite; _iss sqInt newFinalization; @@ -1919,9 +1919,9 @@ _iss sqInt freeSpaceCheckOopToIgnore; _iss usqInt heapSizeAtPreviousGC; _iss sqInt interruptKeycode; _iss sqInt interruptPending; -_iss sqInt longRunningPrimitiveCheckSequenceNumber; _iss usqLong nextPollUsecs; _iss sqLong osErrorCode; +_iss usqLong statCheckForEvents; _iss usqLong statCompactionUsecs; _iss usqLong statForceInterruptCheck; _iss usqLong statFullGCUsecs; @@ -1942,7 +1942,6 @@ _iss sqInt extraFramesToMoveOnOverflow; _iss sqInt globalSessionID; _iss sqInt imageFloatsBigEndian; _iss sqInt inFFIFlags; -_iss sqInt longRunningPrimitiveSignalUndelivered; _iss sqInt maxExtSemTabSizeSet; _iss sqInt refCountToShrinkRT; _iss sqInt signalLowSpace; @@ -1956,7 +1955,6 @@ _iss sqInt classByteArrayCompactIndex; _iss usqInt exceptionPC; _iss sqInt gcSemaphoreIndex; _iss usqLong gcSweepEndUsecs; -_iss usqLong longRunningPrimitiveGCUsecs; _iss sqInt overflowLimit; _iss StackPage * overflowedPage; _iss sqInt statCompactPassCount; @@ -1975,6 +1973,9 @@ _iss usqInt suspendedCallbacks[MaxJumpBuf + 1 /* 33 */]; _iss usqInt suspendedMethods[MaxJumpBuf + 1 /* 33 */]; _iss jmp_buf jmpBuf[MaxJumpBuf + 1 /* 33 */]; _iss usqLong byteCount; +_iss usqLong longRunningPrimitiveGCUsecs; +_iss usqLong longRunningPrimitiveStartUsecs; +_iss usqLong longRunningPrimitiveStopUsecs; _iss sqInt preferredPinningSegment; _iss sqInt statCoalesces; _iss usqLong statFGCDeltaUsecs; @@ -2047,7 +2048,6 @@ static signed char primitiveAccessorDepthTable[MaxPrimitiveIndex + 2 /* 578 */] }; static void (*interruptCheckChain)(void) = 0; static int (*sHEAFn)() = 0; -static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); static void (*primitiveTable[MaxPrimitiveIndex + 2 /* 578 */])(void) = { /* 0 */ (void (*)(void))0, /* 1 */ primitiveAdd, @@ -2627,12 +2627,13 @@ static void (*primitiveTable[MaxPrimitiveIndex + 2 /* 578 */])(void) = { /* 575 */ primitiveHighBit, /* 576 */ (void (*)(void))0, 0 }; +static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); sqInt maxLiteralCountForCompile = MaxLiteralCountForCompile /* 60 */; sqInt checkForLeaks; sqInt breakLookupClassTag; sqInt breakSelectorLength = MinSmallInteger; -sqInt debugCallbackPath; char * primTracePluginName; +sqInt debugCallbackPath; void * displayBits; sqInt desiredEdenBytes; sqInt desiredNumStackPages; @@ -2651,7 +2652,7 @@ sqInt debugCallbackInvokes; sqInt debugCallbackReturns; sqInt ffiExceptionResponse; sqInt checkedPluginName; -const char *interpreterVersion = "Newspeak Virtual Machine [ Open Smalltalk, Spur] CoInterpreterPrimitives_VMMaker.oscog-eem.2997"; +const char *interpreterVersion = "Newspeak Virtual Machine [ Open Smalltalk, Spur] CoInterpreterPrimitives_VMMaker.oscog-eem.3034"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; int displayWidth; int displayDepth; @@ -2696,7 +2697,7 @@ volatile int sendTrace; compilationBreakpointFor(sel); \ } \ } while (0) -#define primNumberExternalCall() null +#define primNumberExternalCall() 117 #define primTraceLogIndex(aValue) (GIV(primTraceLogIndex) = (aValue)) #define pageIndexForstackBasePlus1bytesPerPage(pointer,stkBasePlus1,pageByteSize) (((char *)(pointer) - (stkBasePlus1)) / (pageByteSize)) #define startOfMemory() heapBase @@ -14508,7 +14509,7 @@ accessorDepthForExternalPrimitiveMethod(sqInt methodObj) /* begin fetchPointer:ofObject: */ lit = longAt((methodObj + BaseHeaderSize) + (((sqInt)((usqInt)((0 + LiteralStart)) << (shiftForWord()))))); flags = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord()))))); - return (((usqInt)(((flags >> 3)))) >> 8); + return (((flags >> 3))) >> SpurPrimitiveAccessorDepthShift; } /* CoInterpreter>>#accessorDepthForPrimitiveIndex: */ @@ -15313,6 +15314,10 @@ ceActivateFailingPrimitiveMethod(sqInt aPrimitiveMethod) assert(GIV(newMethod) == aPrimitiveMethod); retryPrimitiveOnFailure(); if (!GIV(primFailCode)) { + if ((GIV(profileSemaphore) != GIV(nilObj)) + && ((ioHighResClock()) >= GIV(nextProfileTick))) { + ceTakeProfileSample(null); + } result = longAt(GIV(stackPointer)); longAtPointerput(GIV(stackPointer), GIV(instructionPointer)); /* begin push: */ @@ -15591,21 +15596,6 @@ ceCheckForInterrupt(void) returnToExecutivepostContextSwitch(0, switched); } - -/* Check if the profile timer has expired and if so take a sample. - If the primitive has failed sample the profileMethod as nil. - As a courtesy to compileInterpreterPrimitive: map NULL to nilObj. */ - - /* CoInterpreter>>#ceCheckProfileTick */ -void -ceCheckProfileTick(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if (!GIV(newMethod)) { - GIV(newMethod) = GIV(nilObj); - } - checkProfileTick(GIV(newMethod)); -} - /* CoInterpreter>>#ceContext:instVar: */ sqInt ceContextinstVar(sqInt maybeContext, sqInt slotIndex) @@ -17723,6 +17713,35 @@ ceStackOverflow(sqInt contextSwitchIfNotNil) error("should not be reached"); } + +/* A primitive has succeeded and the nextProfileTick has been reached (all + done in machine code). + If aCogMethodOrNil is not nil then it is the cog method containing the + primitive call. + If aCogMethodOrNil is nil then this has been called from + primReturnEnterCogCode and newMethod + Now take a sample. c.f. checkProfileTick: */ +/* Slang type inferrence can't deal with self ceTakeProfileSample: nil... */ + + /* CoInterpreter>>#ceTakeProfileSample: */ +void +ceTakeProfileSample(CogMethod *aCogMethodOrNil) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt objOop; + sqInt objOop1; + + /* begin fetchPointer:ofObject: */ + objOop1 = longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(SchedulerAssociation) << (shiftForWord()))))); + objOop = longAt((objOop1 + BaseHeaderSize) + (((sqInt)((usqInt)(ValueIndex) << (shiftForWord()))))); + GIV(profileProcess) = longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(ActiveProcessIndex) << (shiftForWord()))))); + GIV(profileMethod) = (aCogMethodOrNil == null + ? GIV(newMethod) + : (aCogMethodOrNil->methodObject)); + forceInterruptCheck(); + /* begin zeroNextProfileTick */ + GIV(nextProfileTick) = 0; +} + /* CoInterpreter>>#ceTraceBlockActivation */ void ceTraceBlockActivation(void) @@ -17829,9 +17848,10 @@ checkCodeIntegrity(sqInt gcModes) /* In Spur a primitive may fail due to encountering a forwarder. On failure, - check the accessorDepth for the primitive and if non-negative scan the - args to the depth, following any forwarders. Answer if any are found so - the prim can be retried. The primitive index is derived from newMethod. + check the accessorDepth for the + primitive and if non-negative scan the args to the depth, following any + forwarders. Answer if any are found + so the prim can be retried. The primitive index is derived from newMethod. See http://www.mirandabanda.org/cogblog/2014/02/08/primitives-and-the-partial-read-barrier/ @@ -17861,7 +17881,7 @@ checkForAndFollowForwardedPrimitiveState(void) primTraceLogIndex(GIV(primTraceLogIndex) + 1); } assert(failed()); - found1 = (scannedStackFrame = 0); + found1 = 0; /* begin primitiveIndexOfMethod:header: */ assert(isCompiledMethod(GIV(newMethod))); header = longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)(HeaderIndex) << (shiftForWord()))))); @@ -17883,6 +17903,11 @@ checkForAndFollowForwardedPrimitiveState(void) } assert((GIV(argumentCount) == (argumentCountOf(GIV(newMethod)))) || (isMetaPrimitiveIndex(primIndex))); + if (((isCalloutPrimitiveIndex(primIndex)) + || (primIndex == PrimNumberDoExternalCall)) + && (unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(GIV(newMethod), primIndex))) { + found1 = 1; + } if ((isMetaPrimitiveIndex(primIndex)) && (GIV(metaAccessorDepth) > -2)) { accessorDepth = GIV(metaAccessorDepth); @@ -17890,7 +17915,7 @@ checkForAndFollowForwardedPrimitiveState(void) else { if ((primIndex == PrimNumberExternalCall) && (primitiveFunctionPointer != primitiveExternalCall)) { - accessorDepth = (((usqInt)((((fetchPointerofObject(2, literalofMethod(0, GIV(newMethod)))) >> 3)))) >> 8); + accessorDepth = ((((fetchPointerofObject(ExternalCallLiteralFlagsIndex, literalofMethod(0, GIV(newMethod)))) >> 3))) >> SpurPrimitiveAccessorDepthShift; } else { accessorDepth = primitiveAccessorDepthTable[primIndex]; @@ -17899,11 +17924,7 @@ checkForAndFollowForwardedPrimitiveState(void) assert(saneFunctionPointerForFailureOfPrimIndex(primIndex)); assert(((accessorDepth >= -1) && (accessorDepth <= 5))); if (accessorDepth >= 0) { - if (isCalloutPrimitiveIndex(primIndex)) { - if (followForwardedObjectFieldstoDepth(longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)((0 + LiteralStart)) << (shiftForWord()))))), accessorDepth)) { - found1 = 1; - } - } + scannedStackFrame = 0; for (index = 0; index <= GIV(argumentCount); index += 1) { oop = longAt(GIV(stackPointer) + (index * BytesPerWord)); if ((!(oop & (tagMask())))) { @@ -19074,10 +19095,12 @@ flushExternalPrimitives(void) sqInt prevObj; sqInt prevPrevObj; sqInt senderOop; + sqInt senderOop1; char *sp; char *sp1; sqInt startObject; - char *theFP; + char * theFP; + char *theFP1; char * theFrame; StackPage * thePage; char *theSP; @@ -19085,17 +19108,17 @@ flushExternalPrimitives(void) sqInt top1; /* begin divorceAllFramesSuchThat: */ - theFP = GIV(framePointer); + theFP1 = GIV(framePointer); theSP = GIV(stackPointer); - if (((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory()) - ? ((longAt(theFP + FoxMethod)) & MFMethodFlagHasContextFlag) != 0 - : (byteAt((theFP + FoxIFrameFlags) + 2)) != 0)) { - assert(isContext(frameContext(theFP))); - activeContext1 = longAt(theFP + FoxThisContext); - goto l12; - } - activeContext1 = marryFrameSP(theFP, theSP); - l12: /* end ensureFrameIsMarried:SP: */; + if (((((usqInt)(longAt(theFP1 + FoxMethod)))) < (startOfMemory()) + ? ((longAt(theFP1 + FoxMethod)) & MFMethodFlagHasContextFlag) != 0 + : (byteAt((theFP1 + FoxIFrameFlags) + 2)) != 0)) { + assert(isContext(frameContext(theFP1))); + activeContext1 = longAt(theFP1 + FoxThisContext); + goto l14; + } + activeContext1 = marryFrameSP(theFP1, theSP); + l14: /* end ensureFrameIsMarried:SP: */; /* begin ensurePushedInstructionPointer */ if ((((usqInt)GIV(instructionPointer))) >= (startOfMemory())) { @@ -19184,13 +19207,20 @@ flushExternalPrimitives(void) /* begin mapToBytecodePCIfActivationOfExternalMethod: */ if (isExternalMethodInPlugin(longAt((obj + BaseHeaderSize) + (((sqInt)((usqInt)(MethodIndex) << (shiftForWord()))))))) { if (((((longAt((obj + BaseHeaderSize) + (((sqInt)((usqInt)(SenderIndex) << (shiftForWord()))))))) & 7) == 1)) { - if (asserta(isWidowedContext(obj))) { - goto l15; + if (isWidowedContext(obj)) { + goto l17; + } + /* begin frameOfMarriedContext: */ + senderOop1 = longAt((obj + BaseHeaderSize) + (((sqInt)((usqInt)(SenderIndex) << (shiftForWord()))))); + assert((((senderOop1) & 7) == 1)); + theFP = pointerForOop(senderOop1 - 1); + if (!((((usqInt)(longAt(theFP + FoxMethod)))) < (startOfMemory()))) { + goto l17; } } ensureContextHasBytecodePC(obj); } - l15: /* end mapToBytecodePCIfActivationOfExternalMethod: */; + l17: /* end mapToBytecodePCIfActivationOfExternalMethod: */; } } } @@ -19702,24 +19732,6 @@ void forceInterruptCheckFromHeartbeat(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT if (!suppressHeartbeatFlag) { - /* begin checkForLongRunningPrimitive */ - if (GIV(longRunningPrimitiveCheckSemaphore) == null) { - goto l1; - } - if ((GIV(longRunningPrimitiveStartUsecs) > 0) - && ((GIV(longRunningPrimitiveCheckMethod) == GIV(newMethod)) - && (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)))) { - GIV(longRunningPrimitiveStopUsecs) = ioUTCMicroseconds(); - assert(GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)); - goto l1; - } - if (GIV(longRunningPrimitiveStopUsecs) == 0) { - GIV(longRunningPrimitiveCheckSequenceNumber) = GIV(statCheckForEvents); - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - GIV(longRunningPrimitiveStartUsecs) = ioUTCMicroseconds(); - sqLowLevelMFence(); - } - l1: /* end checkForLongRunningPrimitive */; sqLowLevelMFence(); if (GIV(deferSmash)) { GIV(deferredSmash) = 1; @@ -19819,38 +19831,25 @@ frameReceiver(char *theFP) void (*functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto(sqInt methodObj, sqInt primitiveIndex, sqInt *flagsPtr))(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - void (*addr)(); sqInt firstBytecode; sqInt firstLiteral; sqInt flags; - sqInt fmt; - sqInt fmt1; static void *function = (void *)-1; - sqInt functionLength; - sqInt functionName; void (*functionPointer)(void); void (*functionPointer1)(void); sqInt header; sqInt header1; - sqInt i; sqInt index; - sqInt index1; sqInt lit; sqInt lit1; - sqInt metadata; - sqInt moduleLength; - sqInt moduleName; - usqInt numSlots; - usqInt numSlots1; - usqInt numSlots11; - usqInt numSlots2; + sqInt metadataFlags; sqInt primIdx; sqInt shiftedMetadataFlags; sqInt targetFunctionIndex; - metadata = 0; + flags = 0; if (!(flagsPtr == null)) { - flagsPtr[0] = (primitivePropertyFlags(primitiveIndex)); + flagsPtr[0] = ((flags = primitivePropertyFlags(primitiveIndex))); } /* begin functionPointerFor:inClass: */ functionPointer = ((void (*)(void)) ((primitiveIndex > MaxPrimitiveIndex @@ -19892,120 +19891,25 @@ void (*functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto( targetFunctionIndex = longAt((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))); assert((((targetFunctionIndex) & 7) == 1)); if (((targetFunctionIndex >> 3)) == 0) { - /* begin linkExternalCall:ifFail: */ - moduleName = longAt((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralModuleNameIndex) << (shiftForWord()))))); - if (moduleName == GIV(nilObj)) { - moduleLength = 0; - } - else { - if (!(((!(moduleName & (tagMask())))) - && (((((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - goto l14; - } - /* begin lengthOf:format: */ - fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots1 = byteAt(moduleName + 7); - numSlots = (numSlots1 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(moduleName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots1); - if (fmt <= 5 /* ephemeronFormat */) { - moduleLength = numSlots; - goto l8; - } - if (fmt >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - moduleLength = (numSlots << (shiftForWord())) - (fmt & 7); - goto l8; - } - if (fmt >= (firstShortFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 1)) - (fmt & 3); - goto l8; - } - if (fmt >= (firstLongFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 2)) - (fmt & 1); - goto l8; - } - if (fmt == (sixtyFourBitIndexableFormat())) { - moduleLength = numSlots; - goto l8; - } - moduleLength = 0; - l8: /* end lengthOf:format: */; - } - /* begin fetchPointer:ofObject: */ - functionName = longAt((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFunctionNameIndex) << (shiftForWord()))))); - if (!(((!(functionName & (tagMask())))) - && (((((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - goto l14; - } - /* begin lengthOf:format: */ - fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots11 = byteAt(functionName + 7); - numSlots2 = (numSlots11 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(functionName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots11); - if (fmt1 <= 5 /* ephemeronFormat */) { - functionLength = numSlots2; - goto l10; - } - if (fmt1 >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - functionLength = (numSlots2 << (shiftForWord())) - (fmt1 & 7); - goto l10; - } - if (fmt1 >= (firstShortFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 1)) - (fmt1 & 3); - goto l10; - } - if (fmt1 >= (firstLongFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 2)) - (fmt1 & 1); - goto l10; - } - if (fmt1 == (sixtyFourBitIndexableFormat())) { - functionLength = numSlots2; - goto l10; - } - functionLength = 0; - l10: /* end lengthOf:format: */; - addr = ioLoadExternalFunctionOfLengthFromModuleOfLengthMetadataInto(functionName + BaseHeaderSize, functionLength, moduleName + BaseHeaderSize, moduleLength, (&metadata)); - if (addr == 0) { - index = -1; - } - else { + linkExternalCallerrInto(firstLiteral, null); + } + lit = firstLiteral; + metadataFlags = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord()))))); + if ((((metadataFlags) & 7) == 1)) { + shiftedMetadataFlags = (((sqInt)((usqInt)((((metadataFlags >> 3)) & SpurPrimitiveFlagsMask)) << PrimitiveMetadataFlagsShift))); + if (shiftedMetadataFlags > 0) { - /* add the function to the external primitive table */ - /* begin addToExternalPrimitiveTable: */ - for (i = GIV(externalPrimitiveTableFirstFreeIndex); i < MaxExternalPrimitiveTableSize; i += 1) { - if ((externalPrimitiveTable[i]) == 0) { - externalPrimitiveTable[i] = (((void *) addr)); - index = (GIV(externalPrimitiveTableFirstFreeIndex) = i + 1); - goto l13; - } - } - index = 0; - l13: /* end addToExternalPrimitiveTable: */; - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(firstLiteral))); - longAtput((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord())))), (((usqInt)metadata << 3) | 1)); + /* Intentionally clear all other flags if there are Spur metadata flags... */ + flags = shiftedMetadataFlags; } - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(firstLiteral))); - longAtput((firstLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), (((usqInt)index << 3) | 1)); - rewriteMethodCacheEntryForExternalPrimitiveToFunction((index >= 0 - ? addr - : 0)); - l14: /* end linkExternalCall:ifFail: */; } - lit = firstLiteral; - flags = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord()))))); - if ((((flags) & 7) == 1)) { - shiftedMetadataFlags = (((sqInt)((usqInt)((((flags >> 3)) & 0xFF)) << PrimitiveMetadataFlagsShift))); - flagsPtr[0] = ((flagsPtr[0]) | shiftedMetadataFlags); + if (objectequalsString(longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))), primitiveProfileSemaphore)) { + flags = flags | PrimCallMayEndureCodeCompaction; + } + if (GIV(profileSemaphore) != GIV(nilObj)) { + flags = flags | PrimCallCollectsProfileSamples; } + flagsPtr[0] = flags; /* begin functionForPrimitiveExternalCall: */ if (!((literalCountOfMethodHeader(methodHeaderOf(methodObj))) > 0)) { return ((void (*)(void)) primitiveExternalCall); @@ -20017,13 +19921,13 @@ void (*functionPointerForCompiledMethodprimitiveIndexprimitivePropertyFlagsInto( && ((lengthOfformat(lit1, (((usqInt)((longAt(lit1)))) >> (formatShift())) & (formatMask()))) == 4))) { return ((void (*)(void)) primitiveExternalCall); } - index1 = longAt((lit1 + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))); - if (!(((((index1) & 7) == 1)) - && ((((index1 = (index1 >> 3))) > 0) - && (index1 <= MaxExternalPrimitiveTableSize)))) { + index = longAt((lit1 + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord()))))); + if (!(((((index) & 7) == 1)) + && ((((index = (index >> 3))) > 0) + && (index <= MaxExternalPrimitiveTableSize)))) { return ((void (*)(void)) primitiveExternalCall); } - functionPointer1 = externalPrimitiveTable[index1 - 1]; + functionPointer1 = externalPrimitiveTable[index - 1]; if (functionPointer1 == 0) { return ((void (*)(void)) primitiveExternalCall); } @@ -20450,8 +20354,13 @@ interpretMethodFromMachineCode(void) compute a bytecode pc and hence may provoke a code compaction. Hence primitive invocation from these primitives must use a static return address - (cePrimReturnEnterCogCode:). - */ + (cePrimReturnEnterCogCode:). Note that the process switch primitives may + also provoke a code compaction, which + happens when switching to a process whose top context has a machine code + pc but + the method is no longer in the code cache. However, in this case they are + switching process and don't go through the normal return. So we don't + include them here. */ /* CoInterpreter>>#isCodeCompactingPrimitiveIndex: */ static sqInt NoDbgRegParms @@ -20459,7 +20368,9 @@ isCodeCompactingPrimitiveIndex(sqInt primIndex) { return (primIndex == PrimNumberInstVarAt) || ((primIndex == PrimNumberShallowCopy) - || (primIndex == PrimNumberSlotAt)); + || ((primIndex == PrimNumberSlotAt) + || ((primIndex == PrimNumberFlushExternalPrimitives) + || (primIndex == PrimNumberUnoadModule)))); } /* CoInterpreter>>#isCogMethodReference: */ @@ -21774,10 +21685,11 @@ methodHasCogMethod(sqInt aMethodOop) static sqInt NoDbgRegParms NeverInline methodHasPrimitiveInPrimTracePlugin(sqInt aMethodObj) { - sqInt fmt; + sqInt aCStringStrlen; sqInt lit; - sqInt nameLength; + sqInt ok; sqInt pluginName; + sqInt size; if (!(((primitiveIndexOf(aMethodObj)) == PrimNumberExternalCall) && ((literalCountOfMethodHeader(methodHeaderOf(aMethodObj))) > 0))) { @@ -21796,12 +21708,13 @@ methodHasPrimitiveInPrimTracePlugin(sqInt aMethodObj) && (((((usqInt)((longAt(pluginName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { return 0; } - /* begin numBytesOfBytes: */ - fmt = (((usqInt)((longAt(pluginName)))) >> (formatShift())) & (formatMask()); - assert(fmt >= (firstByteFormat())); - nameLength = ((numSlotsOf(pluginName)) << (shiftForWord())) - (fmt & 7); - return ((strncmp(primTracePluginName, firstIndexableField(pluginName), nameLength)) == 0) - && ((strlen(primTracePluginName)) == nameLength); + /* begin object:equalsString:ofSize: */ + aCStringStrlen = strlen(primTracePluginName); + ok = (((!(pluginName & (tagMask())))) + && (((((usqInt)((longAt(pluginName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(pluginName))) == aCStringStrlen) + && ((strncmp(primTracePluginName, firstIndexableField(pluginName), aCStringStrlen)) == 0)); + return ok; } /* CoInterpreter>>#methodNeedsLargeContext: */ @@ -21944,13 +21857,13 @@ mframeReceiver(char *theFP) checking that there is enough headroom allocated in stack pages. */ /* CoInterpreter>>#minimumUnusedHeadroom */ -static sqInt +static sqInt NeverInline minimumUnusedHeadroom(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt i; int minUnused; char *p; - StackPage *page; + StackPage * page; int unused; minUnused = (((stackPageAt(0))->baseAddress)) - (((stackPageAt(0))->lastAddress)); @@ -22836,7 +22749,7 @@ primitivePropertyFlags(sqInt primIndex) /* begin primitivePropertyFlagsForSpur: */ if (primIndex == PrimNumberHashMultiply) { - return PrimCallOnSmalltalkStack; + return PrimCallOnSmalltalkStack + FastCPrimitiveUseCABIFlag; } baseFlags = PrimCallNeedsPrimitiveFunction + PrimCallNeedsNewMethod; if (GIV(profileSemaphore) != GIV(nilObj)) { @@ -23956,7 +23869,7 @@ readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squea /* default */ GIV(thisClassIndex) = 5; - for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (lengthOfformat(classArrayClass, (((usqInt)((longAt(classArrayClass)))) >> (formatShift())) & (formatMask()))); i1 <= iLimiT; i1 += 1) { + for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (numSlotsOf(classArrayClass)); i1 <= iLimiT; i1 += 1) { if ((longAt((classArrayClass + BaseHeaderSize) + (((sqInt)((usqInt)((i1 - 1)) << (shiftForWord())))))) == classArrayObj) { GIV(thisClassIndex) = i1 - 1; } @@ -23964,13 +23877,10 @@ readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squea /* default */ GIV(classNameIndex) = 6; - for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (lengthOfformat(classArrayObj, (((usqInt)((longAt(classArrayObj)))) >> (formatShift())) & (formatMask()))); i1 <= iLimiT; i1 += 1) { + for (i1 = (InstanceSpecificationIndex + 1), iLimiT = (numSlotsOf(classArrayObj)); i1 <= iLimiT; i1 += 1) { /* begin fetchPointer:ofObject: */ oop = longAt((classArrayObj + BaseHeaderSize) + (((sqInt)((usqInt)((i1 - 1)) << (shiftForWord()))))); - if ((((!(oop & (tagMask())))) - && (((((usqInt)((longAt(oop)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) - && (((lengthOfformat(oop, (((usqInt)((longAt(oop)))) >> (formatShift())) & (formatMask()))) == 5) - && ((strncmp("Array", firstFixedField(oop), 5)) == 0))) { + if (objectequalsStringofSize(oop, "Array", strlen("Array"))) { GIV(classNameIndex) = i1 - 1; } } @@ -23997,6 +23907,23 @@ readImageFromFileHeapSizeStartingAt(sqImageFile f, usqInt desiredHeapSize, squea } +/* This is a little elaborate. The primTraceLog is only useful if it is not + full of noise. + To reduce noise when debugging a specific plugin we allow a plugin name to + be specified and will only generate the primTraceLog code for primitives + in that plugin. */ + + /* CoInterpreter>>#recordFastCCallPrimTraceForMethod: */ +sqInt +recordFastCCallPrimTraceForMethod(sqInt aMethodObj) +{ + return (recordFastCCallPrimTrace()) + && ((primTracePluginName == null + ? 1 + : methodHasPrimitiveInPrimTracePlugin(aMethodObj))); +} + + /* This is a little elaborate. The primTraceLog is only useful if it is not full of noise. To reduce noise when debugging a specific plugin we allow a plugin name to @@ -26466,56 +26393,6 @@ primitiveFunctionPointerAddress(void) return ((usqInt)((&primitiveFunctionPointer))); } - -/* Primitive. Install the semaphore to be used for collecting long-running - primitives, - or nil if no semaphore should be used. */ - - /* CoInterpreterPrimitives>>#primitiveLongRunningPrimitiveSemaphore */ -EXPORT(sqInt) -primitiveLongRunningPrimitiveSemaphore(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; - int flushState; - sqInt sema; - char *sp; - - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } - sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - if (sema == GIV(nilObj)) { - flushState = GIV(longRunningPrimitiveCheckSemaphore) != null; - GIV(longRunningPrimitiveCheckSemaphore) = null; - } - else { - flushState = GIV(longRunningPrimitiveCheckSemaphore) == null; - if (!(((!(sema & (tagMask())))) - && (((longAt(sema)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))))) { - return (GIV(primFailCode) = PrimErrBadArgument); - } - GIV(longRunningPrimitiveCheckSemaphore) = sema; - } - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(longRunningPrimitiveCheckSemaphore) == null)) - || (((stackValue(0)) == GIV(longRunningPrimitiveCheckSemaphore)) - && (isSemaphoreOop(sema)))); - } - voidLongRunningPrimitive("install"); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - if (flushState) { - ceInvokeInterpret(); - } - return 0; -} - /* CoInterpreterPrimitives>>#primitiveMethodPCData */ EXPORT(sqInt) primitiveMethodPCData(void) @@ -26828,14 +26705,9 @@ primitiveObjectAtPut(void) EXPORT(sqInt) primitiveProfileSemaphore(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt activeContext; int flushState; sqInt sema; - char *sp; - if (GIV(argumentCount) != 1) { - return (GIV(primFailCode) = PrimErrBadNumArgs); - } sema = longAt(GIV(stackPointer) + (0 * BytesPerWord)); if (sema == GIV(nilObj)) { flushState = GIV(profileSemaphore) != GIV(nilObj); @@ -26847,28 +26719,21 @@ primitiveProfileSemaphore(void) return (GIV(primFailCode) = PrimErrBadArgument); } } + GIV(profileSemaphore) = sema; /* If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in. */ - GIV(profileSemaphore) = sema; - if (flushState) { - /* begin push: */ - longAtput((sp = GIV(stackPointer) - BytesPerWord), GIV(instructionPointer)); - GIV(stackPointer) = sp; - activeContext = voidVMStateForSnapshotFlushingExternalPrimitivesIf(0); - marryContextInNewStackPageAndInitializeInterpreterRegisters(activeContext); - assert((((stackValue(0)) == (nilObject())) - && (GIV(profileSemaphore) == (nilObject()))) - || (((stackValue(0)) == GIV(profileSemaphore)) - && (isSemaphoreOop(sema)))); - } GIV(profileProcess) = (GIV(profileMethod) = GIV(nilObj)); - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; if (flushState) { - ceInvokeInterpret(); + flushExternalPrimitives(); + } + else { + /* begin methodReturnReceiver */ + assert(!((failed()))); + /* begin pop: */ + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; } return 0; } @@ -30441,7 +30306,7 @@ primitiveCalloutToFFI(void) } } else { - primitiveCallout(); + dispatchFunctionPointer(primitiveCallout); } } @@ -34448,26 +34313,28 @@ primitiveHighBit(void) } -/* Return the value of the high resolution clock if this system has any. The - exact frequency of the high res clock is undefined specifically so that we - can use processor dependent instructions (like RDTSC). The only use for - the high res clock is for profiling where we can allocate time based on - sub-msec resolution of the high res clock. If no high-resolution counter - is available, the platform should return zero. - */ +/* Return the value of the high resolution clock if this system has any. + The exact frequency of the high res clock is undefined specifically so + that we can use + processor dependent instructions (like RDTSC). The only use for the high + res clock is for + profiling where we can allocate time based on sub-msec resolution of the + high res clock. + If no high-resolution counter is available, the platform should return + zero. ar 6/22/2007 */ /* InterpreterPrimitives>>#primitiveHighResClock */ EXPORT(sqInt) primitiveHighResClock(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt object; + sqInt oop; char *sp; - /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; - /* begin push: */ - object = positive64BitIntegerFor(ioHighResClock()); - longAtput((sp = GIV(stackPointer) - BytesPerWord), object); + /* begin methodReturnValue: */ + oop = positive64BitIntegerFor(ioHighResClock()); + assert(!((failed()))); + /* begin pop:thenPush: */ + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), oop); GIV(stackPointer) = sp; return 0; } @@ -37124,15 +36991,10 @@ primitiveProfilePrimitive(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileMethod)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileMethod)); GIV(stackPointer) = sp; GIV(profileMethod) = GIV(nilObj); return 0; @@ -37150,15 +37012,10 @@ primitiveProfileSample(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT char *sp; - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } + /* begin methodReturnValue: */ + assert(!((failed()))); /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), GIV(profileProcess)); + longAtput((sp = GIV(stackPointer) + (((GIV(argumentCount) + 1) - 1) * BytesPerWord)), GIV(profileProcess)); GIV(stackPointer) = sp; GIV(profileProcess) = GIV(nilObj); return 0; @@ -37182,39 +37039,18 @@ EXPORT(sqInt) primitiveProfileStart(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt deltaTicks; - sqInt integerPointer; - if (!(GIV(argumentCount) == 1)) { - /* begin success: */ - - /* Don't overwrite an error code that has already been set. */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - /* begin stackIntegerValue: */ - integerPointer = longAt(GIV(stackPointer) + (0 * BytesPerWord)); - /* begin checkedIntegerValueOf: */ - if ((((integerPointer) & 7) == 1)) { - deltaTicks = (integerPointer >> 3); - goto l2; - } - else { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - deltaTicks = 0; - goto l2; - } - l2: /* end stackIntegerValue: */; - if (!GIV(primFailCode)) { - GIV(nextProfileTick) = (ioHighResClock()) + deltaTicks; + deltaTicks = longAt(GIV(stackPointer) + (0 * BytesPerWord)); + if ((((deltaTicks) & 7) == 1)) { + GIV(nextProfileTick) = (ioHighResClock()) + ((deltaTicks >> 3)); + /* begin methodReturnReceiver */ + assert(!((failed()))); /* begin pop: */ - GIV(stackPointer) += 1 * BytesPerWord; + GIV(stackPointer) += GIV(argumentCount) * BytesPerWord; + return 0; } - return 0; + /* begin primitiveFailFor: */ + return (GIV(primFailCode) = PrimErrBadArgument); } /* InterpreterPrimitives>>#primitiveQuit */ @@ -41705,7 +41541,7 @@ followForwardedObjectFieldstoDepth(sqInt objOop, sqInt depth) sqInt header1; sqInt i; sqInt numLiterals; - sqInt numSlots; + usqInt numSlots; usqInt numSlots1; sqInt oop; sqInt referent; @@ -49142,7 +48978,7 @@ copyObjtoAddrstopAtsavedFirstFieldsindex(sqInt objOop, sqInt segAddr, sqInt endS sqInt iLimiT; sqInt methodHeader; sqInt numLiterals; - sqInt numMediatedSlots; + usqInt numMediatedSlots; usqInt numSlots; usqInt numSlots1; sqInt oop; @@ -50304,17 +50140,18 @@ findLargestFreeChunk(void) void findStringBeginningWith(char *aCString) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt aCStringStrlen; sqInt address; - sqInt cssz; sqInt followingWord; usqInt followingWordAddress; usqInt numSlots; sqInt obj1; sqInt prevObj; sqInt prevPrevObj; + sqInt size; sqInt startObject; - cssz = strlen(aCString); + aCStringStrlen = strlen(aCString); /* begin allObjectsDo: */ address = (GIV(pastSpaceStart) > (((pastSpace()).start)) ? ((pastSpace()).start) @@ -50335,9 +50172,10 @@ findStringBeginningWith(char *aCString) if (!(oopisLessThan(obj1, GIV(endOfMemory)))) break; assert((long64At(obj1)) != 0); if (isEnumerableObject(obj1)) { - if ((((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())) - && (((lengthOfformat(obj1, (((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask()))) >= cssz) - && ((strncmp(aCString, pointerForOop(obj1 + BaseHeaderSize), cssz)) == 0))) { + if ((((!(obj1 & (tagMask())))) + && (((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(obj1))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(obj1), aCStringStrlen)) == 0))) { printHex(obj1); /* begin space */ putchar(' '); @@ -50379,17 +50217,18 @@ findStringBeginningWith(char *aCString) void findString(char *aCString) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt aCStringStrlen; sqInt address; - sqInt cssz; sqInt followingWord; usqInt followingWordAddress; usqInt numSlots; sqInt obj1; sqInt prevObj; sqInt prevPrevObj; + sqInt size; sqInt startObject; - cssz = strlen(aCString); + aCStringStrlen = strlen(aCString); /* begin allObjectsDo: */ address = (GIV(pastSpaceStart) > (((pastSpace()).start)) ? ((pastSpace()).start) @@ -50410,9 +50249,10 @@ findString(char *aCString) if (!(oopisLessThan(obj1, GIV(endOfMemory)))) break; assert((long64At(obj1)) != 0); if (isEnumerableObject(obj1)) { - if ((((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())) - && (((lengthOfformat(obj1, (((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask()))) == cssz) - && ((strncmp(aCString, pointerForOop(obj1 + BaseHeaderSize), cssz)) == 0))) { + if ((((!(obj1 & (tagMask())))) + && (((((usqInt)((longAt(obj1)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(obj1))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(obj1), aCStringStrlen)) == 0))) { printHex(obj1); /* begin space */ putchar(' '); @@ -52581,14 +52421,6 @@ isSegmentBridge(sqInt objOop) return ((longAt(objOop)) & (classIndexMask())) == (segmentBridgePun()); } - /* SpurMemoryManager>>#isSemaphoreOop: */ -static sqInt NoDbgRegParms -isSemaphoreOop(sqInt anOop) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - return ((!(anOop & (tagMask())))) - && (((longAt(anOop)) & (classIndexMask())) == (rawHashBitsOf(longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (((sqInt)((usqInt)(ClassSemaphore) << (shiftForWord())))))))); -} - /* Answer if the argument contains only indexable 16-bit half words (no oops). See comment in formatOf: @@ -54868,8 +54700,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) sqInt referent; sqInt referent1; sqInt referent2; - sqInt referent3; - sqInt referent4; sqInt sizeOfUnusedEden; StackPage *thePage; @@ -55008,38 +54838,6 @@ markObjects(sqInt objectsShouldBeUnmarkedAndUnmarkedClassesShouldBeExpunged) markAndTrace(GIV(profileProcess)); markAndTrace(GIV(profileMethod)); markAndTrace(GIV(profileSemaphore)); - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveCheckMethod) != null) - && (GIV(longRunningPrimitiveCheckSequenceNumber) != GIV(statCheckForEvents))) { - if ((!((longAt(GIV(longRunningPrimitiveCheckMethod))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckMethod))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((GIV(longRunningPrimitiveCheckMethod) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent3 & (tagMask())))) - && ((!((longAt(referent3)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent3 = longAt((referent3 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckMethod) = referent3; - } - markAndTrace(GIV(longRunningPrimitiveCheckMethod)); - } - if (GIV(longRunningPrimitiveCheckSemaphore) != null) { - if ((!((longAt(GIV(longRunningPrimitiveCheckSemaphore))) & ((classIndexMask()) - (isForwardedObjectClassIndexPun()))))) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(GIV(longRunningPrimitiveCheckSemaphore))); - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((GIV(longRunningPrimitiveCheckSemaphore) + BaseHeaderSize) + (0U << (shiftForWord()))); - while (((!(referent4 & (tagMask())))) - && ((!((longAt(referent4)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { - /* begin fetchPointer:ofMaybeForwardedObject: */ - referent4 = longAt((referent4 + BaseHeaderSize) + (0U << (shiftForWord()))); - } - GIV(longRunningPrimitiveCheckSemaphore) = referent4; - } - markAndTrace(GIV(longRunningPrimitiveCheckSemaphore)); - } if (!(GIV(tempOop) == 0)) { markAndTrace(GIV(tempOop)); } @@ -55692,7 +55490,7 @@ numBytesOf(sqInt objOop) Works with CompiledMethods, as well as ordinary objects. */ /* SpurMemoryManager>>#numPointerSlotsOf: */ -sqInt +usqInt numPointerSlotsOf(sqInt objOop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt contextSize; @@ -56527,8 +56325,8 @@ outOfPlaceBecomeandcopyHashFlag(sqInt obj1, sqInt obj2, sqInt copyHashFlag) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classIndex; sqInt classIndex1; - usqInt clone1; - usqInt clone2; + sqInt clone1; + sqInt clone2; sqInt format; sqInt format1; sqInt hash; @@ -58702,7 +58500,7 @@ printReferencesTo(sqInt anOop) assert((ReceiverIndex + ((sp >> 3))) < (lengthOf(obj1))); contextSize = (sp >> 3); l9: /* end fetchStackPointerOf: */; - i = CtxtTempFrameStart + contextSize; + i = ((usqInt) (CtxtTempFrameStart + contextSize)); goto l10; } /* begin numSlotsOf: */ @@ -58735,7 +58533,7 @@ printReferencesTo(sqInt anOop) /* begin literalCountOfMethodHeader: */ assert((((header) & 7) == 1)); numLiterals = ((header >> 3)) & AlternateHeaderNumLiteralsMask; - i = numLiterals + LiteralStart; + i = ((usqInt) (numLiterals + LiteralStart)); l10: /* end numPointerSlotsOf: */; while (((i -= 1)) >= 0) { if (anOop == (longAt((obj1 + BaseHeaderSize) + (((sqInt)((usqInt)(i) << (shiftForWord()))))))) { @@ -61928,10 +61726,10 @@ updatePointers(void) sqInt numLiterals1; sqInt numLiterals2; sqInt numLiterals3; - sqInt numPointerSlots; - sqInt numPointerSlots1; - sqInt numPointerSlots2; - sqInt numPointerSlots3; + usqInt numPointerSlots; + usqInt numPointerSlots1; + usqInt numPointerSlots2; + usqInt numPointerSlots3; usqInt numSlots; usqInt numSlots1; usqInt numSlots11; @@ -64022,33 +63820,6 @@ checkAllAccessibleObjectsOkay(void) } -/* Check for a hit of the longRunningPrimitive probe and if so attempt to - signal the - longRunningPrimitiveCheckSemaphore. Answer if a process switch occurred as - a result. */ - - /* StackInterpreter>>#checkDeliveryOfLongRunningPrimitiveSignal */ -static sqInt -checkDeliveryOfLongRunningPrimitiveSignal(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((GIV(longRunningPrimitiveCheckSemaphore) != null) - && (GIV(longRunningPrimitiveSignalUndelivered)))) { - - /* but not yet delivered */ - GIV(longRunningPrimitiveSignalUndelivered) = 0; - - /* Signal the LRP check semaphore if it is present */ - GIV(longRunningPrimitiveGCUsecs) = ((GIV(gcStartUsecs) < GIV(longRunningPrimitiveStopUsecs)) - && (GIV(statGCEndUsecs) > GIV(longRunningPrimitiveStartUsecs)) - ? GIV(statGCEndUsecs) - GIV(gcStartUsecs) - : 0); - return synchronousSignal(GIV(longRunningPrimitiveCheckSemaphore)); - } - return 0; -} - - /* Note: May be called by translated primitive code. */ /* StackInterpreter>>#checkedIntegerValueOf: */ @@ -64121,10 +63892,7 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) if ((GIV(profileProcess) != GIV(nilObj)) || ((GIV(nextProfileTick) > 0) && ((ioHighResClock()) >= GIV(nextProfileTick)))) { - - /* Take a sample (if not already done so) for the profiler if it is active. This - must be done before any of the synchronousSignals below or else we will - attribute a pause in ioRelinquishProcessor to the newly activated process. */ + /* begin zeroNextProfileTick */ GIV(nextProfileTick) = 0; if (GIV(profileProcess) == GIV(nilObj)) { /* begin activeProcess */ @@ -64139,9 +63907,6 @@ checkForEventsMayContextSwitch(sqInt mayContextSwitch) switched = 1; } } - if (checkDeliveryOfLongRunningPrimitiveSignal()) { - switched = 1; - } if (GIV(signalLowSpace)) { /* begin signalLowSpace: */ GIV(signalLowSpace) = 0; @@ -64547,6 +64312,7 @@ checkProfileTick(sqInt aPrimitiveMethod) GIV(profileMethod) = GIV(nilObj); } forceInterruptCheck(); + /* begin zeroNextProfileTick */ GIV(nextProfileTick) = 0; } } @@ -64674,12 +64440,13 @@ checkStackPointerIndexForFrame(char *theFP) static sqInt NoDbgRegParms classNameOfIs(sqInt aClass, char *className) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt fmt; sqInt i; sqInt length; sqInt name; char *srcName; - if ((lengthOfformat(aClass, (((usqInt)((longAt(aClass)))) >> (formatShift())) & (formatMask()))) <= GIV(classNameIndex)) { + if ((numSlotsOf(aClass)) <= GIV(classNameIndex)) { return 0; } /* begin fetchPointer:ofObject: */ @@ -64688,7 +64455,10 @@ classNameOfIs(sqInt aClass, char *className) && (((((usqInt)((longAt(name)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { return 0; } - length = stSizeOf(name); + /* begin numBytesOfBytes: */ + fmt = (((usqInt)((longAt(name)))) >> (formatShift())) & (formatMask()); + assert(fmt >= (firstByteFormat())); + length = ((numSlotsOf(name)) << (shiftForWord())) - (fmt & 7); srcName = ((char *) (arrayValueOf(name))); for (i = 0; i < length; i += 1) { if (!((srcName[i]) == (className[i]))) { @@ -69905,23 +69675,6 @@ mapInterpreterOops(void) if (shouldRemapObj(GIV(profileSemaphore))) { GIV(profileSemaphore) = remapObj(GIV(profileSemaphore)); } - sqLowLevelMFence(); - if (!(GIV(longRunningPrimitiveCheckMethod) == null)) { - if (GIV(longRunningPrimitiveCheckSequenceNumber) == GIV(statCheckForEvents)) { - GIV(longRunningPrimitiveCheckMethod) = GIV(newMethod); - } - else { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckMethod))) { - GIV(longRunningPrimitiveCheckMethod) = remapObj(GIV(longRunningPrimitiveCheckMethod)); - } - } - sqLowLevelMFence(); - } - if (!(GIV(longRunningPrimitiveCheckSemaphore) == null)) { - if (shouldRemapObj(GIV(longRunningPrimitiveCheckSemaphore))) { - GIV(longRunningPrimitiveCheckSemaphore) = remapObj(GIV(longRunningPrimitiveCheckSemaphore)); - } - } /* begin remapCallbackState */ for (i = 1; i <= GIV(jmpDepth); i += 1) { oop = GIV(suspendedCallbacks)[i]; @@ -70798,6 +70551,33 @@ objCouldBeClassObj(sqInt objOop) && (((((longAt((objOop + BaseHeaderSize) + (((sqInt)((usqInt)(InstanceSpecificationIndex) << (shiftForWord()))))))) & 7) == 1))))))); } + /* StackInterpreter>>#object:equalsString: */ +static sqInt NoDbgRegParms +objectequalsString(sqInt anOop, sqInt aCString) +{ + sqInt aCStringStrlen; + sqInt size; + + /* begin object:equalsString:ofSize: */ + aCStringStrlen = strlen(aCString); + return (((!(anOop & (tagMask())))) + && (((((usqInt)((longAt(anOop)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(anOop))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(anOop), aCStringStrlen)) == 0)); +} + + /* StackInterpreter>>#object:equalsString:ofSize: */ +static sqInt NoDbgRegParms +objectequalsStringofSize(sqInt anOop, sqInt aCString, sqInt aCStringStrlen) +{ + sqInt size; + + return (((!(anOop & (tagMask())))) + && (((((usqInt)((longAt(anOop)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat()))) + && ((((size = numBytesOfBytes(anOop))) == aCStringStrlen) + && ((strncmp(aCString, firstIndexableField(anOop), aCStringStrlen)) == 0)); +} + /* This is the entry-point for plugins and primitives that wish to reacquire the VM after having @@ -74026,8 +73806,8 @@ printStackReferencesTo(sqInt oop) static void NoDbgRegParms printStringOf(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT - sqInt aByte; sqInt cnt; + sqInt code; sqInt fmt; sqInt i; sqInt len; @@ -74056,18 +73836,20 @@ printStringOf(sqInt oop) } else { while (i < cnt) { - if ((byteAt((oop + BaseHeaderSize) + i)) == 13) { - - /* Character cr asInteger */ + /* begin fetchByte:ofObject: */ + code = byteAt((oop + BaseHeaderSize) + i); + switch (code) { + case 10: + print(""); + break; + case 13: print(""); - if ((i + 1) < len) { - print("..."); - } - return; + break; + default: + /* begin printChar: */ + putchar(code); + } - /* begin printChar: */ - aByte = byteAt((oop + BaseHeaderSize) + i); - putchar(aByte); i += 1; } } @@ -74646,7 +74428,7 @@ retryPrimitiveOnFailure(void) primTraceLogIndex(GIV(primTraceLogIndex) + 1); } assert(failed()); - found1 = (scannedStackFrame = 0); + found1 = 0; /* begin primitiveIndexOfMethod:header: */ assert(isCompiledMethod(GIV(newMethod))); header = longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)(HeaderIndex) << (shiftForWord()))))); @@ -74668,6 +74450,11 @@ retryPrimitiveOnFailure(void) } assert((GIV(argumentCount) == (argumentCountOf(GIV(newMethod)))) || (isMetaPrimitiveIndex(primIndex))); + if (((isCalloutPrimitiveIndex(primIndex)) + || (primIndex == PrimNumberDoExternalCall)) + && (unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(GIV(newMethod), primIndex))) { + found1 = 1; + } if ((isMetaPrimitiveIndex(primIndex)) && (GIV(metaAccessorDepth) > -2)) { accessorDepth = GIV(metaAccessorDepth); @@ -74675,7 +74462,7 @@ retryPrimitiveOnFailure(void) else { if ((primIndex == PrimNumberExternalCall) && (primitiveFunctionPointer != primitiveExternalCall)) { - accessorDepth = (((usqInt)((((fetchPointerofObject(2, literalofMethod(0, GIV(newMethod)))) >> 3)))) >> 8); + accessorDepth = ((((fetchPointerofObject(ExternalCallLiteralFlagsIndex, literalofMethod(0, GIV(newMethod)))) >> 3))) >> SpurPrimitiveAccessorDepthShift; } else { accessorDepth = primitiveAccessorDepthTable[primIndex]; @@ -74684,11 +74471,7 @@ retryPrimitiveOnFailure(void) assert(saneFunctionPointerForFailureOfPrimIndex(primIndex)); assert(((accessorDepth >= -1) && (accessorDepth <= 5))); if (accessorDepth >= 0) { - if (isCalloutPrimitiveIndex(primIndex)) { - if (followForwardedObjectFieldstoDepth(longAt((GIV(newMethod) + BaseHeaderSize) + (((sqInt)((usqInt)((0 + LiteralStart)) << (shiftForWord()))))), accessorDepth)) { - found1 = 1; - } - } + scannedStackFrame = 0; for (index = 0; index <= GIV(argumentCount); index += 1) { oop = longAt(GIV(stackPointer) + (index * BytesPerWord)); if ((!(oop & (tagMask())))) { @@ -77046,6 +76829,42 @@ ultimateLiteralOf(sqInt aMethodOop) } +/* Follow the first literal of either a primitiveCallout or + primitiveExternalCall primitive method. This + will be an ExternalFunction for primitiveCallout or a four element Array + for primitiveExternalCall. + This is here to avoid following all the literals in a method, which would + be slow. Remember + forwarders are unlikely, so we only want to follow what is necessary, and + for an FFI call or + external primitive only the first literal is salient. */ + + /* StackInterpreter>>#unfollowFirstLiteralOfMaybeCalloutMethod:primitiveIndex: */ +static sqInt NoDbgRegParms +unfollowFirstLiteralOfMaybeCalloutMethodprimitiveIndex(sqInt methodObj, sqInt primIndex) +{ + sqInt firstLiteral; + sqInt found; + + + /* inlined self literal: 0 ofMethod: methodObj for clarity... */ + found = 0; + /* begin fetchPointer:ofObject: */ + firstLiteral = longAt((methodObj + BaseHeaderSize) + (((sqInt)((usqInt)(LiteralStart) << (shiftForWord()))))); + if (((!(firstLiteral & (tagMask())))) + && ((!((longAt(firstLiteral)) & ((classIndexMask()) - (isForwardedObjectClassIndexPun())))))) { + found = 1; + firstLiteral = fixFollowedFieldofObjectwithInitialValue(LiteralStart, methodObj, firstLiteral); + } + if (followForwardedObjectFieldstoDepth(firstLiteral, (primIndex == PrimNumberFFICall + ? (primitiveAccessorDepthTable[primIndex]) - 1 + : 0))) { + found = 1; + } + return found; +} + + /* So rare it mustn't bulk up the common path */ /* StackInterpreter>>#unfollow:atIndex: */ @@ -77181,22 +77000,6 @@ validStackPageBaseFrames(void) } -/* Void the state associated with the long-running primitive check. - This is done when a new semaphore is installed or when it appears - that is longRunningPrimitiveCheckMethod is invalid, e.g. because it - has eben sampled in the middle of a GC. */ - - /* StackInterpreter>>#voidLongRunningPrimitive: */ -static void NoDbgRegParms NeverInline -voidLongRunningPrimitive(char *reason) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - GIV(longRunningPrimitiveCheckMethod) = null; - GIV(longRunningPrimitiveStartUsecs) = (GIV(longRunningPrimitiveStopUsecs) = 0); - GIV(longRunningPrimitiveSignalUndelivered) = 1; - sqLowLevelMFence(); -} - - /* Return the highest priority process that is ready to run. To save time looking at many empty lists before finding a runnable process the VM maintains a variable holding the @@ -77579,6 +77382,87 @@ isAppropriateForCopyObject(sqInt oop) return 1; } + +/* The function has not been loaded yet. Fetch module and function name. */ + + /* StackInterpreterPrimitives>>#linkExternalCall:errInto: */ +static void (*linkExternalCallerrInto(sqInt externalCallLiteral, sqInt *failPtr))() + +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + void (*addr)(); + sqInt fmt; + sqInt fmt1; + sqInt functionLength; + sqInt functionName; + sqInt i; + sqInt index; + sqInt metadata; + sqInt moduleLength; + sqInt moduleName; + + metadata = 0; + /* begin fetchPointer:ofObject: */ + moduleName = longAt((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralModuleNameIndex) << (shiftForWord()))))); + if (moduleName == GIV(nilObj)) { + moduleLength = 0; + } + else { + if (!(((!(moduleName & (tagMask())))) + && (((((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { + if (!(failPtr == null)) { + failPtr[0] = PrimErrBadMethod; + } + return 0; + } + /* begin numBytesOfBytes: */ + fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); + assert(fmt >= (firstByteFormat())); + moduleLength = ((numSlotsOf(moduleName)) << (shiftForWord())) - (fmt & 7); + } + /* begin fetchPointer:ofObject: */ + functionName = longAt((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFunctionNameIndex) << (shiftForWord()))))); + if (!(((!(functionName & (tagMask())))) + && (((((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { + if (!(failPtr == null)) { + failPtr[0] = PrimErrBadMethod; + } + return 0; + } + /* begin numBytesOfBytes: */ + fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); + assert(fmt1 >= (firstByteFormat())); + functionLength = ((numSlotsOf(functionName)) << (shiftForWord())) - (fmt1 & 7); + addr = ioLoadExternalFunctionOfLengthFromModuleOfLengthMetadataInto(functionName + BaseHeaderSize, functionLength, moduleName + BaseHeaderSize, moduleLength, (&metadata)); + if (addr == 0) { + index = -1; + } + else { + + /* add the function to the external primitive table */ + assert(((((metadata) >> SpurPrimitiveAccessorDepthShift) >= -1) && (((metadata) >> SpurPrimitiveAccessorDepthShift) <= 5))); + /* begin addToExternalPrimitiveTable: */ + for (i = GIV(externalPrimitiveTableFirstFreeIndex); i < MaxExternalPrimitiveTableSize; i += 1) { + if ((externalPrimitiveTable[i]) == 0) { + externalPrimitiveTable[i] = (((void *) addr)); + index = (GIV(externalPrimitiveTableFirstFreeIndex) = i + 1); + goto l1; + } + } + index = 0; + l1: /* end addToExternalPrimitiveTable: */; + /* begin storePointerUnchecked:ofObject:withValue: */ + assert(!(isOopForwarded(externalCallLiteral))); + longAtput((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord())))), (((usqInt)metadata << 3) | 1)); + } + /* begin storePointerUnchecked:ofObject:withValue: */ + assert(!(isOopForwarded(externalCallLiteral))); + longAtput((externalCallLiteral + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), (((usqInt)index << 3) | 1)); + rewriteMethodCacheEntryForExternalPrimitiveToFunction((index >= 0 + ? addr + : 0)); + return addr; +} + /* StackInterpreterPrimitives>>#noInlineLoadFloatOrIntFrom: */ static double NoDbgRegParms NeverInline noInlineLoadFloatOrIntFrom(sqInt floatOrInt) @@ -78541,10 +78425,6 @@ primitiveDoNamedPrimitiveWithArgs(void) sqInt moduleName; sqInt nItems; usqInt numSlots; - usqInt numSlots1; - usqInt numSlots11; - usqInt numSlots2; - usqInt numSlots3; sqInt object; sqInt object1; sqInt object2; @@ -78656,37 +78536,10 @@ primitiveDoNamedPrimitiveWithArgs(void) GIV(primFailCode) = 1; } } - /* begin lengthOf:format: */ + /* begin numBytesOfBytes: */ fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots1 = byteAt(moduleName + 7); - numSlots2 = (numSlots1 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(moduleName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots1); - if (fmt <= 5 /* ephemeronFormat */) { - moduleLength = numSlots2; - goto l15; - } - if (fmt >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - moduleLength = (numSlots2 << (shiftForWord())) - (fmt & 7); - goto l15; - } - if (fmt >= (firstShortFormat())) { - moduleLength = (numSlots2 << ((shiftForWord()) - 1)) - (fmt & 3); - goto l15; - } - if (fmt >= (firstLongFormat())) { - moduleLength = (numSlots2 << ((shiftForWord()) - 2)) - (fmt & 1); - goto l15; - } - if (fmt == (sixtyFourBitIndexableFormat())) { - moduleLength = numSlots2; - goto l15; - } - moduleLength = 0; - l15: /* end lengthOf:format: */; + assert(fmt >= (firstByteFormat())); + moduleLength = ((numSlotsOf(moduleName)) << (shiftForWord())) - (fmt & 7); } /* begin fetchPointer:ofObject: */ functionName = longAt((spec + BaseHeaderSize) + (1U << (shiftForWord()))); @@ -78700,37 +78553,10 @@ primitiveDoNamedPrimitiveWithArgs(void) GIV(primFailCode) = 1; } } - /* begin lengthOf:format: */ + /* begin numBytesOfBytes: */ fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots11 = byteAt(functionName + 7); - numSlots3 = (numSlots11 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(functionName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots11); - if (fmt1 <= 5 /* ephemeronFormat */) { - functionLength = numSlots3; - goto l20; - } - if (fmt1 >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - functionLength = (numSlots3 << (shiftForWord())) - (fmt1 & 7); - goto l20; - } - if (fmt1 >= (firstShortFormat())) { - functionLength = (numSlots3 << ((shiftForWord()) - 1)) - (fmt1 & 3); - goto l20; - } - if (fmt1 >= (firstLongFormat())) { - functionLength = (numSlots3 << ((shiftForWord()) - 2)) - (fmt1 & 1); - goto l20; - } - if (fmt1 == (sixtyFourBitIndexableFormat())) { - functionLength = numSlots3; - goto l20; - } - functionLength = 0; - l20: /* end lengthOf:format: */; + assert(fmt1 >= (firstByteFormat())); + functionLength = ((numSlotsOf(functionName)) << (shiftForWord())) - (fmt1 & 7); if (GIV(primFailCode)) { /* begin primitiveFailFor: */ (GIV(primFailCode) = -3); @@ -79038,24 +78864,10 @@ static void primitiveExternalCall(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt addr; - void (*addr1)(); - sqInt fmt; - sqInt fmt1; - sqInt functionLength; - sqInt functionName; - sqInt i; sqInt index; - sqInt index1; sqInt lit; - sqInt metadata; - sqInt moduleLength; - sqInt moduleName; - usqInt numSlots; - usqInt numSlots1; - usqInt numSlots11; - usqInt numSlots2; + sqInt reasonCode; - metadata = 0; if (!((((!(GIV(newMethod) & (tagMask())))) && (((((usqInt)((longAt(GIV(newMethod))))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat()))) && (((literalCountOf(GIV(newMethod))) > 0) @@ -79105,126 +78917,14 @@ primitiveExternalCall(void) /* begin storePointerUnchecked:ofObject:withValue: */ assert(!(isOopForwarded(lit))); longAtput((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), ConstZero); - /* begin linkExternalCall:ifFail: */ - moduleName = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralModuleNameIndex) << (shiftForWord()))))); - if (moduleName == GIV(nilObj)) { - moduleLength = 0; - } - else { - if (!(((!(moduleName & (tagMask())))) - && (((((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - /* begin primitiveFailFor: */ - (GIV(primFailCode) = PrimErrBadMethod); - return; - addr = ((void (*)()) 0); - goto l13; - } - /* begin lengthOf:format: */ - fmt = (((usqInt)((longAt(moduleName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots1 = byteAt(moduleName + 7); - numSlots = (numSlots1 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(moduleName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots1); - if (fmt <= 5 /* ephemeronFormat */) { - moduleLength = numSlots; - goto l8; - } - if (fmt >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - moduleLength = (numSlots << (shiftForWord())) - (fmt & 7); - goto l8; - } - if (fmt >= (firstShortFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 1)) - (fmt & 3); - goto l8; - } - if (fmt >= (firstLongFormat())) { - moduleLength = (numSlots << ((shiftForWord()) - 2)) - (fmt & 1); - goto l8; - } - if (fmt == (sixtyFourBitIndexableFormat())) { - moduleLength = numSlots; - goto l8; - } - moduleLength = 0; - l8: /* end lengthOf:format: */; - } - /* begin fetchPointer:ofObject: */ - functionName = longAt((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFunctionNameIndex) << (shiftForWord()))))); - if (!(((!(functionName & (tagMask())))) - && (((((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask())) >= (firstByteFormat())))) { - /* begin primitiveFailFor: */ - (GIV(primFailCode) = PrimErrBadMethod); - return; - addr = ((void (*)()) 0); - goto l13; - } - /* begin lengthOf:format: */ - fmt1 = (((usqInt)((longAt(functionName)))) >> (formatShift())) & (formatMask()); - /* begin numSlotsOfAny: */ - numSlots11 = byteAt(functionName + 7); - numSlots2 = (numSlots11 == (numSlotsMask()) - ? ((((usqInt)(((sqInt)((usqInt)((longAt(functionName - BaseHeaderSize))) << 8)))))) >> 8 - : numSlots11); - if (fmt1 <= 5 /* ephemeronFormat */) { - functionLength = numSlots2; - goto l10; - } - if (fmt1 >= (firstByteFormat())) { - - /* bytes, including CompiledMethod */ - functionLength = (numSlots2 << (shiftForWord())) - (fmt1 & 7); - goto l10; - } - if (fmt1 >= (firstShortFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 1)) - (fmt1 & 3); - goto l10; - } - if (fmt1 >= (firstLongFormat())) { - functionLength = (numSlots2 << ((shiftForWord()) - 2)) - (fmt1 & 1); - goto l10; - } - if (fmt1 == (sixtyFourBitIndexableFormat())) { - functionLength = numSlots2; - goto l10; - } - functionLength = 0; - l10: /* end lengthOf:format: */; - addr1 = ioLoadExternalFunctionOfLengthFromModuleOfLengthMetadataInto(functionName + BaseHeaderSize, functionLength, moduleName + BaseHeaderSize, moduleLength, (&metadata)); - if (addr1 == 0) { - index1 = -1; - } - else { - - /* add the function to the external primitive table */ - /* begin addToExternalPrimitiveTable: */ - for (i = GIV(externalPrimitiveTableFirstFreeIndex); i < MaxExternalPrimitiveTableSize; i += 1) { - if ((externalPrimitiveTable[i]) == 0) { - externalPrimitiveTable[i] = (((void *) addr1)); - index1 = (GIV(externalPrimitiveTableFirstFreeIndex) = i + 1); - goto l12; - } - } - index1 = 0; - l12: /* end addToExternalPrimitiveTable: */; - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(lit))); - longAtput((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralFlagsIndex) << (shiftForWord())))), (((usqInt)metadata << 3) | 1)); - } - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(lit))); - longAtput((lit + BaseHeaderSize) + (((sqInt)((usqInt)(ExternalCallLiteralTargetFunctionIndex) << (shiftForWord())))), (((usqInt)index1 << 3) | 1)); - rewriteMethodCacheEntryForExternalPrimitiveToFunction((index1 >= 0 - ? addr1 - : 0)); - addr = addr1; - l13: /* end linkExternalCall:ifFail: */; + addr = linkExternalCallerrInto(lit, (&GIV(primFailCode))); if (addr == 0) { assert((fetchPointerofObject(ExternalCallLiteralFlagsIndex, lit)) == ConstZero); /* begin primitiveFailFor: */ - (GIV(primFailCode) = PrimErrNotFound); + reasonCode = (GIV(primFailCode) == 0 + ? PrimErrNotFound + : GIV(primFailCode)); + (GIV(primFailCode) = reasonCode); return; } /* begin callExternalPrimitive: */ @@ -79810,74 +79510,6 @@ primitiveInstVarAtPut(void) } -/* Primitive. Answer an Array with the current long-running primitive method - identified by - the heartbeat, the minimum number of milliseconds it was active for, and - the milliseconds - of GC activity there-in, or nil if none. Since the - longRunningPrimitiveCheckMethod is - sampled at interrupt time be careful to validate it before returning it. */ - - /* StackInterpreterPrimitives>>#primitiveLongRunningPrimitive */ -EXPORT(sqInt) -primitiveLongRunningPrimitive(void) -{ DECL_MAYBE_SQ_GLOBAL_STRUCT - usqLong gcms; - sqInt lrpcm; - sqLong primms; - sqInt result; - char *sp; - - if (!(GIV(argumentCount) == 0)) { - /* begin primitiveFail */ - if (!GIV(primFailCode)) { - GIV(primFailCode) = 1; - } - return null; - } - sqLowLevelMFence(); - if ((GIV(longRunningPrimitiveStopUsecs) > GIV(longRunningPrimitiveStartUsecs)) - && ((((lrpcm = GIV(longRunningPrimitiveCheckMethod))) != null) - && ((addressCouldBeObj(lrpcm)) - && ((!(((longAt(lrpcm)) & (classIndexMask())) == (isFreeObjectClassIndexPun()))) - && (((((usqInt)((longAt(lrpcm)))) >> (formatShift())) & (formatMask())) >= (firstCompiledMethodFormat())))))) { - result = instantiateClassindexableSize(splObj(ClassArray), 3); - primms = ((GIV(longRunningPrimitiveStopUsecs) - GIV(longRunningPrimitiveStartUsecs)) + 500) / 1000; - gcms = (GIV(longRunningPrimitiveGCUsecs) + 500) / 1000; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(result))); - if ((assert(isNonImmediate(result)), - oopisGreaterThanOrEqualTo(result, GIV(oldSpaceStart)))) { - - /* most stores into young objects */ - if (((!(lrpcm & (tagMask())))) - && (oopisLessThan(lrpcm, GIV(newSpaceLimit)))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt)((longAt(result)))) >> (rememberedBitShift())) & 1) != 0)) { - remember(result); - } - } - } - longAtput((result + BaseHeaderSize) + (0U << (shiftForWord())), lrpcm); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (1U << (shiftForWord())), (((usqInt)primms << 3) | 1)); - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isOopForwarded(result))); - longAtput((result + BaseHeaderSize) + (2U << (shiftForWord())), ((gcms << 3) | 1)); - } - else { - /* begin nilObject */ - result = GIV(nilObj); - } - /* begin pop:thenPush: */ - longAtput((sp = GIV(stackPointer) + ((0) * BytesPerWord)), result); - GIV(stackPointer) = sp; - voidLongRunningPrimitive("get"); - return 0; -} - - /* This primitive is assumed to be fast (see e.g. MethodDictionary>>includesKey:) so make it so. N.B. Works forrectly for cogged methods too. */ @@ -80916,6 +80548,7 @@ primitiveStoreStackp(void) 74 maximum pause time due to segment allocation 75 whether the arithmetic primitives perform conversion in case of mixed SmallInteger/Float (true) or fail (false) + 76 the minimum unused headroom in all stack pages; Cog VMs only Note: Thanks to Ian Piumarta for this primitive. */ @@ -81011,11 +80644,12 @@ primitiveVMParameter(void) sqInt valuePointer61; sqInt valuePointer62; sqInt valuePointer63; + sqInt valuePointer64; sqInt valuePointer7; sqInt valuePointer8; sqInt valuePointer9; - paramsArraySize = 75; + paramsArraySize = 76; if (GIV(argumentCount) == 0) { /* begin primitiveAllVMParameters: */ result1 = instantiateClassindexableSize(splObj(ClassArray), paramsArraySize); @@ -81333,6 +80967,10 @@ primitiveVMParameter(void) : GIV(falseObj)); assert(!(isOopForwarded(result1))); longAtput((result1 + BaseHeaderSize) + (74U << (shiftForWord())), valuePointer63); + /* begin storePointerUnchecked:ofObject:withValue: */ + valuePointer64 = (((usqInt)(minimumUnusedHeadroom()) << 3) | 1); + assert(!(isOopForwarded(result1))); + longAtput((result1 + BaseHeaderSize) + (75U << (shiftForWord())), valuePointer64); beRootIfOld(result1); /* begin methodReturnValue: */ assert(!((failed()))); @@ -81370,43 +81008,43 @@ primitiveVMParameter(void) switch (index) { case 1: result = positiveMachineIntegerFor(totalBytesInSegments()); - goto l86; + goto l87; break; case 2: result = (((usqInt)((GIV(freeStart) - (((eden()).start))) + (GIV(pastSpaceStart) - (((pastSpace()).start)))) << 3) | 1); - goto l86; + goto l87; break; case 3: result = positiveMachineIntegerFor((newSpaceCapacity()) + (totalBytesInSegments())); - goto l86; + goto l87; break; case 6: result = (((usqInt)(((sqInt)(((scavengerTenuringThreshold()) * (((GIV(pastSpace).limit)) - ((GIV(pastSpace).start)))) / (8 * BytesPerOop)))) << 3) | 1); - goto l86; + goto l87; break; case 7: result = (((usqInt)GIV(statFullGCs) << 3) | 1); - goto l86; + goto l87; break; case 8: result = ((((GIV(statFullGCUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 9: result = (((usqInt)(/* begin statScavenges */ GIV(statScavenges)) << 3) | 1); - goto l86; + goto l87; break; case 10: result = (((((/* begin statScavengeGCUsecs */ GIV(statScavengeGCUsecs)) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 11: result = (((usqInt)GIV(statTenures) << 3) | 1); - goto l86; + goto l87; break; case 12: result = (((usqInt)eventTraceMask << 3) | 1); - goto l86; + goto l87; break; case 13: result = @@ -81416,7 +81054,7 @@ primitiveVMParameter(void) ConstZero # endif ; - goto l86; + goto l87; break; case 14: /* begin getVMTickerCount */ @@ -81427,7 +81065,7 @@ primitiveVMParameter(void) ConstZero # endif ; - goto l86; + goto l87; break; case 15: /* begin getVMTickeeCallCount */ @@ -81438,196 +81076,196 @@ primitiveVMParameter(void) ConstZero # endif ; - goto l86; + goto l87; break; case 16: result = positive64BitIntegerFor(GIV(statIdleUsecs)); - goto l86; + goto l87; break; case 17: result = ConstZero; - goto l86; + goto l87; break; case 18: result = ((((GIV(statCompactionUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 19: result = (((usqInt)(GIV(scavengeThreshold) - (((eden()).start))) << 3) | 1); - goto l86; + goto l87; break; case 20: result = positive64BitIntegerFor(ioUTCStartMicroseconds()); - goto l86; + goto l87; break; case 21: result = (((usqInt)(rootTableCount()) << 3) | 1); - goto l86; + goto l87; break; case 22: result = (((usqInt)GIV(statRootTableOverflows) << 3) | 1); - goto l86; + goto l87; break; case 23: result = (((usqInt)extraVMMemory << 3) | 1); - goto l86; + goto l87; break; case 24: result = (((usqInt)GIV(shrinkThreshold) << 3) | 1); - goto l86; + goto l87; break; case 25: result = (((usqInt)GIV(growHeadroom) << 3) | 1); - goto l86; + goto l87; break; case 26: result = (((usqInt)(ioHeartbeatMilliseconds()) << 3) | 1); - goto l86; + goto l87; break; case 27: result = (((usqInt)GIV(statMarkCount) << 3) | 1); - goto l86; + goto l87; break; case 28: result = (((usqInt)0 /* statSweepCount */ << 3) | 1); - goto l86; + goto l87; break; case 29: result = (((usqInt)0 /* statMkFwdCount */ << 3) | 1); - goto l86; + goto l87; break; case 30: result = (((usqInt)GIV(statCompactPassCount) << 3) | 1); - goto l86; + goto l87; break; case 0x1F: result = (((usqInt)GIV(statGrowMemory) << 3) | 1); - goto l86; + goto l87; break; case 32: result = (((usqInt)GIV(statShrinkMemory) << 3) | 1); - goto l86; + goto l87; break; case 33: result = (((usqInt)GIV(statRootTableCount) << 3) | 1); - goto l86; + goto l87; break; case 34: result = positive64BitIntegerFor(currentAllocatedBytes()); - goto l86; + goto l87; break; case 35: result = (((usqInt)GIV(statSurvivorCount) << 3) | 1); - goto l86; + goto l87; break; case 36: result = ((((GIV(statGCEndUsecs) / 1000) & MillisecondClockMask) << 3) | 1); - goto l86; + goto l87; break; case 37: result = (((usqInt)0 /* statSpecialMarkCount */ << 3) | 1); - goto l86; + goto l87; break; case 38: result = ((((GIV(statIGCDeltaUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 39: result = (((usqInt)GIV(statPendingFinalizationSignals) << 3) | 1); - goto l86; + goto l87; break; case 40: result = (((usqInt)BytesPerWord << 3) | 1); - goto l86; + goto l87; break; case 41: result = (((usqInt)68021 /* imageFormatVersion */ << 3) | 1); - goto l86; + goto l87; break; case 42: result = (((usqInt)GIV(numStackPages) << 3) | 1); - goto l86; + goto l87; break; case 43: result = (((usqInt)desiredNumStackPages << 3) | 1); - goto l86; + goto l87; break; case 44: result = (((usqInt)(((GIV(eden).limit)) - ((GIV(eden).start))) << 3) | 1); - goto l86; + goto l87; break; case 45: result = (((usqInt)desiredEdenBytes << 3) | 1); - goto l86; + goto l87; break; case 46: result = getCogCodeSize(); - goto l86; + goto l87; break; case 47: result = getDesiredCogCodeSize(); - goto l86; + goto l87; break; case 48: /* begin getImageHeaderFlagsParameter */ result = (((usqInt)(((usqInt)((getImageHeaderFlags()))) >> 2) << 3) | 1); - goto l86; + goto l87; break; case 49: result = (((usqInt)(ioGetMaxExtSemTableSize()) << 3) | 1); - goto l86; + goto l87; break; case 52: result = (((usqInt)(rootTableCapacity()) << 3) | 1); - goto l86; + goto l87; break; case 53: result = (((usqInt)(numSegments()) << 3) | 1); - goto l86; + goto l87; break; case 54: result = ((GIV(totalFreeOldSpace) << 3) | 1); - goto l86; + goto l87; break; case 55: result = floatObjectOf(getHeapGrowthToSizeGCRatio()); - goto l86; + goto l87; break; case 56: result = positive64BitIntegerFor(GIV(statProcessSwitch)); - goto l86; + goto l87; break; case 57: result = positive64BitIntegerFor(GIV(statIOProcessEvents)); - goto l86; + goto l87; break; case 58: result = positive64BitIntegerFor(GIV(statForceInterruptCheck)); - goto l86; + goto l87; break; case 59: result = positive64BitIntegerFor(GIV(statCheckForEvents)); - goto l86; + goto l87; break; case 60: result = positive64BitIntegerFor(GIV(statStackOverflow)); - goto l86; + goto l87; break; case 61: result = positive64BitIntegerFor(GIV(statStackPageDivorce)); - goto l86; + goto l87; break; case 0x3E: result = getCodeCompactionCount(); - goto l86; + goto l87; break; case 0x3F: result = getCodeCompactionMSecs(); - goto l86; + goto l87; break; case 64: result = (((usqInt)(numMethodsOfType(CMMethod)) << 3) | 1); - goto l86; + goto l87; break; case 65: /* begin getCogVMFeatureFlags */ @@ -81646,43 +81284,43 @@ primitiveVMParameter(void) 0 #endif )) << 3) | 1); - goto l86; + goto l87; break; case 66: result = (((usqInt)(stackPageByteSize()) << 3) | 1); - goto l86; + goto l87; break; case 67: result = positiveMachineIntegerFor(maxOldSpaceSize()); - goto l86; + goto l87; break; case 68: result = floatObjectOf(statAverageLivePagesWhenMapping()); - goto l86; + goto l87; break; case 69: result = (((usqInt)(statMaxPageCountWhenMapping()) << 3) | 1); - goto l86; + goto l87; break; case 70: result = (((usqInt)VM_PROXY_MAJOR << 3) | 1); - goto l86; + goto l87; break; case 71: result = (((usqInt)VM_PROXY_MINOR << 3) | 1); - goto l86; + goto l87; break; case 72: result = ((((GIV(statMarkUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 73: result = ((((GIV(statSweepUsecs) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 74: result = (((usqInt)((GIV(statMaxAllocSegmentTime) + 500) / 1000) << 3) | 1); - goto l86; + goto l87; break; case 75: /* begin booleanObjectOf: */ @@ -81690,14 +81328,18 @@ primitiveVMParameter(void) result = (aBool1 ? GIV(trueObj) : GIV(falseObj)); - goto l86; + goto l87; + break; + case 76: + result = (((usqInt)(minimumUnusedHeadroom()) << 3) | 1); + goto l87; break; default: result = null; - goto l86; + goto l87; } - l86: /* end primitiveGetVMParameter: */; + l87: /* end primitiveGetVMParameter: */; /* begin methodReturnValue: */ oop = (!(result) ? /* begin nilObject */ GIV(nilObj) @@ -81731,10 +81373,10 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = ((usqIntptr_t) null); - goto l90; + goto l91; } arg = ((usqIntptr_t) value); - goto l90; + goto l91; } if (((argOop & (tagMask())) != 0)) { /* begin primitiveFail */ @@ -81742,22 +81384,22 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = 0; - goto l90; + goto l91; } /* begin isClassOfNonImm:equalTo:compactClassIndex: */ assert(!(isImmediate(argOop))); /* begin classIndexOf: */ ccIndex = (longAt(argOop)) & (classIndexMask()); ok = ClassLargePositiveIntegerCompactIndex == ccIndex; - goto l101; - l101: /* end isClassOfNonImm:equalTo:compactClassIndex: */; + goto l102; + l102: /* end isClassOfNonImm:equalTo:compactClassIndex: */; if (!ok) { /* begin primitiveFail */ if (!GIV(primFailCode)) { GIV(primFailCode) = 1; } arg = 0; - goto l90; + goto l91; } /* begin numBytesOfBytes: */ fmt = (((usqInt)((longAt(argOop)))) >> (formatShift())) & (formatMask()); @@ -81769,25 +81411,25 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = 0; - goto l90; + goto l91; } if (((sizeof(usqIntptr_t)) == 8) && (bs > 4)) { arg = ((usqIntptr_t) (SQ_SWAP_8_BYTES_IF_BIGENDIAN((long64At((argOop + BaseHeaderSize)))))); - goto l90; + goto l91; } arg = ((usqIntptr_t) (((unsigned int) (SQ_SWAP_4_BYTES_IF_BIGENDIAN((long32At((argOop + BaseHeaderSize)))))))); - l90: /* end positiveMachineIntegerValueOf: */; + l91: /* end positiveMachineIntegerValueOf: */; break; case 75: /* begin booleanValueOf: */ if (argOop == GIV(trueObj)) { arg = 1; - goto l102; + goto l103; } if (argOop == GIV(falseObj)) { arg = 0; - goto l102; + goto l103; } /* begin success: */ @@ -81796,7 +81438,7 @@ primitiveVMParameter(void) GIV(primFailCode) = 1; } arg = null; - l102: /* end booleanValueOf: */; + l103: /* end booleanValueOf: */; break; default: arg = (argOop >> 3); @@ -81805,7 +81447,7 @@ primitiveVMParameter(void) if (GIV(primFailCode)) { /* begin primitiveFailFor: */ GIV(primFailCode) = PrimErrBadArgument; - goto l104; + goto l105; } /* begin primitiveFailFor: */ GIV(primFailCode) = PrimErrBadArgument; @@ -81817,7 +81459,7 @@ primitiveVMParameter(void) /* begin tenuringThreshold: */ if (arg < 0) { GIV(primFailCode) = PrimErrBadArgument; - goto l96; + goto l97; } /* begin scavengerTenuringThreshold: */ aProportion = (((double) (arg * (8 * BytesPerOop)) )) / (((double) (((GIV(pastSpace).limit)) - ((GIV(pastSpace).start))) )); @@ -81826,7 +81468,7 @@ primitiveVMParameter(void) ? 0 : (round(((((GIV(pastSpace).limit)) - ((GIV(pastSpace).start))) * (1.0 - aProportion)))) + ((GIV(pastSpace).start))); GIV(primFailCode) = 0; - l96: /* end tenuringThreshold: */; + l97: /* end tenuringThreshold: */; break; case 12: result2 = (((usqInt)eventTraceMask << 3) | 1); @@ -81926,7 +81568,7 @@ primitiveVMParameter(void) /* begin setImageHeaderFlags: */ if ((((usqInt)arg)) > 0xFF) { GIV(primFailCode) = PrimErrUnsupported; - goto l98; + goto l99; } GIV(imageHeaderFlags) = (((arg & 1) != 0) ? GIV(imageHeaderFlags) | 4 @@ -81944,7 +81586,7 @@ primitiveVMParameter(void) GIV(imageHeaderFlags) = (((arg & 128) != 0) ? GIV(imageHeaderFlags) | 0x200 : ((GIV(imageHeaderFlags) | 0x200) - 0x200)); - l98: /* end setImageHeaderFlags: */; + l99: /* end setImageHeaderFlags: */; if ((GIV(primFailCode) == 0) && (oldPrimitiveDoMixedArithmetic != primitiveDoMixedArithmetic)) { flushMethodCache(); @@ -82039,7 +81681,7 @@ primitiveVMParameter(void) /* begin primitiveFailFor: */ GIV(primFailCode) = PrimErrInappropriate; } - l104: /* end primitiveSetVMParameter:arg: */; + l105: /* end primitiveSetVMParameter:arg: */; } @@ -82315,20 +81957,20 @@ void* vm_exports[][3] = { {(void*)_m, "longPrintOop", (void*)longPrintOop}, {(void*)_m, "longPrintReferencesTo", (void*)longPrintReferencesTo}, {(void*)_m, "moduleUnloaded", (void*)moduleUnloaded}, - {(void*)_m, "primitiveAddLargeIntegers\000\377\000", (void*)primitiveAddLargeIntegers}, + {(void*)_m, "primitiveAddLargeIntegers\000\000\000", (void*)primitiveAddLargeIntegers}, {(void*)_m, "primitiveAllInstances\000\377\000", (void*)primitiveAllInstances}, {(void*)_m, "primitiveAllObjects\000\377\000", (void*)primitiveAllObjects}, {(void*)_m, "primitiveBitAndLargeIntegers\000\377\000", (void*)primitiveBitAndLargeIntegers}, {(void*)_m, "primitiveBitOrLargeIntegers\000\377\000", (void*)primitiveBitOrLargeIntegers}, - {(void*)_m, "primitiveBitShiftLargeIntegers\000\377\000", (void*)primitiveBitShiftLargeIntegers}, + {(void*)_m, "primitiveBitShiftLargeIntegers\000\000\000", (void*)primitiveBitShiftLargeIntegers}, {(void*)_m, "primitiveBitXorLargeIntegers\000\377\000", (void*)primitiveBitXorLargeIntegers}, {(void*)_m, "primitiveClockLogAddresses\000\377\000", (void*)primitiveClockLogAddresses}, - {(void*)_m, "primitiveCompareBytes\000\377\000", (void*)primitiveCompareBytes}, - {(void*)_m, "primitiveCompareWith\000\377\000", (void*)primitiveCompareWith}, + {(void*)_m, "primitiveCompareBytes\000\000\000", (void*)primitiveCompareBytes}, + {(void*)_m, "primitiveCompareWith\000\001\000", (void*)primitiveCompareWith}, {(void*)_m, "primitiveCrashVM\000\377\000", (void*)primitiveCrashVM}, - {(void*)_m, "primitiveDisablePowerManager\000\377\000", (void*)primitiveDisablePowerManager}, - {(void*)_m, "primitiveDivideLargeIntegers\000\377\000", (void*)primitiveDivideLargeIntegers}, - {(void*)_m, "primitiveDivLargeIntegers\000\377\000", (void*)primitiveDivLargeIntegers}, + {(void*)_m, "primitiveDisablePowerManager\000\000\000", (void*)primitiveDisablePowerManager}, + {(void*)_m, "primitiveDivideLargeIntegers\000\000\000", (void*)primitiveDivideLargeIntegers}, + {(void*)_m, "primitiveDivLargeIntegers\000\000\000", (void*)primitiveDivLargeIntegers}, {(void*)_m, "primitiveEqualLargeIntegers\000\377\000", (void*)primitiveEqualLargeIntegers}, {(void*)_m, "primitiveEventProcessingControl\000\377\000", (void*)primitiveEventProcessingControl}, {(void*)_m, "primitiveGetenv\000\377\000", (void*)primitiveGetenv}, @@ -82338,39 +81980,37 @@ void* vm_exports[][3] = { {(void*)_m, "primitiveGreaterOrEqualLargeIntegers\000\377\000", (void*)primitiveGreaterOrEqualLargeIntegers}, {(void*)_m, "primitiveGreaterThanLargeIntegers\000\377\000", (void*)primitiveGreaterThanLargeIntegers}, {(void*)_m, "primitiveHeartbeatFrequency\000\377\000", (void*)primitiveHeartbeatFrequency}, - {(void*)_m, "primitiveHighResClock\000\377\000", (void*)primitiveHighResClock}, + {(void*)_m, "primitiveHighResClock\000\377\001", (void*)primitiveHighResClock}, {(void*)_m, "primitiveImageFormatVersion\000\377\000", (void*)primitiveImageFormatVersion}, {(void*)_m, "primitiveInterruptChecksPerMSec\000\377\000", (void*)primitiveInterruptChecksPerMSec}, {(void*)_m, "primitiveIsBigEnder\000\377\000", (void*)primitiveIsBigEnder}, {(void*)_m, "primitiveIsWindowObscured\000\377\000", (void*)primitiveIsWindowObscured}, {(void*)_m, "primitiveLessOrEqualLargeIntegers\000\377\000", (void*)primitiveLessOrEqualLargeIntegers}, {(void*)_m, "primitiveLessThanLargeIntegers\000\377\000", (void*)primitiveLessThanLargeIntegers}, - {(void*)_m, "primitiveLongRunningPrimitive\000\377\000", (void*)primitiveLongRunningPrimitive}, - {(void*)_m, "primitiveLongRunningPrimitiveSemaphore\000\377\000", (void*)primitiveLongRunningPrimitiveSemaphore}, - {(void*)_m, "primitiveMethodPCData\000\377\000", (void*)primitiveMethodPCData}, + {(void*)_m, "primitiveMethodPCData\000\000\000", (void*)primitiveMethodPCData}, {(void*)_m, "primitiveMillisecondClockMask\000\377\000", (void*)primitiveMillisecondClockMask}, {(void*)_m, "primitiveMinimumUnusedHeadroom\000\377\000", (void*)primitiveMinimumUnusedHeadroom}, - {(void*)_m, "primitiveModLargeIntegers\000\377\000", (void*)primitiveModLargeIntegers}, - {(void*)_m, "primitiveMultiplyLargeIntegers\000\377\000", (void*)primitiveMultiplyLargeIntegers}, + {(void*)_m, "primitiveModLargeIntegers\000\000\000", (void*)primitiveModLargeIntegers}, + {(void*)_m, "primitiveMultiplyLargeIntegers\000\000\000", (void*)primitiveMultiplyLargeIntegers}, {(void*)_m, "primitiveNotEqualLargeIntegers\000\377\000", (void*)primitiveNotEqualLargeIntegers}, - {(void*)_m, "primitivePathToUsing\000\377\000", (void*)primitivePathToUsing}, - {(void*)_m, "primitiveProfilePrimitive\000\377\000", (void*)primitiveProfilePrimitive}, - {(void*)_m, "primitiveProfileSample\000\377\000", (void*)primitiveProfileSample}, - {(void*)_m, "primitiveProfileSemaphore\000\377\000", (void*)primitiveProfileSemaphore}, - {(void*)_m, "primitiveProfileStart\000\377\000", (void*)primitiveProfileStart}, - {(void*)_m, "primitiveQuoLargeIntegers\000\377\000", (void*)primitiveQuoLargeIntegers}, - {(void*)_m, "primitiveRemLargeIntegers\000\377\000", (void*)primitiveRemLargeIntegers}, + {(void*)_m, "primitivePathToUsing\000\000\000", (void*)primitivePathToUsing}, + {(void*)_m, "primitiveProfilePrimitive\000\377\001", (void*)primitiveProfilePrimitive}, + {(void*)_m, "primitiveProfileSample\000\377\001", (void*)primitiveProfileSample}, + {(void*)_m, "primitiveProfileSemaphore\000\000\000", (void*)primitiveProfileSemaphore}, + {(void*)_m, "primitiveProfileStart\000\000\001", (void*)primitiveProfileStart}, + {(void*)_m, "primitiveQuoLargeIntegers\000\000\000", (void*)primitiveQuoLargeIntegers}, + {(void*)_m, "primitiveRemLargeIntegers\000\000\000", (void*)primitiveRemLargeIntegers}, {(void*)_m, "primitiveScreenDepth\000\377\000", (void*)primitiveScreenDepth}, {(void*)_m, "primitiveScreenScaleFactor\000\377\000", (void*)primitiveScreenScaleFactor}, - {(void*)_m, "primitiveSetGCSemaphore\000\377\000", (void*)primitiveSetGCSemaphore}, - {(void*)_m, "primitiveSetLogDirectory\000\377\000", (void*)primitiveSetLogDirectory}, - {(void*)_m, "primitiveSetWindowLabel\000\377\000", (void*)primitiveSetWindowLabel}, - {(void*)_m, "primitiveSetWindowSize\000\377\000", (void*)primitiveSetWindowSize}, - {(void*)_m, "primitiveSubtractLargeIntegers\000\377\000", (void*)primitiveSubtractLargeIntegers}, + {(void*)_m, "primitiveSetGCSemaphore\000\000\000", (void*)primitiveSetGCSemaphore}, + {(void*)_m, "primitiveSetLogDirectory\000\000\000", (void*)primitiveSetLogDirectory}, + {(void*)_m, "primitiveSetWindowLabel\000\000\000", (void*)primitiveSetWindowLabel}, + {(void*)_m, "primitiveSetWindowSize\000\000\000", (void*)primitiveSetWindowSize}, + {(void*)_m, "primitiveSubtractLargeIntegers\000\000\000", (void*)primitiveSubtractLargeIntegers}, #if TestingPrimitives - {(void*)_m, "primitiveTestShortenIndexableSize\000\377\000", (void*)primitiveTestShortenIndexableSize}, + {(void*)_m, "primitiveTestShortenIndexableSize\000\000\000", (void*)primitiveTestShortenIndexableSize}, #endif /* TestingPrimitives */ - {(void*)_m, "primitiveUtcWithOffset\000\377\000", (void*)primitiveUtcWithOffset}, + {(void*)_m, "primitiveUtcWithOffset\000\000\000", (void*)primitiveUtcWithOffset}, {(void*)_m, "primitiveVoidReceiver\000\377\000", (void*)primitiveVoidReceiver}, {(void*)_m, "printActivationsOf", (void*)printActivationsOf}, {(void*)_m, "printAllStacks", (void*)printAllStacks}, diff --git a/spur64src/vm/cogit.h b/spur64src/vm/cogit.h index 7936e20c7c..323635d8f4 100644 --- a/spur64src/vm/cogit.h +++ b/spur64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ diff --git a/spur64src/vm/cogitARMv8.c b/spur64src/vm/cogitARMv8.c index 6d3be10b5d..76ef5bc0e2 100644 --- a/spur64src/vm/cogitARMv8.c +++ b/spur64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - StackToRegisterMappingCogit VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -5945,7 +5945,7 @@ generateDCacheFlush(AbstractInstruction * self_in_generateDCacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperand(RetN, 0); # endif // !(__APPLE__ && __MACH__) } @@ -6064,7 +6064,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); } genoperandoperand(DSB, DSB_ISH, DSB_ALL); if (instructionCacheFlushRequired(self_in_generateICacheFlush)) { @@ -6086,7 +6086,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperandoperand(DSB, DSB_ISH, DSB_ALL); } gen(ISB); diff --git a/spurlowcode64src/vm/cogit.h b/spurlowcode64src/vm/cogit.h index 9d4c4cd385..64b771747e 100644 --- a/spurlowcode64src/vm/cogit.h +++ b/spurlowcode64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ diff --git a/spurlowcode64src/vm/cogitARMv8.c b/spurlowcode64src/vm/cogitARMv8.c index 6cb7ae21e6..b655d7f4aa 100644 --- a/spurlowcode64src/vm/cogitARMv8.c +++ b/spurlowcode64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - StackToRegisterMappingCogit VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -6127,7 +6127,7 @@ generateDCacheFlush(AbstractInstruction * self_in_generateDCacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperand(RetN, 0); # endif // !(__APPLE__ && __MACH__) } @@ -6246,7 +6246,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); } genoperandoperand(DSB, DSB_ISH, DSB_ALL); if (instructionCacheFlushRequired(self_in_generateICacheFlush)) { @@ -6268,7 +6268,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperandoperand(DSB, DSB_ISH, DSB_ALL); } gen(ISB); @@ -7454,7 +7454,7 @@ rewriteImm19JumpBeforetarget(AbstractInstruction * self_in_rewriteImm19JumpBefor static sqInt NoDbgRegParms rewriteImm26JumpBeforetarget(AbstractInstruction * self_in_rewriteImm26JumpBeforetarget, sqInt followingAddress, sqInt targetAddress) { - sqInt instrOpcode; + usqInt instrOpcode; sqInt mcpc; sqInt offset; @@ -7464,7 +7464,7 @@ rewriteImm26JumpBeforetarget(AbstractInstruction * self_in_rewriteImm26JumpBefor instrOpcode = ((instructionBeforeAddress(self_in_rewriteImm26JumpBeforetarget, followingAddress))) >> 26; assert((instrOpcode == 5) || (instrOpcode == 37)); - codeLong32Atput(mcpc, (((sqInt)((usqInt)(instrOpcode) << 26))) + (((offset) >> 2) & (0x3FFFFFF))); + codeLong32Atput(mcpc, (instrOpcode << 26) + (((offset) >> 2) & (0x3FFFFFF))); return 4; } diff --git a/spursista64src/vm/cogit.h b/spursista64src/vm/cogit.h index 60e530bb1e..fbe2d1e0a9 100644 --- a/spursista64src/vm/cogit.h +++ b/spursista64src/vm/cogit.h @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ diff --git a/spursista64src/vm/cogitARMv8.c b/spursista64src/vm/cogitARMv8.c index 42e5f00db6..95767cb041 100644 --- a/spursista64src/vm/cogitARMv8.c +++ b/spursista64src/vm/cogitARMv8.c @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + CCodeGenerator VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 from - SistaCogit VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 + SistaCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 */ -static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3033 uuid: f561c302-005c-4fa1-bff2-8d965409d563 " __DATE__ ; +static char __buildInfo[] = "SistaCogit VMMaker.oscog-eem.3034 uuid: 3ea0aaa2-20e4-4c02-b448-c3e708578e16 " __DATE__ ; char *__cogitBuildInfo = __buildInfo; @@ -6050,7 +6050,7 @@ generateDCacheFlush(AbstractInstruction * self_in_generateDCacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperand(RetN, 0); # endif // !(__APPLE__ && __MACH__) } @@ -6169,7 +6169,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); } genoperandoperand(DSB, DSB_ISH, DSB_ALL); if (instructionCacheFlushRequired(self_in_generateICacheFlush)) { @@ -6191,7 +6191,7 @@ generateICacheFlush(AbstractInstruction * self_in_generateICacheFlush) } assert(!((CArg1Reg == SPReg))); genoperandoperand(CmpRR, CArg1Reg, CArg2Reg); - genConditionalBranchoperand(JumpBelowOrEqual, ((sqInt)loop)); + genConditionalBranchoperand(JumpBelow, ((sqInt)loop)); genoperandoperand(DSB, DSB_ISH, DSB_ALL); } gen(ISB); @@ -7377,7 +7377,7 @@ rewriteImm19JumpBeforetarget(AbstractInstruction * self_in_rewriteImm19JumpBefor static sqInt NoDbgRegParms rewriteImm26JumpBeforetarget(AbstractInstruction * self_in_rewriteImm26JumpBeforetarget, sqInt followingAddress, sqInt targetAddress) { - sqInt instrOpcode; + usqInt instrOpcode; sqInt mcpc; sqInt offset; @@ -7387,7 +7387,7 @@ rewriteImm26JumpBeforetarget(AbstractInstruction * self_in_rewriteImm26JumpBefor instrOpcode = ((instructionBeforeAddress(self_in_rewriteImm26JumpBeforetarget, followingAddress))) >> 26; assert((instrOpcode == 5) || (instrOpcode == 37)); - codeLong32Atput(mcpc, (((sqInt)((usqInt)(instrOpcode) << 26))) + (((offset) >> 2) & (0x3FFFFFF))); + codeLong32Atput(mcpc, (instrOpcode << 26) + (((offset) >> 2) & (0x3FFFFFF))); return 4; }