Revision: 3404 Author: eliot Date: 2015-07-16 08:25:58 -0700 (Thu, 16 Jul 2015) Log Message: ----------- CogVM source as per VMMaker.oscog-eem.1423
All Cogits: Implement a machine code perform:[with:]* primitive. Eliminate the duplication of SimpleStackBasedCogit/StackToRegisterMappingCogit>>compileOpenPIC:numArgs: now that we have dead code elimination enabled.
ARM Cogits: Use __aeabit_idivmod to implement machine code div/mod primitives on ARM.
64-bits: Change the type of the event buffer from int[8] to long[8].
Newspeak: Compile Newspeak self and super sends as clean sends as well. Slower in monomorphic case but net win for the larger benchmarks, presumably because it avoids I-cache flushes in the polymorphic case.
Also means implementing polymorphic caches for clean sends will benefit all non-ordinary sends.
DeltaBlue +8.2% Splay +7.6% ParserCombinators +4.7% Richards +0.5% SlotRead (replaced with self send) -17.6%
Spill ReceiverResultReg before runtime call to fix pushEnclosingObject on ARM. (ReceiverResultReg is edx/caller-saved on IA32 but r7/callee-saved on ARM.)
Fix the 64-bit Newspeak builds' plugins.ext
Nuke obsolete newspeak.*.v3 build directories.
Modified Paths: -------------- branches/Cog/build.linux64x64/newspeak.cog.spur/plugins.ext branches/Cog/build.linux64x64/newspeak.sista.spur/plugins.ext branches/Cog/build.linux64x64/newspeak.stack.spur/plugins.ext branches/Cog/nsspursrc/vm/cogit.h branches/Cog/nsspursrc/vm/cogitARMv5.c branches/Cog/nsspursrc/vm/cogitIA32.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/platforms/unix/config/bin.squeak.sh.in branches/Cog/platforms/unix/config/squeak.sh.in branches/Cog/spursistasrc/vm/cogit.h branches/Cog/spursistasrc/vm/cogitARMv5.c branches/Cog/spursistasrc/vm/cogitIA32.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/cointerp.c branches/Cog/spursrc/vm/cointerp.h branches/Cog/spursrc/vm/gcc3x-cointerp.c branches/Cog/spurstack64src/vm/gcc3x-interp.c branches/Cog/spurstack64src/vm/interp.c branches/Cog/spurstacksrc/vm/gcc3x-interp.c branches/Cog/spurstacksrc/vm/interp.c branches/Cog/src/vm/cogit.h branches/Cog/src/vm/cogitARMv5.c branches/Cog/src/vm/cogitIA32.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
Removed Paths: ------------- branches/Cog/build.linux32x86/newspeak.cog.v3/build/ branches/Cog/build.linux32x86/newspeak.cog.v3/build.assert/ branches/Cog/build.linux32x86/newspeak.cog.v3/build.assert.itimerheartbeat/ branches/Cog/build.linux32x86/newspeak.cog.v3/build.debug/ branches/Cog/build.linux32x86/newspeak.cog.v3/build.debug.itimerheartbeat/ branches/Cog/build.linux32x86/newspeak.cog.v3/build.itimerheartbeat/ branches/Cog/build.linux32x86/newspeak.cog.v3/makeallclean branches/Cog/build.linux32x86/newspeak.cog.v3/makealldirty branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.ext branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.int branches/Cog/build.win32x86/newspeak.cog.v3/
Property Changed: ---------------- branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
Deleted: branches/Cog/build.linux32x86/newspeak.cog.v3/makeallclean =================================================================== --- branches/Cog/build.linux32x86/newspeak.cog.v3/makeallclean 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux32x86/newspeak.cog.v3/makeallclean 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,6 +0,0 @@ -#!/bin/sh -trap 'exit 2' HUP INT PIPE TERM -for d in `dirname $0`/build*; do - (cd $d - echo y | ./mvm "$@") -done
Deleted: branches/Cog/build.linux32x86/newspeak.cog.v3/makealldirty =================================================================== --- branches/Cog/build.linux32x86/newspeak.cog.v3/makealldirty 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux32x86/newspeak.cog.v3/makealldirty 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,6 +0,0 @@ -#!/bin/sh -trap 'exit 2' HUP INT PIPE TERM -for d in `dirname $0`/build*; do - (cd $d - echo n | ./mvm "$@") -done
Deleted: branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.ext =================================================================== --- branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.ext 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.ext 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,3 +0,0 @@ -# Copied, perhaps edited, from ../../../nscogsrc/examplePlugins.ext -EXTERNAL_PLUGINS = \ -SqueakSSL
Deleted: branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.int =================================================================== --- branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.int 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux32x86/newspeak.cog.v3/plugins.int 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,27 +0,0 @@ -# Copied, perhaps edited, from ../../../nscogsrc/examplePlugins.int -INTERNAL_PLUGINS = \ -AioPlugin \ -AsynchFilePlugin \ -BMPReadWriterPlugin \ -B2DPlugin \ -BitBltPlugin \ -DSAPrims \ -DropPlugin \ -FileCopyPlugin \ -FilePlugin \ -FloatArrayPlugin \ -FloatMathPlugin \ -ZipPlugin \ -JPEGReadWriter2Plugin \ -JPEGReaderPlugin \ -LargeIntegers \ -Matrix2x3Plugin \ -MiscPrimitivePlugin \ -IA32ABI \ -RePlugin \ -SecurityPlugin \ -SocketPlugin \ -SurfacePlugin \ -UUIDPlugin \ -UnixOSProcessPlugin \ -VMProfileLinuxSupportPlugin
Modified: branches/Cog/build.linux64x64/newspeak.cog.spur/plugins.ext =================================================================== --- branches/Cog/build.linux64x64/newspeak.cog.spur/plugins.ext 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux64x64/newspeak.cog.spur/plugins.ext 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,10 +1,3 @@ -# Copied, perhaps edited, from ../../src/examplePlugins.ext -# SqueakFFIPrims needs implementing -EXTERNAL_PLUGINS = \ -B3DAcceleratorPlugin \ -SqueakSSL \ -LocalePlugin \ -UnicodePlugin \ -UnixOSProcessPlugin \ -UUIDPlugin \ -XDisplayControlPlugin +# Copied, perhaps edited, from ../../../nscogsrc/examplePlugins.ext +EXTERNAL_PLUGINS = \ +SqueakSSL
Modified: branches/Cog/build.linux64x64/newspeak.sista.spur/plugins.ext =================================================================== --- branches/Cog/build.linux64x64/newspeak.sista.spur/plugins.ext 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux64x64/newspeak.sista.spur/plugins.ext 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,10 +1,3 @@ -# Copied, perhaps edited, from ../../src/examplePlugins.ext -# SqueakFFIPrims needs implementing -EXTERNAL_PLUGINS = \ -B3DAcceleratorPlugin \ -SqueakSSL \ -LocalePlugin \ -UnicodePlugin \ -UnixOSProcessPlugin \ -UUIDPlugin \ -XDisplayControlPlugin +# Copied, perhaps edited, from ../../../nscogsrc/examplePlugins.ext +EXTERNAL_PLUGINS = \ +SqueakSSL
Modified: branches/Cog/build.linux64x64/newspeak.stack.spur/plugins.ext =================================================================== --- branches/Cog/build.linux64x64/newspeak.stack.spur/plugins.ext 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/build.linux64x64/newspeak.stack.spur/plugins.ext 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,10 +1,3 @@ -# Copied, perhaps edited, from ../../src/examplePlugins.ext -# SqueakFFIPrims needs implementing -EXTERNAL_PLUGINS = \ -B3DAcceleratorPlugin \ -SqueakSSL \ -LocalePlugin \ -UnicodePlugin \ -UnixOSProcessPlugin \ -UUIDPlugin \ -XDisplayControlPlugin +# Copied, perhaps edited, from ../../../nscogsrc/examplePlugins.ext +EXTERNAL_PLUGINS = \ +SqueakSSL
Modified: branches/Cog/nsspursrc/vm/cogit.h =================================================================== --- branches/Cog/nsspursrc/vm/cogit.h 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/nsspursrc/vm/cogit.h 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b + CCodeGenerator VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe */
Modified: branches/Cog/nsspursrc/vm/cogitARMv5.c =================================================================== --- branches/Cog/nsspursrc/vm/cogitARMv5.c 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/nsspursrc/vm/cogitARMv5.c 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b + CCodeGenerator VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe from - StackToRegisterMappingCogit VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b + StackToRegisterMappingCogit VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe " __DATE__ ; char *__cogitBuildInfo = __buildInfo;
@@ -952,6 +952,7 @@ static sqInt compileFallbackToInterpreterPrimitive(void); static void compileGetErrorCode(void); static sqInt compileInterpreterPrimitive(void (*primitiveRoutine)(void)) NoDbgRegParms; +static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs) NoDbgRegParms; static sqInt extendedPushBytecode(void); static sqInt extendedStoreAndPopBytecode(void); static sqInt extendedStoreBytecode(void); @@ -989,6 +990,7 @@ static sqInt genLongStoreTemporaryVariableBytecode(void); static sqInt genLongUnconditionalBackwardJump(void); static sqInt genLongUnconditionalForwardJump(void); +static sqInt genLookupForPerformNumArgs(sqInt numArgs) NoDbgRegParms; static AbstractInstruction * genMoveFalseR(sqInt reg) NoDbgRegParms; static AbstractInstruction * genMoveTrueR(sqInt reg) NoDbgRegParms; static sqInt genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) NoDbgRegParms; @@ -1059,6 +1061,7 @@ static sqInt v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) NoDbgRegParms; extern void voidCogCompiledCode(void); static BlockStart * addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) NoDbgRegParms; +static void adjustArgumentsForPerform(sqInt numArgs) NoDbgRegParms; static sqInt allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) NoDbgRegParms; static sqInt allocateRegNotConflictingWith(sqInt regMask) NoDbgRegParms; static void annotateBytecodeIfAnnotated(CogSimStackEntry *aSimStackEntry) NoDbgRegParms; @@ -1072,7 +1075,6 @@ static CogMethod * compileCogMethod(sqInt selector) NoDbgRegParms; static sqInt compileEntireMethod(void); static sqInt compileFrameBuild(void); -static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs) NoDbgRegParms; static sqInt cPICMissTrampolineFor(sqInt numArgs) NoDbgRegParms; static sqInt doubleExtendedDoAnythingBytecode(void); static sqInt duplicateTopBytecode(void); @@ -1129,6 +1131,7 @@ static sqInt genPrimitiveNewMethod(void); static sqInt genPrimitiveNewWithArg(void); static sqInt genPrimitiveNotIdentical(void); +static sqInt genPrimitivePerform(void); static sqInt genPrimitiveQuo(void); static sqInt genPrimitiveSize(void); static sqInt genPrimitiveStringAt(void); @@ -9892,7 +9895,7 @@ { sqInt classIndex; sqInt i; - usqInt pc; + sqInt pc;
pc = (((((usqInt)cPIC)) + firstCPICCaseOffset) + cPICCaseSize) - (jumpLongConditionalByteSize(backEnd)); for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { @@ -13704,6 +13707,7 @@ { 0, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, + { genPrimitivePerform, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, @@ -13730,7 +13734,6 @@ { 0, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, - { 0, -1, 0 }, { genPrimitiveIdentical, 1, 0 }, { genPrimitiveClass, -1, 0 }, { 0, -1, 0 }, @@ -21106,6 +21109,125 @@ return 0; }
+ +/* Compile the code for an open PIC. Perform a probe of the first-level + method lookup cache followed by a call of ceSendFromInLineCacheMiss: if + the probe fails. */ + + /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ +static void +compileOpenPICnumArgs(sqInt selector, sqInt numArgs) +{ + AbstractInstruction *itsAHit; + AbstractInstruction *jumpBCMethod; + AbstractInstruction *jumpClassMiss; + AbstractInstruction *jumpSelectorMiss; + sqInt offset; + sqInt offset1; + sqInt offset2; + sqInt offset3; + sqInt offset4; + sqInt offset5; + sqInt offset6; + + compilePICAbort(numArgs); + + /* Do first of three probes. See CoInterpreter>>lookupInMethodCacheSel:classTag: */ + + entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, ClassReg, TempReg); + flag("lookupInMethodCacheSel:classTag:"); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, SendNumArgsReg); + annotateobjRef(gXorCwR(selector, ClassReg), selector); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); + /* begin MoveMw:r:R: */ + offset = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset, genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg)); + annotateobjRef(gCmpCwR(selector, TempReg), selector); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset1, genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpNonZero: */ + jumpClassMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin Label */ + itsAHit = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin MoveMw:r:R: */ + offset2 = (((usqInt)(methodCacheAddress()))) + (MethodCacheMethod << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset2, genoperandoperandoperand(MoveMwrR, offset2, ClassReg, SendNumArgsReg)); + genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); + jumpBCMethod = genJumpImmediate(ClassReg); + jmpTarget(jumpBCMethod, picInterpretAbort); + /* begin AddCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(cmNoCheckEntryOffset, genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg)); + /* begin JumpR: */ + genoperand(JumpR, ClassReg); + jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, gLabel())); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + annotateobjRef(gXorCwR(selector, ClassReg), selector); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); + /* begin MoveMw:r:R: */ + offset3 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset3, genoperandoperandoperand(MoveMwrR, offset3, ClassReg, TempReg)); + annotateobjRef(gCmpCwR(selector, TempReg), selector); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset4 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset4, genoperandoperandoperand(MoveMwrR, offset4, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, gLabel()); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + annotateobjRef(gXorCwR(selector, ClassReg), selector); + + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); + /* begin MoveMw:r:R: */ + offset5 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset5, genoperandoperandoperand(MoveMwrR, offset5, ClassReg, TempReg)); + annotateobjRef(gCmpCwR(selector, TempReg), selector); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset6 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset6, genoperandoperandoperand(MoveMwrR, offset6, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, gLabel()); + genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); + + genSmalltalkToCStackSwitch(1); + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), SendNumArgsReg))); + compileCallFornumArgsargargargargresultRegsaveRegs(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, null, 0); +} + /* SimpleStackBasedCogit>>#extendedPushBytecode */ static sqInt extendedPushBytecode(void) @@ -21768,6 +21890,131 @@ return genJumpTo(targetpc); }
+ +/* Compile the code for a probe of the first-level method cache for a perform + primtiive. The selector is assumed to be in Arg0Reg. Defer to + adjustArgumentsForPerform: to + adjust the arguments before the jump to the method. */ + + /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ +static sqInt +genLookupForPerformNumArgs(sqInt numArgs) +{ + AbstractInstruction *itsAHit; + AbstractInstruction *jumpClassMiss; + AbstractInstruction *jumpInterpret; + AbstractInstruction *jumpSelectorMiss; + sqInt offset; + sqInt offset1; + sqInt offset2; + sqInt offset3; + sqInt offset4; + sqInt offset5; + sqInt offset6; + + + /* N.B. Can't assume TempReg already contains the tag because a method can + of course be invoked via the unchecked entry-point, e.g. as does perform:. */ + + genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, ClassReg, 0); + flag("lookupInMethodCacheSel:classTag:"); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, SendNumArgsReg); + /* begin XorR:R: */ + genoperandoperand(XorRR, Arg0Reg, ClassReg); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); + /* begin MoveMw:r:R: */ + offset = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset, genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, Arg0Reg, TempReg); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset1, genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpNonZero: */ + jumpClassMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin Label */ + itsAHit = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin MoveMw:r:R: */ + offset2 = (((usqInt)(methodCacheAddress()))) + (MethodCacheMethod << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset2, genoperandoperandoperand(MoveMwrR, offset2, ClassReg, SendNumArgsReg)); + genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); + + /* Adjust arguments and jump to the method's unchecked entry-point. */ + + jumpInterpret = genJumpImmediate(ClassReg); + /* begin AddCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(cmNoCheckEntryOffset, genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg)); + adjustArgumentsForPerform(numArgs); + /* begin JumpR: */ + genoperand(JumpR, ClassReg); + jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, gLabel())); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + /* begin XorR:R: */ + genoperandoperand(XorRR, Arg0Reg, ClassReg); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); + /* begin MoveMw:r:R: */ + offset3 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset3, genoperandoperandoperand(MoveMwrR, offset3, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, Arg0Reg, TempReg); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset4 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset4, genoperandoperandoperand(MoveMwrR, offset4, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, gLabel()); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + /* begin XorR:R: */ + genoperandoperand(XorRR, Arg0Reg, ClassReg); + + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); + /* begin MoveMw:r:R: */ + offset5 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset5, genoperandoperandoperand(MoveMwrR, offset5, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, Arg0Reg, TempReg); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset6 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset6, genoperandoperandoperand(MoveMwrR, offset6, ClassReg, TempReg)); + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, gLabel())); + return 0; +} + /* SimpleStackBasedCogit>>#genMoveFalseR: */ static AbstractInstruction * genMoveFalseR(sqInt reg) @@ -22771,6 +23018,56 @@ }
+/* e.g. Receiver Receiver + Selector/Arg0 => Arg1 + Arg1 Arg2 + Arg2 sp-> retpc + sp-> retpc */ +/* Generate code to adjust the possibly stacked arguments immediately + before jumping to a method looked up by a perform primitive. */ + + /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ +static void +adjustArgumentsForPerform(sqInt numArgs) +{ + sqInt index; + sqInt offset; + + assert((numRegArgs()) <= 2); + assert(numArgs >= 1); + if (numArgs <= 2) { + if (numArgs == 2) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); + } + return; + } + if ((2 + 1) == numArgs) { + /* begin PopR: */ + genoperand(PopR, Arg1Reg); + + /* begin PopR: */ + genoperand(PopR, Arg0Reg); + + return; + } + for (index = (numArgs - 2); index >= 0; index += -1) { + /* begin MoveMw:r:R: */ + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(index * BytesPerWord, genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg)); + /* begin MoveR:Mw:r: */ + offset = (index + 1) * BytesPerWord; + /* begin gen:operand:quickConstant:operand: */ + checkQuickConstantforInstruction(offset, genoperandoperandoperand(MoveRMwr, TempReg, offset, SPReg)); + } + /* begin PopR: */ + genoperand(PopR, TempReg); + /* begin MoveR:Mw:r: */ + /* begin gen:operand:quickConstant:operand: */ + checkQuickConstantforInstruction(0, genoperandoperandoperand(MoveRMwr, TempReg, 0, SPReg)); +} + + /* If the stack entry is already in a register not conflicting with regMask, answers it, else allocate a new register not conflicting with reg mask @@ -23393,125 +23690,6 @@ initSimStackForFramefulMethod(initialPC); }
- -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. - Override to push the register args when calling ceSendFromInLineCacheMiss: */ - - /* StackToRegisterMappingCogit>>#compileOpenPIC:numArgs: */ -static void -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt offset3; - sqInt offset4; - sqInt offset5; - sqInt offset6; - - compilePICAbort(numArgs); - - /* Do first of three probes. See CoInterpreter>>lookupInMethodCacheSel:classTag: */ - - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, ClassReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, SendNumArgsReg); - annotateobjRef(gXorCwR(selector, ClassReg), selector); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); - /* begin AndCq:R: */ - /* begin gen:quickConstant:operand: */ - checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); - /* begin MoveMw:r:R: */ - offset = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset, genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg)); - annotateobjRef(gCmpCwR(selector, TempReg), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset1 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset1, genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg)); - /* begin CmpR:R: */ - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - /* begin JumpNonZero: */ - jumpClassMiss = genoperand(JumpNonZero, ((sqInt)0)); - /* begin Label */ - itsAHit = genoperandoperand(Label, (labelCounter += 1), bytecodePC); - /* begin MoveMw:r:R: */ - offset2 = (((usqInt)(methodCacheAddress()))) + (MethodCacheMethod << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset2, genoperandoperandoperand(MoveMwrR, offset2, ClassReg, SendNumArgsReg)); - genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); - jumpBCMethod = genJumpImmediate(ClassReg); - jmpTarget(jumpBCMethod, picInterpretAbort); - /* begin AddCq:R: */ - /* begin gen:quickConstant:operand: */ - checkQuickConstantforInstruction(cmNoCheckEntryOffset, genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg)); - /* begin JumpR: */ - genoperand(JumpR, ClassReg); - jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, gLabel())); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - annotateobjRef(gXorCwR(selector, ClassReg), selector); - /* begin LogicalShiftLeftCq:R: */ - genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); - /* begin AndCq:R: */ - /* begin gen:quickConstant:operand: */ - checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); - /* begin MoveMw:r:R: */ - offset3 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset3, genoperandoperandoperand(MoveMwrR, offset3, ClassReg, TempReg)); - annotateobjRef(gCmpCwR(selector, TempReg), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset4 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset4, genoperandoperandoperand(MoveMwrR, offset4, ClassReg, TempReg)); - /* begin CmpR:R: */ - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - /* begin JumpZero: */ - genoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, gLabel()); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); - annotateobjRef(gXorCwR(selector, ClassReg), selector); - - /* begin AndCq:R: */ - /* begin gen:quickConstant:operand: */ - checkQuickConstantforInstruction(MethodCacheMask << (shiftForWord()), genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg)); - /* begin MoveMw:r:R: */ - offset5 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset5, genoperandoperandoperand(MoveMwrR, offset5, ClassReg, TempReg)); - annotateobjRef(gCmpCwR(selector, TempReg), selector); - /* begin JumpNonZero: */ - jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); - /* begin MoveMw:r:R: */ - offset6 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); - /* begin gen:quickConstant:operand:operand: */ - checkQuickConstantforInstruction(offset6, genoperandoperandoperand(MoveMwrR, offset6, ClassReg, TempReg)); - /* begin CmpR:R: */ - genoperandoperand(CmpRR, SendNumArgsReg, TempReg); - /* begin JumpZero: */ - genoperand(JumpZero, ((sqInt)itsAHit)); - jmpTarget(jumpSelectorMiss, gLabel()); - genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); - genSmalltalkToCStackSwitch(1); - addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), SendNumArgsReg))); - compileCallFornumArgsargargargargresultRegsaveRegs(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, null, 0); -} - /* StackToRegisterMappingCogit>>#cPICMissTrampolineFor: */ static sqInt cPICMissTrampolineFor(sqInt numArgs) @@ -25667,6 +25845,28 @@ return genInnerPrimitiveIdenticalorNotIf(0, 1); }
+ +/* Generate an in-line perform primitive. The lookup code requires the + selector to be in Arg0Reg. + adjustArgumentsForPerform: adjusts the arguments once + genLookupForPerformNumArgs: has generated the code for the lookup. */ + + /* StackToRegisterMappingCogit>>#genPrimitivePerform */ +static sqInt +genPrimitivePerform(void) +{ + sqInt offset; + + if (methodOrBlockNumArgs > 2) { + /* begin MoveMw:r:R: */ + offset = (methodOrBlockNumArgs - 1) * BytesPerWord; + /* begin gen:quickConstant:operand:operand: */ + checkQuickConstantforInstruction(offset, genoperandoperandoperand(MoveMwrR, offset, SPReg, Arg0Reg)); + } + genLookupForPerformNumArgs(methodOrBlockNumArgs); + return compileInterpreterPrimitive(functionPointerForCompiledMethodprimitiveIndex(methodObj, primitiveIndex)); +} + /* StackToRegisterMappingCogit>>#genPrimitiveQuo */ static sqInt genPrimitiveQuo(void)
Modified: branches/Cog/nsspursrc/vm/cogitIA32.c =================================================================== --- branches/Cog/nsspursrc/vm/cogitIA32.c 2015-07-14 22:46:03 UTC (rev 3403) +++ branches/Cog/nsspursrc/vm/cogitIA32.c 2015-07-16 15:25:58 UTC (rev 3404) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b + CCodeGenerator VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe from - StackToRegisterMappingCogit VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b + StackToRegisterMappingCogit VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1417 uuid: 5220753e-35a2-46e9-89ad-f7e65d93073b " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.1423 uuid: cf39cfd3-52f5-4f6b-bba6-892ee83000fe " __DATE__ ; char *__cogitBuildInfo = __buildInfo;
@@ -871,6 +871,7 @@ static sqInt compileFallbackToInterpreterPrimitive(void); static void compileGetErrorCode(void); static sqInt compileInterpreterPrimitive(void (*primitiveRoutine)(void)) NoDbgRegParms; +static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs) NoDbgRegParms; static sqInt extendedPushBytecode(void); static sqInt extendedStoreAndPopBytecode(void); static sqInt extendedStoreBytecode(void); @@ -908,6 +909,7 @@ static sqInt genLongStoreTemporaryVariableBytecode(void); static sqInt genLongUnconditionalBackwardJump(void); static sqInt genLongUnconditionalForwardJump(void); +static sqInt genLookupForPerformNumArgs(sqInt numArgs) NoDbgRegParms; static AbstractInstruction * genMoveFalseR(sqInt reg) NoDbgRegParms; static AbstractInstruction * genMoveTrueR(sqInt reg) NoDbgRegParms; static sqInt genMustBeBooleanTrampolineForcalled(sqInt boolean, char *trampolineName) NoDbgRegParms; @@ -978,6 +980,7 @@ static sqInt v4LongBranchDistance(BytecodeDescriptor *descriptor, sqInt pc, sqInt nExts, sqInt aMethodObj) NoDbgRegParms; extern void voidCogCompiledCode(void); static BlockStart * addBlockStartAtnumArgsnumCopiedspan(sqInt bytecodepc, sqInt numArgs, sqInt numCopied, sqInt span) NoDbgRegParms; +static void adjustArgumentsForPerform(sqInt numArgs) NoDbgRegParms; static sqInt allocateRegForStackEntryAtnotConflictingWith(sqInt index, sqInt regMask) NoDbgRegParms; static sqInt allocateRegNotConflictingWith(sqInt regMask) NoDbgRegParms; static void annotateBytecodeIfAnnotated(CogSimStackEntry *aSimStackEntry) NoDbgRegParms; @@ -991,7 +994,6 @@ static CogMethod * compileCogMethod(sqInt selector) NoDbgRegParms; static sqInt compileEntireMethod(void); static sqInt compileFrameBuild(void); -static void compileOpenPICnumArgs(sqInt selector, sqInt numArgs) NoDbgRegParms; static sqInt cPICMissTrampolineFor(sqInt numArgs) NoDbgRegParms; static sqInt doubleExtendedDoAnythingBytecode(void); static sqInt duplicateTopBytecode(void); @@ -1048,6 +1050,7 @@ static sqInt genPrimitiveNewMethod(void); static sqInt genPrimitiveNewWithArg(void); static sqInt genPrimitiveNotIdentical(void); +static sqInt genPrimitivePerform(void); static sqInt genPrimitiveQuo(void); static sqInt genPrimitiveSize(void); static sqInt genPrimitiveStringAt(void); @@ -9990,12 +9993,12 @@ generateMapAtstart(sqInt addressOrNull, sqInt startAddress) { unsigned char annotation; - sqInt delta; + usqInt delta; sqInt i; AbstractInstruction *instruction; sqInt length; - sqInt location; - sqInt mapEntry; + usqInt location; + usqInt mapEntry; sqInt maxDelta; usqInt mcpc;
@@ -12843,6 +12846,7 @@ { 0, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, + { genPrimitivePerform, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, @@ -12869,7 +12873,6 @@ { 0, -1, 0 }, { 0, -1, 0 }, { 0, -1, 0 }, - { 0, -1, 0 }, { genPrimitiveIdentical, 1, 0 }, { genPrimitiveClass, -1, 0 }, { 0, -1, 0 }, @@ -20435,6 +20438,164 @@ return 0; }
+ +/* Compile the code for an open PIC. Perform a probe of the first-level + method lookup cache followed by a call of ceSendFromInLineCacheMiss: if + the probe fails. */ + + /* SimpleStackBasedCogit>>#compileOpenPIC:numArgs: */ +static void +compileOpenPICnumArgs(sqInt selector, sqInt numArgs) +{ + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + AbstractInstruction *anInstruction7; + AbstractInstruction *anInstruction8; + AbstractInstruction *anInstruction9; + AbstractInstruction *itsAHit; + AbstractInstruction *jumpBCMethod; + AbstractInstruction *jumpClassMiss; + AbstractInstruction *jumpSelectorMiss; + sqInt literal; + sqInt literal1; + sqInt literal2; + sqInt offset; + sqInt offset1; + sqInt offset2; + sqInt offset3; + sqInt offset4; + sqInt offset5; + sqInt offset6; + + compilePICAbort(numArgs); + + /* Do first of three probes. See CoInterpreter>>lookupInMethodCacheSel:classTag: */ + + entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, ClassReg, TempReg); + flag("lookupInMethodCacheSel:classTag:"); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, SendNumArgsReg); + annotateobjRef(gXorCwR(selector, ClassReg), selector); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + literal = MethodCacheMask << (shiftForWord()); + anInstruction = genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg); + anInstruction; + /* begin MoveMw:r:R: */ + offset = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction1; + annotateobjRef(gCmpCwR(selector, TempReg), selector); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction2 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); + anInstruction2; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpNonZero: */ + jumpClassMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin Label */ + itsAHit = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin MoveMw:r:R: */ + offset2 = (((usqInt)(methodCacheAddress()))) + (MethodCacheMethod << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction3 = genoperandoperandoperand(MoveMwrR, offset2, ClassReg, SendNumArgsReg); + anInstruction3; + genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); + jumpBCMethod = genJumpImmediate(ClassReg); + jmpTarget(jumpBCMethod, picInterpretAbort); + /* begin AddCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction4 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); + anInstruction4; + /* begin JumpR: */ + genoperand(JumpR, ClassReg); + jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, gLabel())); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + annotateobjRef(gXorCwR(selector, ClassReg), selector); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + literal1 = MethodCacheMask << (shiftForWord()); + anInstruction5 = genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg); + anInstruction5; + /* begin MoveMw:r:R: */ + offset3 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset3, ClassReg, TempReg); + anInstruction6; + annotateobjRef(gCmpCwR(selector, TempReg), selector); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset4 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset4, ClassReg, TempReg); + anInstruction7; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, gLabel()); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + annotateobjRef(gXorCwR(selector, ClassReg), selector); + + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + literal2 = MethodCacheMask << (shiftForWord()); + anInstruction8 = genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg); + anInstruction8; + /* begin MoveMw:r:R: */ + offset5 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction9 = genoperandoperandoperand(MoveMwrR, offset5, ClassReg, TempReg); + anInstruction9; + annotateobjRef(gCmpCwR(selector, TempReg), selector); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset6 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction10 = genoperandoperandoperand(MoveMwrR, offset6, ClassReg, TempReg); + anInstruction10; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, gLabel()); + genPushRegisterArgsForNumArgsscratchReg(backEnd, numArgs, SendNumArgsReg); + + genSmalltalkToCStackSwitch(1); + addDependent(methodLabel, annotateAbsolutePCRef(gMoveCwR(((sqInt)methodLabel), SendNumArgsReg))); + compileCallFornumArgsargargargargresultRegsaveRegs(ceSendFromInLineCacheMiss, 1, SendNumArgsReg, null, null, null, null, 0); +} + /* SimpleStackBasedCogit>>#extendedPushBytecode */ static sqInt extendedPushBytecode(void) @@ -21117,6 +21278,164 @@ return genJumpTo(targetpc); }
+ +/* Compile the code for a probe of the first-level method cache for a perform + primtiive. The selector is assumed to be in Arg0Reg. Defer to + adjustArgumentsForPerform: to + adjust the arguments before the jump to the method. */ + + /* SimpleStackBasedCogit>>#genLookupForPerformNumArgs: */ +static sqInt +genLookupForPerformNumArgs(sqInt numArgs) +{ + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction10; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + AbstractInstruction *anInstruction5; + AbstractInstruction *anInstruction6; + AbstractInstruction *anInstruction7; + AbstractInstruction *anInstruction8; + AbstractInstruction *anInstruction9; + AbstractInstruction *itsAHit; + AbstractInstruction *jumpClassMiss; + AbstractInstruction *jumpInterpret; + AbstractInstruction *jumpSelectorMiss; + sqInt offset; + sqInt offset1; + sqInt offset2; + sqInt offset3; + sqInt offset4; + sqInt offset5; + sqInt offset6; + + + /* N.B. Can't assume TempReg already contains the tag because a method can + of course be invoked via the unchecked entry-point, e.g. as does perform:. */ + + genGetInlineCacheClassTagFromintoforEntry(ReceiverResultReg, ClassReg, 0); + flag("lookupInMethodCacheSel:classTag:"); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, ClassReg, SendNumArgsReg); + /* begin XorR:R: */ + genoperandoperand(XorRR, Arg0Reg, ClassReg); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, shiftForWord(), ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction = genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg); + anInstruction; + /* begin MoveMw:r:R: */ + offset = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction4 = genoperandoperandoperand(MoveMwrR, offset, ClassReg, TempReg); + anInstruction4; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, Arg0Reg, TempReg); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset1 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction5 = genoperandoperandoperand(MoveMwrR, offset1, ClassReg, TempReg); + anInstruction5; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpNonZero: */ + jumpClassMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin Label */ + itsAHit = genoperandoperand(Label, (labelCounter += 1), bytecodePC); + /* begin MoveMw:r:R: */ + offset2 = (((usqInt)(methodCacheAddress()))) + (MethodCacheMethod << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction6 = genoperandoperandoperand(MoveMwrR, offset2, ClassReg, SendNumArgsReg); + anInstruction6; + genLoadSlotsourceRegdestReg(HeaderIndex, SendNumArgsReg, ClassReg); + + /* Adjust arguments and jump to the method's unchecked entry-point. */ + + jumpInterpret = genJumpImmediate(ClassReg); + /* begin AddCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperand(AddCqR, cmNoCheckEntryOffset, ClassReg); + anInstruction1; + adjustArgumentsForPerform(numArgs); + /* begin JumpR: */ + genoperand(JumpR, ClassReg); + jmpTarget(jumpSelectorMiss, jmpTarget(jumpClassMiss, gLabel())); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + /* begin XorR:R: */ + genoperandoperand(XorRR, Arg0Reg, ClassReg); + /* begin LogicalShiftLeftCq:R: */ + genoperandoperand(LogicalShiftLeftCqR, (shiftForWord()) - 1, ClassReg); + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction2 = genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg); + anInstruction2; + /* begin MoveMw:r:R: */ + offset3 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction7 = genoperandoperandoperand(MoveMwrR, offset3, ClassReg, TempReg); + anInstruction7; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, Arg0Reg, TempReg); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset4 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction8 = genoperandoperandoperand(MoveMwrR, offset4, ClassReg, TempReg); + anInstruction8; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, gLabel()); + /* begin MoveR:R: */ + genoperandoperand(MoveRR, SendNumArgsReg, ClassReg); + /* begin XorR:R: */ + genoperandoperand(XorRR, Arg0Reg, ClassReg); + + /* begin AndCq:R: */ + /* begin gen:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction3 = genoperandoperand(AndCqR, MethodCacheMask << (shiftForWord()), ClassReg); + anInstruction3; + /* begin MoveMw:r:R: */ + offset5 = (((usqInt)(methodCacheAddress()))) + (MethodCacheSelector << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction9 = genoperandoperandoperand(MoveMwrR, offset5, ClassReg, TempReg); + anInstruction9; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, Arg0Reg, TempReg); + /* begin JumpNonZero: */ + jumpSelectorMiss = genoperand(JumpNonZero, ((sqInt)0)); + /* begin MoveMw:r:R: */ + offset6 = (((usqInt)(methodCacheAddress()))) + (MethodCacheClass << (shiftForWord())); + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction10 = genoperandoperandoperand(MoveMwrR, offset6, ClassReg, TempReg); + anInstruction10; + /* begin CmpR:R: */ + genoperandoperand(CmpRR, SendNumArgsReg, TempReg); + /* begin JumpZero: */ + genoperand(JumpZero, ((sqInt)itsAHit)); + jmpTarget(jumpSelectorMiss, jmpTarget(jumpInterpret, gLabel())); + return 0; +} + /* SimpleStackBasedCogit>>#genMoveFalseR: */ static AbstractInstruction * genMoveFalseR(sqInt reg) @@ -22200,6 +22519,75 @@ }
+/* e.g. Receiver Receiver + Selector/Arg0 => Arg1 + Arg1 Arg2 + Arg2 sp-> retpc + sp-> retpc */ +/* Generate code to adjust the possibly stacked arguments immediately + before jumping to a method looked up by a perform primitive. */ + + /* StackToRegisterMappingCogit>>#adjustArgumentsForPerform: */ +static void +adjustArgumentsForPerform(sqInt numArgs) +{ + AbstractInstruction *anInstruction; + AbstractInstruction *anInstruction1; + AbstractInstruction *anInstruction2; + AbstractInstruction *anInstruction3; + AbstractInstruction *anInstruction4; + sqInt index; + + assert((numRegArgs()) <= 2); + assert(numArgs >= 1); + if (numArgs <= 2) { + if (numArgs == 2) { + /* begin MoveR:R: */ + genoperandoperand(MoveRR, Arg1Reg, Arg0Reg); + } + return; + } + if ((2 + 1) == numArgs) { + /* begin PopR: */ + genoperand(PopR, TempReg); + /* begin PopR: */ + genoperand(PopR, Arg1Reg); + + /* begin MoveMw:r:R: */ + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction = genoperandoperandoperand(MoveMwrR, 0, SPReg, Arg0Reg); + anInstruction; + /* begin MoveR:Mw:r: */ + /* begin gen:operand:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction1 = genoperandoperandoperand(MoveRMwr, TempReg, 0, SPReg); + anInstruction1; + + return; + } + for (index = (numArgs - 1); index >= 0; index += -1) { + /* begin MoveMw:r:R: */ + /* begin gen:quickConstant:operand:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction2 = genoperandoperandoperand(MoveMwrR, index * BytesPerWord, SPReg, TempReg); + anInstruction2; + /* begin MoveR:Mw:r: */ + /* begin gen:operand:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction3 = genoperandoperandoperand(MoveRMwr, TempReg, (index + 1) * BytesPerWord, SPReg); + anInstruction3; + } + /* begin PopR: */ + genoperand(PopR, TempReg); + /* begin MoveR:Mw:r: */ + /* begin gen:operand:quickConstant:operand: */ + /* begin checkQuickConstant:forInstruction: */ + anInstruction4 = genoperandoperandoperand(MoveRMwr, TempReg, 0, SPReg); + anInstruction4; +} + + /* If the stack entry is already in a register not conflicting with regMask, answers it, else allocate a new register not conflicting with reg mask @@ -22837,158 +23225,6 @@ initSimStackForFramefulMethod(initialPC); }
- -/* Compile the code for an open PIC. Perform a probe of the first-level - method lookup cache followed by a call of ceSendFromInLineCacheMiss: if - the probe fails. - Override to push the register args when calling ceSendFromInLineCacheMiss: */ - - /* StackToRegisterMappingCogit>>#compileOpenPIC:numArgs: */ -static void -compileOpenPICnumArgs(sqInt selector, sqInt numArgs) -{ - AbstractInstruction *anInstruction; - AbstractInstruction *anInstruction1; - AbstractInstruction *anInstruction10; - AbstractInstruction *anInstruction2; - AbstractInstruction *anInstruction3; - AbstractInstruction *anInstruction4; - AbstractInstruction *anInstruction5; - AbstractInstruction *anInstruction6; - AbstractInstruction *anInstruction7; - AbstractInstruction *anInstruction8; - AbstractInstruction *anInstruction9; - AbstractInstruction *itsAHit; - AbstractInstruction *jumpBCMethod; - AbstractInstruction *jumpClassMiss; - AbstractInstruction *jumpSelectorMiss; - sqInt offset; - sqInt offset1; - sqInt offset2; - sqInt offset3; - sqInt offset4; - sqInt offset5; - sqInt offset6; - - compilePICAbort(numArgs); - - /* Do first of three probes. See CoInterpreter>>lookupInMethodCacheSel:classTag: */ - - entry = genGetClassTagOfintoscratchReg(ReceiverResultReg, ClassReg, TempReg); - flag("lookupInMethodCacheSel:classTag:"); - /* begin MoveR:R: */ - genoperandoperand(MoveRR, ClassReg, SendNumArgsReg);
@@ Diff output truncated at 50000 characters. @@
vm-dev@lists.squeakfoundation.org