Revision: 3733 Author: eliot Date: 2016-06-01 12:32:08 -0700 (Wed, 01 Jun 2016) Log Message: ----------- CogVM source as per VMMaker.oscog-eem.1876
Cogit: Change the JIT so that (with Immutability/Write barrier ON) methods with only frameless instance variable stores are compiled with two paths. The code first checks if the receiver is immutable/read-only, and takes the right path accordingly. The first path is frameless and does not include immutability/write barrier checks. The second one is frameful and does all the immutability/write barrier checks.
Eliminate the callerSavedRegMask variable and replace it with a CallerSavedRegisterMask variable computed at register initialization time.
On ARM: - define the caller-saved registers as the subset of the caller-saved registers that excludes R0/CArg0Reg/TempReg & R1/CArg1Reg (R0 is the C result register), and use R2 & R3 for abstract registers (ClassReg and Arg0Reg). - save and restore elements of the caller-saved registers as appropriate around run-time calls. - use LDM & STM to do the saving. - hence provide two extra registers, now provinding Extra[012]Reg
Fix some compilation warnings in cogitX64.c
Plugins: Change the JPEGReaderPlugin to handle 8- and 16- bit JPEGs (thank you Laura ! ; still to integrate the refactoring into C and Smalltalk code).
More inlining of low-level copy routines in the LargeInegersPlugin.
Modified Paths: -------------- branches/Cog/nsspur64src/vm/cogit.h branches/Cog/nsspur64src/vm/cogitX64.c branches/Cog/nsspur64src/vm/cointerp.c branches/Cog/nsspur64src/vm/cointerp.h branches/Cog/nsspur64src/vm/gcc3x-cointerp.c branches/Cog/nsspursrc/vm/cogit.h branches/Cog/nsspursrc/vm/cogitARMv5.c branches/Cog/nsspursrc/vm/cogitIA32.c branches/Cog/nsspursrc/vm/cogitMIPSEL.c branches/Cog/nsspursrc/vm/cointerp.c branches/Cog/nsspursrc/vm/cointerp.h branches/Cog/nsspursrc/vm/gcc3x-cointerp.c branches/Cog/nsspurstack64src/vm/gcc3x-interp.c branches/Cog/nsspurstack64src/vm/interp.c branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c branches/Cog/nsspurstacksrc/vm/interp.c branches/Cog/spur64src/vm/cogit.h branches/Cog/spur64src/vm/cogitX64.c branches/Cog/spur64src/vm/cointerp.c branches/Cog/spur64src/vm/cointerp.h branches/Cog/spur64src/vm/gcc3x-cointerp.c branches/Cog/spursistasrc/vm/cogit.h branches/Cog/spursistasrc/vm/cogitARMv5.c branches/Cog/spursistasrc/vm/cogitIA32.c branches/Cog/spursistasrc/vm/cogitMIPSEL.c branches/Cog/spursistasrc/vm/cointerp.c branches/Cog/spursistasrc/vm/cointerp.h branches/Cog/spursistasrc/vm/gcc3x-cointerp.c branches/Cog/spursrc/vm/cogit.h branches/Cog/spursrc/vm/cogitARMv5.c branches/Cog/spursrc/vm/cogitIA32.c branches/Cog/spursrc/vm/cogitMIPSEL.c branches/Cog/spurstack64src/vm/gcc3x-interp.c branches/Cog/spurstack64src/vm/interp.c branches/Cog/spurstacksrc/vm/gcc3x-interp.c branches/Cog/spurstacksrc/vm/interp.c branches/Cog/src/plugins/B2DPlugin/B2DPlugin.c branches/Cog/src/plugins/BitBltPlugin/BitBltPlugin.c branches/Cog/src/plugins/JPEGReaderPlugin/JPEGReaderPlugin.c branches/Cog/src/plugins/LargeIntegers/LargeIntegers.c branches/Cog/src/plugins/SqueakFFIPrims/ARM32FFIPlugin.c branches/Cog/src/plugins/SqueakFFIPrims/X64SysVFFIPlugin.c branches/Cog/src/plugins/SqueakFFIPrims/X64Win64FFIPlugin.c branches/Cog/src/vm/cogit.h branches/Cog/src/vm/cogitARMv5.c branches/Cog/src/vm/cogitIA32.c branches/Cog/src/vm/cogitMIPSEL.c branches/Cog/src/vm/cointerp.c branches/Cog/src/vm/cointerp.h branches/Cog/src/vm/cointerpmt.c branches/Cog/src/vm/cointerpmt.h branches/Cog/src/vm/gcc3x-cointerp.c branches/Cog/src/vm/gcc3x-cointerpmt.c branches/Cog/stacksrc/vm/gcc3x-interp.c branches/Cog/stacksrc/vm/interp.c
Property Changed: ---------------- branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
Modified: branches/Cog/nsspur64src/vm/cogit.h =================================================================== --- branches/Cog/nsspur64src/vm/cogit.h 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspur64src/vm/cogit.h 2016-06-01 19:32:08 UTC (rev 3733) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */
Modified: branches/Cog/nsspur64src/vm/cogitX64.c =================================================================== --- branches/Cog/nsspur64src/vm/cogitX64.c 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspur64src/vm/cogitX64.c 2016-06-01 19:32:08 UTC (rev 3733) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 + CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e from - StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 + StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ; char *__cogitBuildInfo = __buildInfo;
@@ -45,6 +45,7 @@ #define BlockCreationBytecodeSize 4 #define BytecodeSetHasDirectedSuperSend 0 #define Call 6 +#define CallerSavedRegisterMask 0xFC7 #define CallFull 7 #define CDQ 116 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ @@ -248,8 +249,6 @@ #define PushCq 74 #define PushCw 75 #define PushR 73 -#define R10 10 -#define R11 11 #define R12 12 #define R13 13 #define R15 15 @@ -469,6 +468,7 @@ static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); static AbstractInstruction * NoDbgRegParms CallNewspeakSend(sqInt callTarget); +static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gCmpCwR(sqInt wordConstant, sqInt reg); @@ -601,7 +601,7 @@ static AbstractInstruction * NoDbgRegParms gMoveCwR(sqInt wordConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gMoveRMwr(sqInt sourceReg, sqInt offset, sqInt baseReg); static AbstractInstruction * NoDbgRegParms gMoveRR(sqInt reg1, sqInt reg2); -static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); +static sqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, sqInt arg), sqInt arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); static void mapObjectReferencesInGeneratedRuntime(void); @@ -632,7 +632,7 @@ static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(sqInt cPIC); +static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); static AbstractInstruction * NoDbgRegParms gPushCw(sqInt wordConstant); @@ -889,11 +889,8 @@ static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); static SimStackEntry * NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static sqInt NoDbgRegParms isBackwardBranchFixup(BytecodeFixup * self_in_isBackwardBranchFixup); static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static sqInt NoDbgRegParms isMergeFixupOrIsFixedUp(BytecodeFixup * self_in_isMergeFixupOrIsFixedUp); static sqInt NoDbgRegParms availableRegisterOrNoneFor(AbstractInstruction * self_in_availableRegisterOrNoneFor, sqInt liveRegsMask); -static sqInt NoDbgRegParms callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask); static sqInt NoDbgRegParms callFullTargetFromReturnAddress(AbstractInstruction * self_in_callFullTargetFromReturnAddress, sqInt callSiteReturnAddress); static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); static sqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); @@ -1076,6 +1073,9 @@ static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); static sqInt compileEntireMethod(void); static void compileFrameBuild(void); +#if IMMUTABILITY +static void compileTwoPathFrameBuild(void); +#endif /* IMMUTABILITY */ static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); static sqInt doubleExtendedDoAnythingBytecode(void); static sqInt duplicateTopBytecode(void); @@ -1210,7 +1210,6 @@ static sqInt bytecodeSetOffset; void * CFramePointer; void * CStackPointer; -static sqInt callerSavedRegMask; static sqInt cbEntryOffset; static sqInt cbNoSwitchEntryOffset; sqInt ceBaseFrameReturnTrampoline; @@ -1273,12 +1272,13 @@ static sqInt debugFixupBreaks; static sqInt debugOpcodeIndices; unsigned long debugPrimCallStackOffset; +static sqInt debugStackPointers; static sqInt disassemblingMethod; static sqInt dynamicSuperSendTrampolines[NumSendTrampolines]; static AbstractInstruction * endCPICCase0; static sqInt endPC; static AbstractInstruction * entry; -static sqInt enumeratingCogMethod; +static CogMethod * enumeratingCogMethod; static sqInt expectedFPAlignment; static sqInt expectedSPAlignment; static sqInt extA; @@ -1831,6 +1831,7 @@ sqInt missOffset; static usqInt mzFreeStart; static sqInt needsFrame; +static sqInt needsTwoPath; static AbstractInstruction * noCheckEntry; static sqInt numAbstractOpcodes; static sqInt numIRCs; @@ -1885,7 +1886,6 @@ #define blockAlignment(self) 8 #define blockStartAt(index) (&blockStarts[index]) #define breakOnImplicitReceiver() (traceFlags & 64) -#define callerSavedRegMask() callerSavedRegMask #define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline #define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) #define ceCheckFeatures() ceCheckFeaturesFunction() @@ -2605,7 +2605,7 @@ static sqInt NoDbgRegParms addressIsInInstructions(AbstractInstruction *address) { - return !((unsigned)(address) & BytesPerWord-1) \ + return !((usqInt)(address) & BytesPerWord-1) \ && (address) >= &abstractOpcodes[0] \ && (address) < &abstractOpcodes[opcodeIndex]; } @@ -2796,7 +2796,7 @@ sqInt byte; BytecodeDescriptor *descriptor; sqInt distance; - usqInt endbcpc; + sqInt endbcpc; CogMethod *homeMethod; sqInt isBackwardBranch; sqInt isInBlock; @@ -2962,6 +2962,44 @@ return abstractInstruction; }
+ /* Cogit>>#CallRT:registersToBeSavedMask: */ +static AbstractInstruction * NoDbgRegParms +CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved) +{ + AbstractInstruction *abstractInstruction; + sqInt callerSavedRegsToBeSaved; + AbstractInstruction *lastInst; + sqInt reg; + sqInt registersToBePushed; + + reg = 0; + callerSavedRegsToBeSaved = CallerSavedRegisterMask & registersToBeSaved; + registersToBePushed = callerSavedRegsToBeSaved; + reg = 0; + while (registersToBePushed != 0) { + if (registersToBePushed & 1) { + /* begin PushR: */ + genoperand(PushR, reg); + } + reg += 1; + registersToBePushed = ((sqInt) registersToBePushed) >> 1; + } + + /* begin CallRT: */ + abstractInstruction = genoperand(Call, callTarget); + (abstractInstruction->annotation = IsRelativeCall); + lastInst = abstractInstruction; + while (reg >= 0) { + if (callerSavedRegsToBeSaved & (1LL << reg)) { + /* begin PopR: */ + lastInst = genoperand(PopR, reg); + } + reg -= 1; + } + return lastInst; + +} + /* Cogit>>#Call: */ static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget) @@ -3667,7 +3705,7 @@ closedPICRefersToUnmarkedObject(CogMethod *cPIC) { sqInt i; - sqInt object; + usqInt object; sqInt pc;
if (!((isImmediate((cPIC->selector))) @@ -4464,6 +4502,8 @@
# if ABI == MSVC + + /* completely untested... */ if (regOrConst2 < NoReg) { /* begin MoveCq:R: */ anInstruction4 = genoperandoperand(MoveCqR, -2 - regOrConst2, R8); @@ -5236,7 +5276,7 @@ findMapLocationForMcpcinMethod(sqInt targetMcpc, CogMethod *cogMethod) { sqInt annotation; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc;
@@ -5320,7 +5360,7 @@ followForwardedLiteralsIn(CogMethod *cogMethod) { sqInt annotation; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -6721,8 +6761,7 @@ (methodLabel->opcode = Label); ((methodLabel->operands))[0] = 0; ((methodLabel->operands))[1] = 0; - callerSavedRegMask = callerSavedRegisterMask(backEnd); - assert(((registerMaskFor(VarBaseReg)) & callerSavedRegMask) == 0); + assert(((registerMaskFor(VarBaseReg)) & CallerSavedRegisterMask) == 0);
}
@@ -7136,10 +7175,10 @@ /* Answer the address of the null byte at the end of the method map. */
/* Cogit>>#mapEndFor: */ -static usqInt NoDbgRegParms +static sqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod) { - usqInt end; + sqInt end;
end = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; while ((byteAt(end)) != MapEnd) { @@ -7157,7 +7196,7 @@ mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, sqInt arg), sqInt arg) { sqInt annotation; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -7264,7 +7303,7 @@ sqInt freedPIC; sqInt hasYoungObj; sqInt hasYoungObjPtr; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt remappedMethod; @@ -7382,7 +7421,7 @@ { sqInt annotation; CogMethod *cogMethod; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -7462,7 +7501,7 @@ CogMethod *cogMethod; sqInt hasYoungObj; sqInt hasYoungObjPtr; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; usqInt pointer; @@ -7582,8 +7621,8 @@ sqInt annotation; sqInt annotation1; CogMethod *cogMethod; - usqInt map; - usqInt map1; + sqInt map; + sqInt map1; sqInt mapByte; sqInt mapByte1; usqInt mcpc; @@ -7742,7 +7781,7 @@ markAndTraceOrFreeCogMethodfirstVisit(CogMethod *cogMethod, sqInt firstVisit) { sqInt annotation; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -8070,7 +8109,7 @@ { sqInt annotation; CogMethod *cogMethod; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -8198,7 +8237,7 @@ sqInt byte; BytecodeDescriptor *descriptor; sqInt distance; - usqInt endbcpc; + sqInt endbcpc; CogMethod *homeMethod; sqInt isBackwardBranch; sqInt isInBlock; @@ -8483,7 +8522,7 @@
/* Cogit>>#noTargetsFreeInClosedPIC: */ static sqInt NoDbgRegParms -noTargetsFreeInClosedPIC(sqInt cPIC) +noTargetsFreeInClosedPIC(CogMethod *cPIC) { return !(cPICHasFreedTargets(cPIC)); } @@ -8628,8 +8667,15 @@
cogMethod = methodFor(address); if (cogMethod == 0) { - print("not a method"); - cr(); + if ((codeEntryFor(address)) == null) { + print("not a method"); + cr(); + } + else { + print("trampoline "); + print(codeEntryNameFor(address)); + cr(); + } } else { printCogMethod(cogMethod); @@ -8641,9 +8687,9 @@ printPCMapPairsFor(CogMethod *cogMethod) { sqInt annotation; - usqInt map; + sqInt map; unsigned char mapByte; - usqInt mcpc; + sqInt mcpc; sqInt value;
mcpc = (0 @@ -8820,7 +8866,7 @@ { sqInt annotation; sqLong callDelta; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqLong refDelta; @@ -9394,7 +9440,7 @@ { sqInt annotation; CogMethod *cogMethod; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -9837,7 +9883,7 @@ sqInt annotation; CogMethod *cogMethod; sqInt freedPIC; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -9914,7 +9960,7 @@ { sqInt annotation; CogMethod *cogMethod; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt mustScanAndUnlink; @@ -10013,7 +10059,7 @@ { sqInt annotation; CogMethod *cogMethod; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -10082,7 +10128,7 @@ sqInt annotation; CogMethod *cogMethod; sqInt freedPIC; - usqInt map; + sqInt map; sqInt mapByte; usqInt mcpc; sqInt result; @@ -10471,8 +10517,6 @@ freeOlderMethodsForCompaction(void) { usqInt amountToFree; - sqInt cascade0; - sqInt cascade1; CogMethod *cogMethod; sqInt freeableUsage; usqInt freedSoFar; @@ -10499,7 +10543,7 @@ } } while((freedSoFar < amountToFree) && (((freeableUsage += 1)) < CMMaxUsageCount)); - } +}
/* Answer that all entries in youngReferrers are in-use and have the @@ -15000,11 +15044,11 @@ genoperand(RetN, 0); jmpTarget(jumpSC, gLabel()); } - ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, (((callerSavedRegMask()) | (1LL << ReceiverResultReg)) - (1LL << ReceiverResultReg)), 1, (callerSavedRegMask & (1LL << ReceiverResultReg) + ceStoreCheckTrampoline = genTrampolineForcallednumArgsargargargargregsToSavepushLinkRegresultRegappendOpcodes(remember, "ceStoreCheckTrampoline", 1, ReceiverResultReg, null, null, null, ((CallerSavedRegisterMask | (1LL << ReceiverResultReg)) - (1LL << ReceiverResultReg)), 1, (CallerSavedRegisterMask & (1LL << ReceiverResultReg) ? ReceiverResultReg : RAX), CheckRememberedInTrampoline); ceStoreCheckContextReceiverTrampoline = genStoreCheckContextReceiverTrampoline(); - ceScheduleScavengeTrampoline = genTrampolineForcalledregsToSave(ceScheduleScavenge, "ceScheduleScavengeTrampoline", callerSavedRegMask()); + ceScheduleScavengeTrampoline = genTrampolineForcalledregsToSave(ceScheduleScavenge, "ceScheduleScavengeTrampoline", CallerSavedRegisterMask); ceSmallActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 0, "ceSmallMethodContext"); ceSmallActiveContextInBlockTrampoline = genActiveContextTrampolineLargeinBlockcalled(0, 1, "ceSmallBlockContext"); ceLargeActiveContextInMethodTrampoline = genActiveContextTrampolineLargeinBlockcalled(1, 0, "ceLargeMethodContext"); @@ -15020,7 +15064,6 @@ static sqInt NoDbgRegParms genGetActiveContextLargeinBlock(sqInt isLarge, sqInt isInBlock) { - AbstractInstruction *abstractInstruction; sqInt address; sqInt address1; AbstractInstruction *anInstruction; @@ -15241,9 +15284,7 @@ /* begin RetN: */ genoperand(RetN, 0); jmpTarget(jumpNeedScavenge, gLabel()); - /* begin CallRT: */ - abstractInstruction = genoperand(Call, ceScheduleScavengeTrampoline); - (abstractInstruction->annotation = IsRelativeCall); + CallRTregistersToBeSavedMask(ceScheduleScavengeTrampoline, ((1LL << ReceiverResultReg) | (1LL << SendNumArgsReg)) | (1LL << ClassReg));
/* begin Jump: */ genoperand(Jump, ((sqInt)continuation)); @@ -16794,13 +16835,6 @@ return self_in_storeToReg; }
- /* CogSSBytecodeFixup>>#isBackwardBranchFixup */ -static sqInt NoDbgRegParms -isBackwardBranchFixup(BytecodeFixup * self_in_isBackwardBranchFixup) -{ - return ((self_in_isBackwardBranchFixup->simStackPtr)) == UnknownSimStackPtrFlag; -} - /* CogSSBytecodeFixup>>#isMergeFixup */ static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup) @@ -16808,14 +16842,7 @@ return (((usqInt)((self_in_isMergeFixup->targetInstruction)))) == NeedsMergeFixupFlag; }
- /* CogSSBytecodeFixup>>#isMergeFixupOrIsFixedUp */ -static sqInt NoDbgRegParms -isMergeFixupOrIsFixedUp(BytecodeFixup * self_in_isMergeFixupOrIsFixedUp) -{ - return (((usqInt)((self_in_isMergeFixupOrIsFixedUp->targetInstruction)))) >= NeedsMergeFixupFlag; -}
- /* Answer an unused abstract register in the liveRegMask. Subclasses with more registers can override to answer them. N.B. Do /not/ allocate TempReg. */ @@ -16864,20 +16891,6 @@ }
-/* See e.g. Figure 3.4 Register Usage in - System V Application Binary Interface - AMD64 Architecture Processor Supplement - N.B. We are playing fast and loose here being processor-specific. - Soon enough this needs to be OS-specific. */ - - /* CogX64Compiler>>#callerSavedRegisterMask */ -static sqInt NoDbgRegParms -callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask) -{ - return ((((((((1LL << RAX) | (1LL << RCX)) | (1LL << RDX)) | (1LL << RSI)) | (1LL << RDI)) | (1LL << R8)) | (1LL << R9)) | (1LL << R10)) | (1LL << R11); -} - - /* Answer the address the full call immediately preceding callSiteReturnAddress will jump to. */ @@ -23144,7 +23157,7 @@ CogBlockMethod *cogMethod1; BytecodeDescriptor *descriptor; sqInt distance; - usqInt endbcpc; + sqInt endbcpc; sqInt errCode; CogMethod *homeMethod; sqInt isBackwardBranch; @@ -24748,7 +24761,6 @@ compileCogMethod(sqInt selector) { unsigned long allocBytes; - sqInt debugStackPointers; int extra; unsigned long fixupBytes; sqInt numBlocks; @@ -24880,6 +24892,15 @@ sqInt iLimiT; AbstractInstruction *jumpSkip;
+ +# if IMMUTABILITY + if (needsTwoPath) { + compileTwoPathFrameBuild(); + return; + } + +# endif /* IMMUTABILITY */ + if (!needsFrame) { initSimStackForFramelessMethod(initialPC); return; @@ -24945,6 +24966,134 @@ initSimStackForFramefulMethod(initialPC); }
+ +/* Build a frame for a CogMethod activation. See CoInterpreter + class>>initializeFrameIndices. receiver (in ReceiverResultReg) + arg0 + ... + argN + caller's saved ip/this stackPage (for a base frame) + fp-> saved fp + method + context (uninitialized?) + receiver + first temp + ... + sp-> Nth temp + If there is a primitive and an error code the Nth temp is the error code. + Ensure SendNumArgsReg is set early on (incidentally to nilObj) because + it is the flag determining whether context switch is allowed on + stack-overflow. */ +/* We are in a method where the frame is needed *only* for instance variable + store, typically a setter method. + This case has 20% overhead with Immutability compared to setter without + immutability because of the stack + frame creation. We compile two path, one where the object is immutable, + one where it isn't. At the beginning + of the frame build, we take one path or the other depending on the + receiver mutability. + + Note: this specific case happens only where there are only instance + variabel stores. We could do something + similar for literal variable stores, but we don't as it's too uncommon. + */ + + /* StackToRegisterMappingCogit>>#compileTwoPathFrameBuild */ +#if IMMUTABILITY +static void +compileTwoPathFrameBuild(void) +{ + sqInt address; + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + sqInt constant; + sqInt i; + sqInt iLimiT; + AbstractInstruction * jumpImmutable; + AbstractInstruction *jumpSkip; + + assert(needsFrame); + assert(IMMUTABILITY); + assert(needsTwoPath); + assert(blockCount == 0); + + /* first path. The receiver is mutable */ + jumpImmutable = genJumpImmutablescratchReg(ReceiverResultReg, TempReg); + initSimStackForFramelessMethod(initialPC); + /* begin compileMethodBody */ + if (endPC < initialPC) { + goto l7; + } + compileAbstractInstructionsFromthrough(initialPC + (deltaToSkipPrimAndErrorStoreInheader(methodObj, methodHeader)), endPC); +l7: /* end compileMethodBody */; + + /* reset because it impact inst var store compilation */ + needsTwoPath = 0; + jmpTarget(jumpImmutable, gLabel()); + genPushRegisterArgs(); + if (!needsFrame) { + return; + } + /* begin PushR: */ + genoperand(PushR, FPReg); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SPReg, FPReg); + addDependent(methodLabel, annotateAbsolutePCRef(gPushCw(((sqInt)methodLabel)))); + /* begin genMoveNilR: */ + constant = nilObject(); + if (shouldAnnotateObjectReference(constant)) { + annotateobjRef(gMoveCwR(constant, SendNumArgsReg), constant); + } + else { + /* begin MoveCq:R: */ + anInstruction = genoperandoperand(MoveCqR, constant, SendNumArgsReg); + } + /* begin PushR: */ + genoperand(PushR, SendNumArgsReg); + /* begin PushR: */ + genoperand(PushR, ReceiverResultReg); + for (i = (methodOrBlockNumArgs + 1), iLimiT = (temporaryCountOfMethodHeader(methodHeader)); i <= iLimiT; i += 1) { + /* begin PushR: */ + genoperand(PushR, SendNumArgsReg); + } + if (((primitiveIndexOfMethodheader(methodObj, methodHeader)) > 0) + && ((longStoreBytecodeForHeader(methodHeader)) == (fetchByteofObject(initialPC + (sizeOfCallPrimitiveBytecode(methodHeader)), methodObj)))) { + compileGetErrorCode(); + } + /* begin MoveAw:R: */ + address = stackLimitAddress(); + /* begin gen:literal:operand: */ + anInstruction3 = genoperandoperand(MoveAwR, address, TempReg); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, TempReg, SPReg); + if (canContextSwitchIfActivatingheader(methodObj, methodHeader)) { + /* begin JumpBelow: */ + genConditionalBranchoperand(JumpBelow, ((sqInt)stackOverflowCall)); + /* begin Label */ + stackCheckLabel = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + } + else { + /* begin JumpAboveOrEqual: */ + jumpSkip = genConditionalBranchoperand(JumpAboveOrEqual, ((sqInt)0)); + /* begin MoveCq:R: */ + anInstruction1 = genoperandoperand(MoveCqR, 0, SendNumArgsReg); + /* begin Jump: */ + genoperand(Jump, ((sqInt)stackOverflowCall)); + jmpTarget(jumpSkip, (stackCheckLabel = gLabel())); + } + /* begin annotateBytecode: */ + (stackCheckLabel->annotation = HasBytecodePC); + if (numIRCs > 0) { + /* begin PrefetchAw: */ + anInstruction2 = genoperand(PrefetchAw, theIRCs); + } + + initSimStackForFramefulMethod(initialPC); +} +#endif /* IMMUTABILITY */ + /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs) @@ -25561,9 +25710,9 @@ static void generateTracingTrampolines(void) { - ceTraceLinkedSendTrampoline = genTrampolineForcalledargregsToSave(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", ReceiverResultReg, callerSavedRegMask); - ceTraceBlockActivationTrampoline = genTrampolineForcalledregsToSave(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", callerSavedRegMask); - ceTraceStoreTrampoline = genTrampolineForcalledargargregsToSave(ceTraceStoreOfinto, "ceTraceStoreTrampoline", TempReg, ReceiverResultReg, callerSavedRegMask); + ceTraceLinkedSendTrampoline = genTrampolineForcalledargregsToSave(ceTraceLinkedSend, "ceTraceLinkedSendTrampoline", ReceiverResultReg, CallerSavedRegisterMask); + ceTraceBlockActivationTrampoline = genTrampolineForcalledregsToSave(ceTraceBlockActivation, "ceTraceBlockActivationTrampoline", CallerSavedRegisterMask); + ceTraceStoreTrampoline = genTrampolineForcalledargargregsToSave(ceTraceStoreOfinto, "ceTraceStoreTrampoline", TempReg, ReceiverResultReg, CallerSavedRegisterMask); }
/* StackToRegisterMappingCogit>>#genJumpBackTo: */ @@ -26076,7 +26225,7 @@ ensureReceiverResultRegContainsSelf(); /* begin genPushMaybeContextSlotIndex: */ assert(needsFrame); - if (callerSavedRegMask & (1LL << ReceiverResultReg)) { + if (CallerSavedRegisterMask & (1LL << ReceiverResultReg)) {
/* We have no way of reloading ReceiverResultReg since we need the inst var value as the result. */ (optStatus.isReceiverResultRegLive = 0); @@ -26979,6 +27128,7 @@ AbstractInstruction *anInstruction; sqInt association; sqInt topReg; + sqInt topReg1;
assert(needsFrame); /* begin genLoadLiteralVariable:in: */ @@ -26998,17 +27148,27 @@ /* begin genStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */ # if IMMUTABILITY - /* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */ - ssAllocateRequiredReg(ClassReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - ssFlushTo(simStackPtr); - genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); + if (needsTwoPath) {
+ /* first path, receiver is mutable */ + /* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */ + topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg); + ssStorePoptoReg(popBoolean, topReg); + genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); + } + else { + /* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */ + ssAllocateRequiredReg(ClassReg); + ssStoreAndReplacePoptoReg(popBoolean, ClassReg); + ssFlushTo(simStackPtr); + genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, ValueIndex, ReceiverResultReg, TempReg, needsStoreCheck, 0); + } + # else /* IMMUTABILITY */ /* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */ - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); + topReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg); + ssStorePoptoReg(popBoolean, topReg1); + genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg1, ValueIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
# endif /* IMMUTABILITY */
@@ -27108,23 +27268,34 @@ genStorePopReceiverVariableneedsStoreCheck(sqInt popBoolean, sqInt slotIndex, sqInt needsStoreCheck) { sqInt topReg; + sqInt topReg1;
ssFlushUpThroughReceiverVariable(slotIndex); ensureReceiverResultRegContainsSelf(); /* begin genStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */ # if IMMUTABILITY - /* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */ - ssAllocateRequiredReg(ClassReg); - ssStoreAndReplacePoptoReg(popBoolean, ClassReg); - ssFlushTo(simStackPtr); - genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck, 1); + if (needsTwoPath) {
+ /* first path, receiver is mutable */ + /* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */ + topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg); + ssStorePoptoReg(popBoolean, topReg); + genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); + } + else { + /* begin genImmCheckStorePop:slotIndex:destReg:needsStoreCheck:needsRestoreRcvr: */ + ssAllocateRequiredReg(ClassReg); + ssStoreAndReplacePoptoReg(popBoolean, ClassReg); + ssFlushTo(simStackPtr); + genStoreWithImmutabilityCheckSourceRegslotIndexdestRegscratchRegneedsStoreCheckneedRestoreRcvr(ClassReg, slotIndex, ReceiverResultReg, TempReg, needsStoreCheck, 1); + } + # else /* IMMUTABILITY */ /* begin genVanillaStorePop:slotIndex:destReg:needsStoreCheck: */ - topReg = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg); - ssStorePoptoReg(popBoolean, topReg); - genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck); + topReg1 = allocateRegForStackEntryAtnotConflictingWith(0, 1LL << ReceiverResultReg); + ssStorePoptoReg(popBoolean, topReg1); + genStoreSourceRegslotIndexdestRegscratchReginFrameneedsStoreCheck(topReg1, slotIndex, ReceiverResultReg, TempReg, needsFrame, needsStoreCheck);
# endif /* IMMUTABILITY */
@@ -27207,6 +27378,7 @@ { AbstractInstruction *abstractInstruction; AbstractInstruction *abstractInstruction1; + sqInt framelessReturn; sqInt offset;
@@ -27222,7 +27394,17 @@ (abstractInstruction->annotation = HasBytecodePC); return 0; } - if (needsFrame) { + +# if IMMUTABILITY + framelessReturn = needsFrame + && (!needsTwoPath); + +# else /* IMMUTABILITY */ + framelessReturn = needsFrame; + +# endif /* IMMUTABILITY */ + + if (framelessReturn) { /* begin MoveR:R: */ genoperandoperand(MoveRR, FPReg, SPReg); /* begin PopR: */ @@ -27871,6 +28053,12 @@
needsFrame = 0; prevBCDescriptor = null; + +# if IMMUTABILITY + needsTwoPath = 0; + +# endif /* IMMUTABILITY */ + numIRCs = 0;
if ((primitiveIndex > 0) @@ -27895,6 +28083,21 @@ && (pc >= latestContinuation)) { endPC = pc; } + +# if IMMUTABILITY + if (!(needsFrame + && (!needsTwoPath))) { + if ((((descriptor->needsFrameFunction)) == null) + || (((descriptor->needsFrameFunction))(framelessStackDelta))) { + needsFrame = 1; + needsTwoPath = ((descriptor->generator)) == genStoreAndPopReceiverVariableBytecode; + } + else { + framelessStackDelta += (descriptor->stackDelta); + } + } + +# else /* IMMUTABILITY */ if (!needsFrame) { if ((((descriptor->needsFrameFunction)) == null) || (((descriptor->needsFrameFunction))(framelessStackDelta))) { @@ -27904,6 +28107,9 @@ framelessStackDelta += (descriptor->stackDelta); } } + +# endif /* IMMUTABILITY */ + if (isBranch(descriptor)) { distance = ((descriptor->spanFunction))(descriptor, pc, nExts, methodObj); targetPC = (pc + ((descriptor->numBytes))) + distance; @@ -27945,7 +28151,7 @@ static void NoDbgRegParms ssAllocateCallReg(sqInt requiredReg) { - ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | (1LL << requiredReg), simStackPtr); + ssAllocateRequiredRegMaskupThrough(CallerSavedRegisterMask | (1LL << requiredReg), simStackPtr); }
@@ -27957,7 +28163,7 @@ static void NoDbgRegParms ssAllocateCallRegand(sqInt requiredReg1, sqInt requiredReg2) { - ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | ((1LL << requiredReg1) | (1LL << requiredReg2)), simStackPtr); + ssAllocateRequiredRegMaskupThrough(CallerSavedRegisterMask | ((1LL << requiredReg1) | (1LL << requiredReg2)), simStackPtr); }
@@ -27969,7 +28175,7 @@ static void NoDbgRegParms ssAllocateCallRegandand(sqInt requiredReg1, sqInt requiredReg2, sqInt requiredReg3) { - ssAllocateRequiredRegMaskupThrough(callerSavedRegMask | ((1LL << requiredReg1) | ((1LL << requiredReg2) | (1LL << requiredReg3))), simStackPtr); + ssAllocateRequiredRegMaskupThrough(CallerSavedRegisterMask | ((1LL << requiredReg1) | ((1LL << requiredReg2) | (1LL << requiredReg3))), simStackPtr); }
/* StackToRegisterMappingCogit>>#ssAllocateRequiredRegMask:upThrough: */
Modified: branches/Cog/nsspur64src/vm/cointerp.c =================================================================== --- branches/Cog/nsspur64src/vm/cointerp.c 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspur64src/vm/cointerp.c 2016-06-01 19:32:08 UTC (rev 3733) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e from - CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -2452,7 +2452,7 @@ }; sqInt checkedPluginName; char expensiveAsserts = 0; -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1872"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1876"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; volatile int sendTrace;
@@ -40930,7 +40930,7 @@ sqInt oopRcvr; sqInt oopResult; usqLong result; - sqInt resultIsNegative; + int resultIsNegative; char *sp;
oopArg = longAt(GIV(stackPointer) + (0 * BytesPerWord)); @@ -61627,7 +61627,7 @@ usqInt prevFree; usqInt prevFreeChunk; usqInt prevPrevFree; - usqInt prevPrevFreeChunk; + sqInt prevPrevFreeChunk; sqInt slotBytes; sqInt slotBytes1; usqInt there; @@ -67437,7 +67437,7 @@ bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil) { usqInt bridgeSpan; - usqInt clifton; + sqInt clifton; usqInt segEnd;
segEnd = ((aSegment->segSize)) + ((aSegment->segStart)); @@ -67618,7 +67618,7 @@ static void postSnapshot(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - usqInt address; + sqInt address; sqInt bytes; usqInt freeChunk; sqInt i; @@ -67681,7 +67681,7 @@ sqInt limit; sqInt newEndOfMemory; sqInt next; - usqInt node; + sqInt node; usqInt numSlots; usqInt numSlots1; SpurSegmentInfo *seg; @@ -68024,8 +68024,8 @@ { usqLong firstSavedBridgeWord; sqInt nWritten; - usqInt pier1; - usqInt pier2; + sqInt pier1; + sqInt pier2; usqLong secondSavedBridgeWord;
pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * BaseHeaderSize);
Modified: branches/Cog/nsspur64src/vm/cointerp.h =================================================================== --- branches/Cog/nsspur64src/vm/cointerp.h 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspur64src/vm/cointerp.h 2016-06-01 19:32:08 UTC (rev 3733) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */
Modified: branches/Cog/nsspur64src/vm/gcc3x-cointerp.c =================================================================== --- branches/Cog/nsspur64src/vm/gcc3x-cointerp.c 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspur64src/vm/gcc3x-cointerp.c 2016-06-01 19:32:08 UTC (rev 3733) @@ -2,11 +2,11 @@
/* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e from - CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -2455,7 +2455,7 @@ }; sqInt checkedPluginName; char expensiveAsserts = 0; -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1872"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.1876"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; volatile int sendTrace;
@@ -40939,7 +40939,7 @@ sqInt oopRcvr; sqInt oopResult; usqLong result; - sqInt resultIsNegative; + int resultIsNegative; char *sp;
oopArg = longAt(GIV(stackPointer) + (0 * BytesPerWord)); @@ -61636,7 +61636,7 @@ usqInt prevFree; usqInt prevFreeChunk; usqInt prevPrevFree; - usqInt prevPrevFreeChunk; + sqInt prevPrevFreeChunk; sqInt slotBytes; sqInt slotBytes1; usqInt there; @@ -67446,7 +67446,7 @@ bridgeFromto(SpurSegmentInfo *aSegment, SpurSegmentInfo *nextSegmentOrNil) { usqInt bridgeSpan; - usqInt clifton; + sqInt clifton; usqInt segEnd;
segEnd = ((aSegment->segSize)) + ((aSegment->segStart)); @@ -67627,7 +67627,7 @@ static void postSnapshot(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT - usqInt address; + sqInt address; sqInt bytes; usqInt freeChunk; sqInt i; @@ -67690,7 +67690,7 @@ sqInt limit; sqInt newEndOfMemory; sqInt next; - usqInt node; + sqInt node; usqInt numSlots; usqInt numSlots1; SpurSegmentInfo *seg; @@ -68033,8 +68033,8 @@ { usqLong firstSavedBridgeWord; sqInt nWritten; - usqInt pier1; - usqInt pier2; + sqInt pier1; + sqInt pier2; usqLong secondSavedBridgeWord;
pier1 = (((segment->segSize)) + ((segment->segStart))) - (2 * BaseHeaderSize);
Modified: branches/Cog/nsspursrc/vm/cogit.h =================================================================== --- branches/Cog/nsspursrc/vm/cogit.h 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspursrc/vm/cogit.h 2016-06-01 19:32:08 UTC (rev 3733) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1872 uuid: 6db6d610-b1a5-4f4d-978d-22c917bdb3e4 + CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */
Modified: branches/Cog/nsspursrc/vm/cogitARMv5.c =================================================================== --- branches/Cog/nsspursrc/vm/cogitARMv5.c 2016-05-26 20:01:37 UTC (rev 3732) +++ branches/Cog/nsspursrc/vm/cogitARMv5.c 2016-06-01 19:32:08 UTC (rev 3733) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 + CCodeGenerator VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e from - StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 + StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1860 uuid: 4d58d995-ee0c-4330-9190-adfa038e8f24 " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1876 uuid: 28e91d90-4197-436d-9702-7c7dae02e85e " __DATE__ ; char *__cogitBuildInfo = __buildInfo;
@@ -39,8 +39,8 @@ #define AndOpcode 0 #define AndRR 91 #define AnnotationShift 5 -#define Arg0Reg 4 -#define Arg1Reg 5 +#define Arg0Reg 3 +#define Arg1Reg 4 #define ArithmeticShiftRightCqR 80 #define ArithmeticShiftRightRR 81 #define BadRegisterSet 1 @@ -52,6 +52,7 @@ #define CArg2Reg 2 #define CArg3Reg 3 #define Call 6 +#define CallerSavedRegisterMask 0x120C #define CallFull 7 #define CC 3 #if !defined(CheckRememberedInTrampoline) /* Allow this to be overridden on the compiler command line */ @@ -61,7 +62,7 @@ #define ClassBlockClosureCompactIndex 37 #define ClassFloatCompactIndex 34 #define ClassMethodContextCompactIndex 36 -#define ClassReg 8 +#define ClassReg 2 #define ClosureFirstCopiedValueIndex 3 #define ClosureIndex 4 #define ClosureNumArgsIndex 2 @@ -73,7 +74,7 @@ #define CMMaxUsageCount 7 #define CMMethod 2 #define CMOpenPIC 5 -#define CMPSMULL 121 +#define CMPSMULL 123 #define CmpC32R 102 #define CmpCqR 94 #define CmpCwR 101 @@ -96,7 +97,9 @@ #define DPFPReg2 2 #define EncounteredUnknownBytecode -6 #define EQ 0 -#define Extra0Reg 9 +#define Extra0Reg 7 +#define Extra1Reg 8 +#define Extra2Reg 9 #define Fill32 4 #define FirstAnnotation 64 #define FirstJump 11 @@ -249,6 +252,7 @@ #define PC 15 #define PCReg 15 #define PL 5 +#define PopLDM 119 #define PopR 72 #define PrefetchAw 76 #define PrimCallCollectsProfileSamples 8 @@ -261,9 +265,10 @@ #define PushCq 74 #define PushCw 75 #define PushR 73 +#define PushSTM 120 #define R0 0 #define ReceiverIndex 5 -#define ReceiverResultReg 7 +#define ReceiverResultReg 5 #define RetN 8 #define RISCTempReg 12 #define RsbOpcode 3 @@ -445,7 +450,6 @@ static sqInt NoDbgRegParms bicsrnimmror(AbstractInstruction * self_in_bicsrnimmror, sqInt destReg, sqInt srcReg, sqInt immediate, sqInt rot); static sqInt NoDbgRegParms bl(AbstractInstruction * self_in_bl, sqInt offset); static sqInt NoDbgRegParms b(AbstractInstruction * self_in_b, sqInt offset); -static sqInt NoDbgRegParms callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask); static sqInt NoDbgRegParms callInstructionByteSize(AbstractInstruction * self_in_callInstructionByteSize); static sqInt NoDbgRegParms callTargetFromReturnAddress(AbstractInstruction * self_in_callTargetFromReturnAddress, sqInt callSiteReturnAddress); static sqInt NoDbgRegParms computeMaximumSize(AbstractInstruction * self_in_computeMaximumSize); @@ -456,6 +460,7 @@ static void NoDbgRegParms concretizeConditionalInstruction(AbstractInstruction * self_in_concretizeConditionalInstruction); static usqInt NoDbgRegParms concretizeFill32(AbstractInstruction * self_in_concretizeFill32); static usqInt NoDbgRegParms concretizeMSR(AbstractInstruction * self_in_concretizeMSR); +static usqInt NoDbgRegParms concretizePushOrPopMultipleRegisters(AbstractInstruction * self_in_concretizePushOrPopMultipleRegisters, sqInt doPush); static usqInt NoDbgRegParms concretizeSMULL(AbstractInstruction * self_in_concretizeSMULL); static sqInt NoDbgRegParms conditionIsNotNever(AbstractInstruction * self_in_conditionIsNotNever, sqInt instr); static sqInt NoDbgRegParms dataOpTyperdrnrmlsr(AbstractInstruction * self_in_dataOpTyperdrnrmlsr, sqInt armOpcode, sqInt destReg, sqInt srcReg, sqInt addReg, sqInt shft); @@ -472,8 +477,6 @@ static AbstractInstruction * NoDbgRegParms genPushRegisterArgsForNumArgsscratchReg(AbstractInstruction * self_in_genPushRegisterArgsForNumArgsscratchReg, sqInt numArgs, sqInt ignored); static sqInt NoDbgRegParms genRemoveNArgsFromStack(AbstractInstruction * self_in_genRemoveNArgsFromStack, sqInt n); static AbstractInstruction * NoDbgRegParms genRestoreRegsExcept(AbstractInstruction * self_in_genRestoreRegsExcept, sqInt abstractReg); -static sqInt NoDbgRegParms genRestoreRegs(AbstractInstruction * self_in_genRestoreRegs, sqInt regMask); -static sqInt NoDbgRegParms genSaveRegs(AbstractInstruction * self_in_genSaveRegs, sqInt regMask); static sqInt NoDbgRegParms genSaveStackPointers(AbstractInstruction * self_in_genSaveStackPointers); static AbstractInstruction * NoDbgRegParms genSubstituteReturnAddress(AbstractInstruction * self_in_genSubstituteReturnAddress, sqInt retpc); static sqInt NoDbgRegParms instructionBeforeAddress(AbstractInstruction * self_in_instructionBeforeAddress, sqInt followingAddress); @@ -569,7 +572,9 @@ static sqInt NoDbgRegParms blockCreationBytecodeSizeForHeader(sqInt aMethodHeader); static sqInt NoDbgRegParms blockDispatchTargetsForperformarg(CogMethod *cogMethod, usqInt (*binaryFunction)(sqInt mcpc, sqInt arg), sqInt arg); extern sqInt bytecodePCForstartBcpcin(sqInt mcpc, sqInt startbcpc, CogBlockMethod *cogMethod); +static AbstractInstruction * NoDbgRegParms CallFullRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); static AbstractInstruction * NoDbgRegParms CallNewspeakSend(sqInt callTarget); +static AbstractInstruction * NoDbgRegParms CallRTregistersToBeSavedMask(sqInt callTarget, sqInt registersToBeSaved); static AbstractInstruction * NoDbgRegParms gCall(sqInt callTarget); static AbstractInstruction * NoDbgRegParms gCmpCqR(sqInt quickConstant, sqInt reg); static AbstractInstruction * NoDbgRegParms gCmpCwR(sqInt wordConstant, sqInt reg); @@ -703,7 +708,7 @@ static AbstractInstruction * NoDbgRegParms gMoveMwrR(sqInt offset, sqInt baseReg, sqInt destReg); static AbstractInstruction * NoDbgRegParms gMoveRMwr(sqInt sourceReg, sqInt offset, sqInt baseReg); static AbstractInstruction * NoDbgRegParms gMoveRR(sqInt reg1, sqInt reg2); -static sqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); +static usqInt NoDbgRegParms mapEndFor(CogMethod *cogMethod); static sqInt NoDbgRegParms mapForperformUntilarg(CogMethod *cogMethod, sqInt (*functionSymbol)(sqInt annotation, char *mcpc, sqInt arg), sqInt arg); static sqInt NoDbgRegParms mapObjectReferencesInClosedPIC(CogMethod *cPIC); static void mapObjectReferencesInGeneratedRuntime(void); @@ -734,7 +739,7 @@ static sqInt NoDbgRegParms needsFrameNever(sqInt stackDelta); static sqInt NoDbgRegParms noAssertMethodClassAssociationOf(sqInt methodPointer); static sqInt noCogMethodsMaximallyMarked(void); -static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(sqInt cPIC); +static sqInt NoDbgRegParms noTargetsFreeInClosedPIC(CogMethod *cPIC); static sqInt NoDbgRegParms outputInstructionsAt(sqInt startAddress); static sqInt NoDbgRegParms outputInstructionsForGeneratedRuntimeAt(sqInt startAddress); static AbstractInstruction * NoDbgRegParms gPopR(sqInt reg); @@ -992,9 +997,7 @@ static sqInt NoDbgRegParms registerMask(SimStackEntry * self_in_registerMask); static sqInt NoDbgRegParms registerOrNone(SimStackEntry * self_in_registerOrNone); static SimStackEntry * NoDbgRegParms storeToReg(SimStackEntry * self_in_storeToReg, sqInt reg); -static sqInt NoDbgRegParms isBackwardBranchFixup(BytecodeFixup * self_in_isBackwardBranchFixup); static sqInt NoDbgRegParms isMergeFixup(BytecodeFixup * self_in_isMergeFixup); -static sqInt NoDbgRegParms isMergeFixupOrIsFixedUp(BytecodeFixup * self_in_isMergeFixupOrIsFixedUp); static AbstractInstruction * NoDbgRegParms allocateLiteral(sqInt aLiteral); static AbstractInstruction * NoDbgRegParms checkLiteralforInstruction(sqInt literal, AbstractInstruction *anInstruction); static sqInt NoDbgRegParms dumpLiterals(sqInt generateBranchAround); @@ -1117,6 +1120,9 @@ static CogMethod * NoDbgRegParms compileCogMethod(sqInt selector); static sqInt compileEntireMethod(void); static void compileFrameBuild(void); +#if IMMUTABILITY +static void compileTwoPathFrameBuild(void); +#endif /* IMMUTABILITY */ static sqInt NoDbgRegParms cPICMissTrampolineFor(sqInt numArgs); static sqInt doubleExtendedDoAnythingBytecode(void); static sqInt duplicateTopBytecode(void); @@ -1251,7 +1257,6 @@ static sqInt bytecodeSetOffset; void * CFramePointer; void * CStackPointer; -static sqInt callerSavedRegMask; static sqInt cbEntryOffset; static sqInt cbNoSwitchEntryOffset; sqInt ceBaseFrameReturnTrampoline; @@ -1314,6 +1319,7 @@ static sqInt debugFixupBreaks; static sqInt debugOpcodeIndices; unsigned long debugPrimCallStackOffset; +static sqInt debugStackPointers; static sqInt disassemblingMethod; static sqInt dynamicSuperSendTrampolines[NumSendTrampolines]; static AbstractInstruction * endCPICCase0; @@ -1877,6 +1883,7 @@ sqInt missOffset; static usqInt mzFreeStart; static sqInt needsFrame; +static sqInt needsTwoPath; static sqInt nextLiteralIndex; static AbstractInstruction * noCheckEntry; static sqInt numAbstractOpcodes; @@ -1938,7 +1945,6 @@ #define blockAlignment(self) 8 #define blockStartAt(index) (&blockStarts[index]) #define breakOnImplicitReceiver() (traceFlags & 64) -#define callerSavedRegMask() callerSavedRegMask #define ceBaseFrameReturnPC() ceBaseFrameReturnTrampoline #define ceCannotResumePC() ((usqInt)ceCannotResumeTrampoline) #define ceCheckFeatures() ceCheckFeaturesFunction() @@ -2341,6 +2347,12 @@ if (!(liveRegsMask & (1L << Extra0Reg))) { return Extra0Reg; } + if (!(liveRegsMask & (1L << Extra1Reg))) { + return Extra1Reg; + } + if (!(liveRegsMask & (1L << Extra2Reg))) { + return Extra2Reg; + } if (!(liveRegsMask & (1L << Arg1Reg))) { return Arg1Reg; } @@ -2399,23 +2411,6 @@ }
-/* According to IHI0042E ARM Architecture Procedure Calling Standard, in - section 5.1.1: - A subroutine must preserve the contents of the registers r4-r8, r10, r11 - and SP (and r9 in PCS variants that designate r9 as v6). - SP = r13, so the callee-saved regs are r4-r8 & r10-r12. - The caller-saved registers are those that are not callee-saved and not - reserved for hardware/abi uses, - i..e r0-r3, r9 & r12. */ - - /* CogARMCompiler>>#callerSavedRegisterMask */ -static sqInt NoDbgRegParms -callerSavedRegisterMask(AbstractInstruction * self_in_callerSavedRegisterMask) -{ - return (((((1L << 0) | (1L << 1)) | (1L << 2)) | (1L << 3)) | (1L << 9)) | (1L << 12); -} - - /* ARM calls and jumps span +/- 32 mb, more than enough for intra-zone calls and jumps. */ @@ -2533,6 +2528,8 @@ case SMULL: case MSR: case CMPSMULL: + case PopLDM: + case PushSTM: case MoveRR: case MoveRdRd: case MoveXbrRR: @@ -2851,7 +2848,18 @@ return ((self_in_concretizeMSR->machineCodeSize) = 4); }
+ /* CogARMCompiler>>#concretizePushOrPopMultipleRegisters: */ +static usqInt NoDbgRegParms +concretizePushOrPopMultipleRegisters(AbstractInstruction * self_in_concretizePushOrPopMultipleRegisters, sqInt doPush) +{ + assert((((self_in_concretizePushOrPopMultipleRegisters->operands))[0]) != 0); + ((self_in_concretizePushOrPopMultipleRegisters->machineCode))[0] = ((((AL << 28) + ((doPush + ? 146L << 20 + : 139L << 20))) + (SP << 16)) + (((self_in_concretizePushOrPopMultipleRegisters->operands))[0])); + return ((self_in_concretizePushOrPopMultipleRegisters->machineCodeSize) = 4); +}
+ /* Generate an SMULL loResultReg, hiResultReg, srcA, srcB instruction */
/* CogARMCompiler>>#concretizeSMULL */ @@ -5008,6 +5016,14 @@ concretizeMSR(self_in_dispatchConcretize); return;
+ case PopLDM: + concretizePushOrPopMultipleRegisters(self_in_dispatchConcretize, 0); + return; + + case PushSTM: + concretizePushOrPopMultipleRegisters(self_in_dispatchConcretize, 1); + return; + case MoveCqR: /* begin concretizeMoveCqR */ word2 = ((self_in_dispatchConcretize->operands))[0]; @@ -5838,7 +5854,6 @@ static AbstractInstruction * NoDbgRegParms genDivRRQuoRem(AbstractInstruction * self_in_genDivRRQuoRem, sqInt abstractRegDivisor, sqInt abstractRegDividend, sqInt abstractRegQuotient, sqInt abstractRegRemainder) { - sqInt callTarget; usqInt divRemFunctionAddr; AbstractInstruction * inst; sqInt rDividend; @@ -5876,12 +5891,8 @@ self_in_saveAndRestoreLinkRegAround = ((AbstractInstruction *) (backEnd())); /* begin PushR: */ inst = genoperand(PushR, LinkReg); - /* begin CallFullRT: */ - callTarget = ((usqInt)divRemFunctionAddr); - /* begin CallFull: */
@@ Diff output truncated at 50000 characters. @@
vm-dev@lists.squeakfoundation.org