Revision: 3084 Author: eliot Date: 2014-09-25 16:12:18 -0700 (Thu, 25 Sep 2014) Log Message: ----------- CogVM source as per VMMaker.oscog-eem.885
Fix regression in V# become youngReferrers management in VMMaker.oscog-eem.882. We /must/ prune young referrers if mapObjectReferencesInMachineCodeForBecome removes a cog method from youngReferrers because it may get added back and youngReferrers cannot contain duplicates.
Fix potential bug in Spur become argument validation. Check for immediates needs to come /after/ following forwarders since an object can become-forward to an immediate.
Fix cPICHasForwardedClass:; this did /not/ enumerate the classIndices in a Spur Closed PIC.
Modified Paths: -------------- branches/Cog/nscogsrc/vm/cogit.c branches/Cog/nscogsrc/vm/cogit.h branches/Cog/nscogsrc/vm/cointerp.c branches/Cog/nscogsrc/vm/cointerp.h branches/Cog/nscogsrc/vm/gcc3x-cointerp.c branches/Cog/nsspursrc/vm/cogit.c branches/Cog/nsspursrc/vm/cogit.h branches/Cog/nsspursrc/vm/cointerp.c branches/Cog/nsspursrc/vm/cointerp.h branches/Cog/nsspursrc/vm/gcc3x-cointerp.c branches/Cog/nsspurstacksrc/vm/gcc3x-interp.c branches/Cog/nsspurstacksrc/vm/interp.c branches/Cog/scripts/revertIfEssentiallyUnchanged branches/Cog/sistasrc/vm/cogit.c branches/Cog/sistasrc/vm/cogit.h branches/Cog/sistasrc/vm/cointerp.c branches/Cog/sistasrc/vm/cointerp.h branches/Cog/sistasrc/vm/gcc3x-cointerp.c branches/Cog/spursistasrc/vm/cogit.c branches/Cog/spursistasrc/vm/cogit.h branches/Cog/spursistasrc/vm/cointerp.c branches/Cog/spursistasrc/vm/cointerp.h branches/Cog/spursistasrc/vm/gcc3x-cointerp.c branches/Cog/spursrc/vm/cogit.c branches/Cog/spursrc/vm/cogit.h branches/Cog/spursrc/vm/cointerp.c branches/Cog/spursrc/vm/cointerp.h branches/Cog/spursrc/vm/gcc3x-cointerp.c branches/Cog/spurstacksrc/vm/gcc3x-interp.c branches/Cog/spurstacksrc/vm/interp.c branches/Cog/src/vm/cogit.c branches/Cog/src/vm/cogit.h branches/Cog/src/vm/cointerp.c branches/Cog/src/vm/cointerp.h branches/Cog/src/vm/cointerpmt.c branches/Cog/src/vm/cointerpmt.h branches/Cog/src/vm/gcc3x-cointerp.c branches/Cog/src/vm/gcc3x-cointerpmt.c branches/Cog/stacksrc/vm/gcc3x-interp.c branches/Cog/stacksrc/vm/interp.c
Property Changed: ---------------- branches/Cog/platforms/Cross/vm/sqSCCSVersion.h
Modified: branches/Cog/nscogsrc/vm/cogit.c =================================================================== --- branches/Cog/nscogsrc/vm/cogit.c 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nscogsrc/vm/cogit.c 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a from - StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ; char *__cogitBuildInfo = __buildInfo;
@@ -12553,7 +12553,7 @@ { sqInt *address; sqInt *address1; - usqInt cacheAddress; + sqInt cacheAddress; sqInt cacheTag; sqInt cacheTag1; sqInt cacheTagMarked; @@ -12723,7 +12723,7 @@ static sqInt markYoungObjectspcmethod(sqInt annotation, char *mcpc, sqInt cogMethod) { - usqInt cacheAddress; + sqInt cacheAddress; sqInt cacheTag; sqInt cacheTag1; sqInt class; @@ -13814,7 +13814,7 @@ static sqInt remapIfObjectRefpchasYoung(sqInt annotation, char *mcpc, sqInt hasYoungPtr) { - usqInt cacheAddress; + sqInt cacheAddress; sqInt cacheTag; sqInt cacheTag1; sqInt entryPoint; @@ -14583,7 +14583,7 @@ static void voidImplicitReceiverCacheAt(sqInt mcpc) { - usqInt cacheAddress; + sqInt cacheAddress;
assert(NumOopsPerIRC == 2); cacheAddress = (((usqInt)mcpc)) + (jumpShortByteSize(backEnd));
Modified: branches/Cog/nscogsrc/vm/cogit.h =================================================================== --- branches/Cog/nscogsrc/vm/cogit.h 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nscogsrc/vm/cogit.h 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */
Modified: branches/Cog/nscogsrc/vm/cointerp.c =================================================================== --- branches/Cog/nscogsrc/vm/cointerp.c 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nscogsrc/vm/cointerp.c 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a from - CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -108,6 +108,7 @@ #define AtCacheSize 2 #define AtCacheTotalSize 64 #define AtPutBase 32 +#define BecameActiveClassFlag 8 #define BecameCompiledMethodFlag 2 #define Byte0Mask 0xFF #define Byte1Mask 0xFF00 @@ -852,7 +853,7 @@ void printWronglySizedContexts(sqInt printContexts); static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut) NoDbgRegParms; static void runLeakCheckerForFullGC(sqInt fullGCFlag) NoDbgRegParms; -static usqInt safeObjectAfter(sqInt oop) NoDbgRegParms; +static sqInt safeObjectAfter(sqInt oop) NoDbgRegParms; static sqInt safePrintStringOf(sqInt oop) NoDbgRegParms; static sqInt shortentoIndexableSize(sqInt obj, sqInt nSlots) NoDbgRegParms; static sqInt sizeBitsOfSafe(sqInt oop) NoDbgRegParms; @@ -2085,7 +2086,7 @@ /* 574 */ (void (*)(void))0, /* 575 */ (void (*)(void))0, 0 }; -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; volatile int sendTrace;
@@ -34936,6 +34937,7 @@ sqInt anArray2; sqInt anArray3; sqInt c; + sqInt c1; sqInt contextSize; sqInt fieldOffset; sqInt first; @@ -34956,6 +34958,8 @@ sqInt i; sqInt i1; sqInt i2; + sqInt i3; + sqInt i4; sqInt iLimiT; sqInt iLimiT1; sqInt last; @@ -34981,6 +34985,7 @@ sqInt oop21; sqInt procLists; sqInt s; + sqInt s1; sqInt sched; sqInt schedAssoc; sqInt sp; @@ -36766,15 +36771,17 @@ sqInt header1; sqInt header2; sqInt header3; + sqInt header4; usqInt lastWord; sqInt newFreeChunk; sqInt newOop; - usqInt next; + sqInt next; sqInt oop; sqInt realHeader; sqInt sz; sqInt sz1; sqInt sz2; + sqInt sz3; sqInt target; usqInt w;
@@ -36785,7 +36792,21 @@ /* begin objectAfterWhileForwarding: */ header2 = longAt(oop); if ((header2 & MarkBit) == 0) { - next = ((sqInt) (objectAfter(oop))); + /* begin objectAfter: */ + if (!(asserta(oopisLessThan(oop, GIV(freeStart))))) { + error("no objects after the end of memory"); + } + if (((longAt(oop)) & TypeMask) == HeaderTypeFree) { + sz2 = (longAt(oop)) & AllButTypeMask; + } + else { + /* begin sizeBitsOf: */ + header3 = longAt(oop); + sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass + ? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask + : header3 & SizeMask); + } + next = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]); goto l1; } fwdBlock1 = (header2 & AllButMarkBitAndTypeMask) << 1; @@ -36800,7 +36821,7 @@ else { sz1 = realHeader & SizeMask; } - next = ((sqInt) ((oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]))); + next = (oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]); l1: /* end objectAfterWhileForwarding: */; if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
@@ -36854,18 +36875,18 @@ } /* begin safeObjectAfter: */ if (((longAt(newFreeChunk)) & TypeMask) == HeaderTypeFree) { - sz2 = (longAt(newFreeChunk)) & AllButTypeMask; + sz3 = (longAt(newFreeChunk)) & AllButTypeMask; } else { /* begin sizeBitsOf: */ - header3 = longAt(newFreeChunk); - sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass + header4 = longAt(newFreeChunk); + sz3 = ((header4 & TypeMask) == HeaderTypeSizeAndClass ? (longAt(newFreeChunk - (BytesPerWord * 2))) & LongSizeMask - : header3 & SizeMask); + : header4 & SizeMask); } - next = ((newFreeChunk + sz2) >= GIV(freeStart) + next = ((newFreeChunk + sz3) >= GIV(freeStart) ? GIV(freeStart) - : (newFreeChunk + sz2) + (headerTypeBytes[(longAt(newFreeChunk + sz2)) & TypeMask])); + : (newFreeChunk + sz3) + (headerTypeBytes[(longAt(newFreeChunk + sz3)) & TypeMask])); assert((next == GIV(freeStart)) || (next == (oopFromChunk(GIV(compEnd))))); if (next == GIV(freeStart)) { @@ -38737,7 +38758,7 @@ given object or free chunk in memory. Return freeStart when enumeration is complete. This is for assertion checking only. */
-static usqInt +static sqInt safeObjectAfter(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt header;
Modified: branches/Cog/nscogsrc/vm/cointerp.h =================================================================== --- branches/Cog/nscogsrc/vm/cointerp.h 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nscogsrc/vm/cointerp.h 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */
Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c =================================================================== --- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c 2014-09-25 23:12:18 UTC (rev 3084) @@ -2,11 +2,11 @@
/* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a from - CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -111,6 +111,7 @@ #define AtCacheSize 2 #define AtCacheTotalSize 64 #define AtPutBase 32 +#define BecameActiveClassFlag 8 #define BecameCompiledMethodFlag 2 #define Byte0Mask 0xFF #define Byte1Mask 0xFF00 @@ -855,7 +856,7 @@ void printWronglySizedContexts(sqInt printContexts); static void restoreHeadersFromtofromandtofrom(sqInt firstIn, sqInt lastIn, sqInt hdrBaseIn, sqInt firstOut, sqInt lastOut, sqInt hdrBaseOut) NoDbgRegParms; static void runLeakCheckerForFullGC(sqInt fullGCFlag) NoDbgRegParms; -static usqInt safeObjectAfter(sqInt oop) NoDbgRegParms; +static sqInt safeObjectAfter(sqInt oop) NoDbgRegParms; static sqInt safePrintStringOf(sqInt oop) NoDbgRegParms; static sqInt shortentoIndexableSize(sqInt obj, sqInt nSlots) NoDbgRegParms; static sqInt sizeBitsOfSafe(sqInt oop) NoDbgRegParms; @@ -2088,7 +2089,7 @@ /* 574 */ (void (*)(void))0, /* 575 */ (void (*)(void))0, 0 }; -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; volatile int sendTrace;
@@ -34945,6 +34946,7 @@ sqInt anArray2; sqInt anArray3; sqInt c; + sqInt c1; sqInt contextSize; sqInt fieldOffset; sqInt first; @@ -34965,6 +34967,8 @@ sqInt i; sqInt i1; sqInt i2; + sqInt i3; + sqInt i4; sqInt iLimiT; sqInt iLimiT1; sqInt last; @@ -34990,6 +34994,7 @@ sqInt oop21; sqInt procLists; sqInt s; + sqInt s1; sqInt sched; sqInt schedAssoc; sqInt sp; @@ -36775,15 +36780,17 @@ sqInt header1; sqInt header2; sqInt header3; + sqInt header4; usqInt lastWord; sqInt newFreeChunk; sqInt newOop; - usqInt next; + sqInt next; sqInt oop; sqInt realHeader; sqInt sz; sqInt sz1; sqInt sz2; + sqInt sz3; sqInt target; usqInt w;
@@ -36794,7 +36801,21 @@ /* begin objectAfterWhileForwarding: */ header2 = longAt(oop); if ((header2 & MarkBit) == 0) { - next = ((sqInt) (objectAfter(oop))); + /* begin objectAfter: */ + if (!(asserta(oopisLessThan(oop, GIV(freeStart))))) { + error("no objects after the end of memory"); + } + if (((longAt(oop)) & TypeMask) == HeaderTypeFree) { + sz2 = (longAt(oop)) & AllButTypeMask; + } + else { + /* begin sizeBitsOf: */ + header3 = longAt(oop); + sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass + ? (longAt(oop - (BytesPerWord * 2))) & LongSizeMask + : header3 & SizeMask); + } + next = (oop + sz2) + (headerTypeBytes[(longAt(oop + sz2)) & TypeMask]); goto l1; } fwdBlock1 = (header2 & AllButMarkBitAndTypeMask) << 1; @@ -36809,7 +36830,7 @@ else { sz1 = realHeader & SizeMask; } - next = ((sqInt) ((oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]))); + next = (oop + sz1) + (headerTypeBytes[(longAt(oop + sz1)) & TypeMask]); l1: /* end objectAfterWhileForwarding: */; if (!(((longAt(oop)) & TypeMask) == HeaderTypeFree)) {
@@ -36863,18 +36884,18 @@ } /* begin safeObjectAfter: */ if (((longAt(newFreeChunk)) & TypeMask) == HeaderTypeFree) { - sz2 = (longAt(newFreeChunk)) & AllButTypeMask; + sz3 = (longAt(newFreeChunk)) & AllButTypeMask; } else { /* begin sizeBitsOf: */ - header3 = longAt(newFreeChunk); - sz2 = ((header3 & TypeMask) == HeaderTypeSizeAndClass + header4 = longAt(newFreeChunk); + sz3 = ((header4 & TypeMask) == HeaderTypeSizeAndClass ? (longAt(newFreeChunk - (BytesPerWord * 2))) & LongSizeMask - : header3 & SizeMask); + : header4 & SizeMask); } - next = ((newFreeChunk + sz2) >= GIV(freeStart) + next = ((newFreeChunk + sz3) >= GIV(freeStart) ? GIV(freeStart) - : (newFreeChunk + sz2) + (headerTypeBytes[(longAt(newFreeChunk + sz2)) & TypeMask])); + : (newFreeChunk + sz3) + (headerTypeBytes[(longAt(newFreeChunk + sz3)) & TypeMask])); assert((next == GIV(freeStart)) || (next == (oopFromChunk(GIV(compEnd))))); if (next == GIV(freeStart)) { @@ -38746,7 +38767,7 @@ given object or free chunk in memory. Return freeStart when enumeration is complete. This is for assertion checking only. */
-static usqInt +static sqInt safeObjectAfter(sqInt oop) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt header;
Modified: branches/Cog/nsspursrc/vm/cogit.c =================================================================== --- branches/Cog/nsspursrc/vm/cogit.c 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nsspursrc/vm/cogit.c 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a from - StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */ -static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ; +static char __buildInfo[] = "StackToRegisterMappingCogit VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ; char *__cogitBuildInfo = __buildInfo;
@@ -625,6 +625,7 @@ static void compileTrampolineFornumArgsargargargargsaveRegspushLinkRegresultReg(void *aRoutine, sqInt numArgs, sqInt regOrConst0, sqInt regOrConst1, sqInt regOrConst2, sqInt regOrConst3, sqInt saveRegs, sqInt pushLinkReg, sqInt resultRegOrNil) NoDbgRegParms; static void computeEntryOffsets(void); static void computeMaximumSizes(void); +static sqInt cPICHasForwardedClass(CogMethod *cPIC) NoDbgRegParms; static sqInt cPICHasFreedTargets(CogMethod *cPIC) NoDbgRegParms; static sqInt cPICHasTarget(CogMethod *cPIC, CogMethod *targetMethod) NoDbgRegParms; static AbstractInstruction * gDivRRQuoRem(sqInt rDivisor, sqInt rDividend, sqInt rQuotient, sqInt rRemainder) NoDbgRegParms; @@ -777,11 +778,13 @@ static sqInt unimplementedPrimitive(void); static sqInt unknownBytecode(void); void unlinkAllSends(void); +static sqInt unlinkIfForwardedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) NoDbgRegParms; static sqInt unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector) NoDbgRegParms; static sqInt unlinkIfLinkedSendToFreepcignored(sqInt annotation, char *mcpc, sqInt superfluity) NoDbgRegParms; static sqInt unlinkIfLinkedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) NoDbgRegParms; static sqInt unlinkIfLinkedSendpcto(sqInt annotation, char *mcpc, sqInt theCogMethod) NoDbgRegParms; void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); +void unlinkSendsToForwardedClasses(void); void unlinkSendsToFree(void); void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); static sqInt updateMaybeObjRefAt(sqInt mcpc) NoDbgRegParms; @@ -10141,6 +10144,24 @@ }
static sqInt +cPICHasForwardedClass(CogMethod *cPIC) +{ + sqInt classIndex; + sqInt i; + sqInt pc; + + pc = (((((usqInt)cPIC)) + firstCPICCaseOffset) + cPICCaseSize) - (jumpLongConditionalByteSize(backEnd)); + for (i = 2; i <= ((cPIC->cPICNumCases)); i += 1) { + classIndex = inlineCacheTagAt(backEnd, pc); + if (isForwardedClassIndex(classIndex)) { + return 1; + } + pc += cPICCaseSize; + } + return 0; +} + +static sqInt cPICHasFreedTargets(CogMethod *cPIC) { sqInt entryPoint; @@ -14001,6 +14022,63 @@ }
static sqInt +unlinkIfForwardedSendpcignored(sqInt annotation, char *mcpc, sqInt superfluity) +{ + usqInt cacheAddress; + sqInt entryPoint; + sqInt sendTable; + sqInt *sendTable1; + sqInt targetMethod; + CogMethod *targetMethod1; + sqInt unlinkedRoutine; + + if ((annotation == IsSendCall) + || (annotation == IsNSSendCall)) { + entryPoint = callTargetFromReturnAddress(backEnd, ((sqInt)mcpc)); + if (entryPoint > methodZoneBase) { + + /* It's a linked send, but maybe a super send or linked to an OpenPIC, in which case the cache tag will be a selector.... */ + + if (isForwardedClassIndex(inlineCacheTagAt(backEnd, mcpc))) { + /* begin targetMethodAndSendTableFor:into: */ + if ((entryPoint & entryPointMask) == checkedEntryAlignment) { + targetMethod1 = ((CogMethod *) (entryPoint - cmEntryOffset)); + sendTable1 = sendTrampolines; + } + else { + if ((entryPoint & entryPointMask) == dynSuperEntryAlignment) { + targetMethod1 = ((CogMethod *) (entryPoint - cmDynSuperEntryOffset)); + sendTable1 = dynamicSuperSendTrampolines; + } + else { + targetMethod1 = ((CogMethod *) (entryPoint - cmNoCheckEntryOffset)); + sendTable1 = superSendTrampolines; + } + } + + /* begin unlinkSendAt:targetMethod:sendTable: */ + unlinkedRoutine = sendTable1[((((targetMethod1->cmNumArgs)) < (NumSendTrampolines - 1)) ? ((targetMethod1->cmNumArgs)) : (NumSendTrampolines - 1))]; + rewriteInlineCacheAttagtarget(backEnd, ((sqInt)mcpc), (targetMethod1->selector), unlinkedRoutine); + codeModified = 1; + + } + } + else { + if (entryPoint == ceImplicitReceiverTrampoline) { + assert(NumOopsPerIRC == 2); + cacheAddress = implicitReceiveCacheAt(backEnd, mcpc); + if ((isForwardedClassIndex(unalignedLongAt(backEnd, cacheAddress))) + || (isForwardedClassIndex(unalignedLongAt(backEnd, cacheAddress + BytesPerOop)))) { + voidImplicitReceiverCacheAt(mcpc); + } + } + + } + } + return 0; +} + +static sqInt unlinkIfFreeOrLinkedSendpcof(sqInt annotation, char *mcpc, sqInt theSelector) { sqInt entryPoint; @@ -14295,6 +14373,72 @@ }
+/* Unlink all sends in cog methods whose class tag is that of a forwarded + class. + */ + +void +unlinkSendsToForwardedClasses(void) +{ + CogMethod *cogMethod; + sqInt freedPIC; + sqInt map; + sqInt mapByte; + sqInt mcpc; + sqInt result; + + if (!(methodZoneBase)) { + return; + } + cogMethod = ((CogMethod *) methodZoneBase); + codeModified = (freedPIC = 0); + while (cogMethod < (limitZony())) { + if (((cogMethod->cmType)) == CMMethod) { + /* begin mapFor:performUntil:arg: */ + mcpc = (((sqInt)cogMethod)) + cmNoCheckEntryOffset; + map = ((((usqInt)cogMethod)) + ((cogMethod->blockSize))) - 1; + while (((mapByte = byteAt(map))) != MapEnd) { + if (mapByte >= FirstAnnotation) { + mcpc += mapByte & DisplacementMask; + result = unlinkIfForwardedSendpcignored((((usqInt) mapByte) >> AnnotationShift), (((char *) mcpc)), 0); + if (result != 0) { + result; + goto l1; + } + } + else { + mcpc += (mapByte >= DisplacementX2N + ? (mapByte - DisplacementX2N) << AnnotationShift + : mapByte); + } + map -= 1; + } + 0; + l1: /* end mapFor:performUntil:arg: */; + } + else { + if ((((cogMethod->cmType)) == CMClosedPIC) + && (cPICHasForwardedClass(cogMethod))) { + freeMethod(cogMethod); + freedPIC = 1; + } + } + cogMethod = ((CogMethod *) (roundUpLength((((sqInt)cogMethod)) + ((cogMethod->blockSize))))); + } + if (freedPIC) { + unlinkSendsToFree(); + } + else { + if (codeModified) { + + /* After possibly updating inline caches we need to flush the icache. */ + + flushICacheFromto(processor, methodZoneBase, ((sqInt)(limitZony()))); + } + } +} + + /* Unlink all sends in cog methods to free methods and/or pics. */
void
Modified: branches/Cog/nsspursrc/vm/cogit.h =================================================================== --- branches/Cog/nsspursrc/vm/cogit.h 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nsspursrc/vm/cogit.h 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGenerator VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGenerator VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */
@@ -69,6 +69,7 @@ sqInt traceLinkedSendOffset(void); void unlinkAllSends(void); void unlinkSendsOfisMNUSelector(sqInt selector, sqInt isMNUSelector); +void unlinkSendsToForwardedClasses(void); void unlinkSendsToFree(void); void unlinkSendsToandFreeIf(sqInt targetMethodObject, sqInt freeIfTrue); void addAllToYoungReferrers(void);
Modified: branches/Cog/nsspursrc/vm/cointerp.c =================================================================== --- branches/Cog/nsspursrc/vm/cointerp.c 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nsspursrc/vm/cointerp.c 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a from - CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -134,6 +134,7 @@ #define AtCacheSize 2 #define AtCacheTotalSize 64 #define AtPutBase 32 +#define BecameActiveClassFlag 8 #define BecameCompiledMethodFlag 2 #define BecamePointerObjectFlag 1 #define BitsPerByte 8 @@ -803,6 +804,7 @@ usqInt freeStartAddress(void); usqInt getScavengeThreshold(void); static sqLong headerWhileForwardingOf(sqInt aCompiledMethodObjOop) NoDbgRegParms; +sqInt isForwardedClassIndex(sqInt maybeClassIndex); sqInt isImmediateClass(sqInt classObj); sqInt isReallyYoungObject(sqInt objOop); sqInt methodHeaderOf(sqInt methodObj); @@ -1559,11 +1561,11 @@ _iss sqInt tempOop; _iss sqInt classTableIndex; _iss usqInt lastFreeChunk; +_iss sqInt becomeEffectsFlags; _iss SpurNewSpaceSpace eden; _iss sqInt ephemeronList; _iss usqInt freeOldSpaceStart; _iss sqInt tenureThreshold; -_iss sqInt becomeEffectsFlags; _iss sqInt extraRootCount; _iss sqInt invalidObjStackPage; _iss sqInt previousRememberedSetSize; @@ -2326,7 +2328,7 @@ /*540*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /*560*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1 }; -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; volatile int sendTrace;
@@ -5618,6 +5620,7 @@ GIV(framePointer) = localFP; ceEnterCogCodePopReceiverReg(); + null; goto l293; } localIP = pointerForOop(longAt(localFP + FoxIFSavedIP)); @@ -5635,7 +5638,7 @@ /* begin fetchNextBytecode */ currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
- /* return self */ + null; l293: /* end baseFrameReturn */; goto l292; } @@ -38723,7 +38726,29 @@ return long64At(aCompiledMethodObjOop); }
+ +/* A lenient tester of forwarded class indices for inline cache management in + the Cogit. + */ + sqInt +isForwardedClassIndex(sqInt maybeClassIndex) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt classTablePage; + sqInt entry; + + if ((((usqInt)maybeClassIndex)) >= (1 << (22 - 10))) { + return 0; + } + classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) maybeClassIndex) >> 10) << 2)); + if (classTablePage == GIV(nilObj)) { + return 0; + } + entry = longAt((classTablePage + (BaseHeaderSize)) + ((maybeClassIndex & ((1 << 10) - 1)) << 2)); + return ((longAt(entry)) & (0x3FFFFF - 8)) == 0; +} + +sqInt isImmediateClass(sqInt classObj) { return ((((usqInt) (((longAt((classObj + (BaseHeaderSize)) + (InstanceSpecificationIndex << 2))) >> 1))) >> 16) & 0x1F) == 7; @@ -42136,14 +42161,19 @@
/* Answer the appropriate become effect flags for objOop, or 0 if none. - The effect flags affect how much work is done after the become in - following forwarding pointers. */ + The effect flags determine how much work is done after the become + in following forwarding pointers, voiding method caches, etc. */
static sqInt becomeEffectFlagsFor(sqInt objOop) { + sqInt hash; + return (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) <= 5 - ? BecamePointerObjectFlag + ? ((((hash = (longAt(objOop + 4)) & 0x3FFFFF)) != 0) + && ((classAtIndex(hash)) == objOop) + ? BecamePointerObjectFlag + BecameActiveClassFlag + : BecamePointerObjectFlag) : (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) >= 24 ? BecameCompiledMethodFlag : 0)); @@ -42172,8 +42202,8 @@ becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt c; + sqInt c1; sqInt classOrNil; - sqInt classTablePage; sqInt clone1; sqInt clone2; sqInt contextSize; @@ -42199,6 +42229,8 @@ sqInt i3; sqInt i4; sqInt i5; + sqInt i6; + sqInt i7; sqInt iLimiT; sqInt iLimiT1; sqInt iLimiT2; @@ -42262,13 +42294,13 @@ sqInt referent8; sqInt referent9; sqInt s; + sqInt s1; sqInt sched; sqInt schedAssoc; sqInt sp; sqInt sp1; sqInt temp1; sqInt temp2; - sqInt tmp; sqInt xArray;
assert(GIV(becomeEffectsFlags) == 0); @@ -42333,11 +42365,8 @@ effectsFlags = 0; while (fieldOffset >= (BaseHeaderSize)) { oop = longAt(array1 + fieldOffset); - if ((oop & 3) != 0) { - ec = PrimErrInappropriate; - goto l3; - } - if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) { + if (((oop & 3) == 0) + && (((longAt(oop)) & 0x3FFFFF) == 8)) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(oop)); referent5 = longAt((oop + (BaseHeaderSize)) + (0 << 2)); @@ -42348,17 +42377,18 @@ oop = referent5; longAtput(array1 + fieldOffset, oop); } + if ((oop & 3) != 0) { + ec = PrimErrInappropriate; + goto l3; + } if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) { ec = PrimErrObjectIsPinned; goto l3; } effectsFlags = effectsFlags | (becomeEffectFlagsFor(oop)); oop = longAt(array2 + fieldOffset); - if ((oop & 3) != 0) { - ec = PrimErrInappropriate; - goto l3; - } - if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) { + if (((oop & 3) == 0) + && (((longAt(oop)) & 0x3FFFFF) == 8)) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(oop)); referent11 = longAt((oop + (BaseHeaderSize)) + (0 << 2)); @@ -42369,6 +42399,10 @@ oop = referent11; longAtput(array2 + fieldOffset, oop); } + if ((oop & 3) != 0) { + ec = PrimErrInappropriate; + goto l3; + } if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) { ec = PrimErrObjectIsPinned; goto l3; @@ -42427,11 +42461,8 @@ effectsFlags1 = 0; while (fieldOffset1 >= (BaseHeaderSize)) { oop1 = longAt(array1 + fieldOffset1); - if ((oop1 & 3) != 0) { - ec = PrimErrInappropriate; - goto l6; - } - if (((longAt(oop1)) & (0x3FFFFF - 8)) == 0) { + if (((oop1 & 3) == 0) + && (((longAt(oop1)) & 0x3FFFFF) == 8)) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(oop1)); referent6 = longAt((oop1 + (BaseHeaderSize)) + (0 << 2)); @@ -42442,6 +42473,10 @@ oop1 = referent6; longAtput(array1 + fieldOffset1, oop1); } + if ((oop1 & 3) != 0) { + ec = PrimErrInappropriate; + goto l6; + } if (((((usqInt) (longAt(oop1))) >> 30) & 1) != 0) { ec = PrimErrObjectIsPinned; goto l6; @@ -42498,26 +42533,25 @@ obj2 = objOop3; if (obj1 != obj2) { /* begin doBecome:and:copyHash: */ - if (!copyHashFlag) { - - /* in-lined - classIndex := (self isInClassTable: obj) ifTrue: [self rawHashBitsOf: obj] ifFalse: [0] - for speed. */ - - o1ClassIndex = (longAt(obj1 + 4)) & 0x3FFFFF; - if ((o1ClassIndex != 0) - && ((classAtIndex(o1ClassIndex)) != obj1)) { - o1ClassIndex = 0; - } - o2ClassIndex = (longAt(obj2 + 4)) & 0x3FFFFF; - if ((o2ClassIndex != 0) - && ((classAtIndex(o2ClassIndex)) != obj2)) { - o2ClassIndex = 0; - } + o1ClassIndex = (longAt(obj1 + 4)) & 0x3FFFFF; + if ((o1ClassIndex != 0) + && ((classAtIndex(o1ClassIndex)) != obj1)) { + o1ClassIndex = 0; } - if ((numSlotsOf(obj1)) == (numSlotsOf(obj2))) { + o2ClassIndex = (longAt(obj2 + 4)) & 0x3FFFFF; + if ((o2ClassIndex != 0) + && ((classAtIndex(o2ClassIndex)) != obj2)) { + o2ClassIndex = 0; + } + if (((numSlotsOf(obj1)) == (numSlotsOf(obj2))) + && ((o1ClassIndex == 0) + && (o2ClassIndex == 0))) { /* begin inPlaceBecome:and:copyHashFlag: */ assert((numSlotsOf(obj1)) == (numSlotsOf(obj2))); + assert(((rawHashBitsOf(obj1)) == 0) + || ((classOrNilAtIndex(rawHashBitsOf(obj1))) != obj1)); + assert(((rawHashBitsOf(obj2)) == 0) + || ((classOrNilAtIndex(rawHashBitsOf(obj2))) != obj2)); temp1 = ((((usqInt) (longAt(obj1))) >> 29) & 1) != 0; temp2 = ((((usqInt) (longAt(obj2))) >> 29) & 1) != 0; headerTemp = long64At(obj1); @@ -42545,15 +42579,15 @@ longAtput(obj2 + 4, ((((longAt(obj2 + 4)) | 0x3FFFFF) - 0x3FFFFF)) + temp1); } o1HasYoung = (o2HasYoung = 0); - for (i5 = 0, iLimiT4 = ((numSlotsOf(obj1)) - 1); i5 <= iLimiT4; i5 += 1) { - temp1 = longAt((obj1 + (BaseHeaderSize)) + (i5 << 2)); - temp2 = longAt((obj2 + (BaseHeaderSize)) + (i5 << 2)); + for (i7 = 0, iLimiT4 = ((numSlotsOf(obj1)) - 1); i7 <= iLimiT4; i7 += 1) { + temp1 = longAt((obj1 + (BaseHeaderSize)) + (i7 << 2)); + temp2 = longAt((obj2 + (BaseHeaderSize)) + (i7 << 2)); /* begin storePointerUnchecked:ofObject:withValue: */ assert(!(isForwarded(obj1))); - longAtput((obj1 + (BaseHeaderSize)) + (i5 << 2), temp2); + longAtput((obj1 + (BaseHeaderSize)) + (i7 << 2), temp2); /* begin storePointerUnchecked:ofObject:withValue: */ assert(!(isForwarded(obj2))); - longAtput((obj2 + (BaseHeaderSize)) + (i5 << 2), temp1); + longAtput((obj2 + (BaseHeaderSize)) + (i7 << 2), temp1); if (((temp2 & 3) == 0) && ((((usqInt) temp2)) < (((usqInt) GIV(newSpaceLimit))))) { o1HasYoung = 1; @@ -42585,11 +42619,7 @@ } } } - assert((o1ClassIndex == 0) - || ((rawHashBitsOf(classAtIndex(o1ClassIndex))) == o1ClassIndex)); - assert((o2ClassIndex == 0) - || ((rawHashBitsOf(classAtIndex(o2ClassIndex))) == o2ClassIndex)); - goto l9; + goto l8; } /* begin outOfPlaceBecome:and:copyHashFlag: */ clone1 = (((longAt(obj1)) & 0x3FFFFF) == ClassMethodContextCompactIndex @@ -42677,29 +42707,16 @@ GIV(becomeEffectsFlags) = GIV(becomeEffectsFlags) | OldBecameNewFlag; } if (copyHashFlag) { - goto l9; + goto l8; } if (o1ClassIndex != 0) { if (o2ClassIndex != 0) { - - /* both were in the table; just swap entries */ - - /* begin classAtIndex: */ - assert((o1ClassIndex <= (tagMask())) - || (o1ClassIndex >= (arrayClassIndexPun()))); - classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) o1ClassIndex) >> 10) << 2)); - if (classTablePage == GIV(nilObj)) { - tmp = null; - goto l8; - } - tmp = longAt((classTablePage + (BaseHeaderSize)) + ((o1ClassIndex & ((1 << 10) - 1)) << 2)); - l8: /* end classAtIndex: */; classAtIndexput(o1ClassIndex, obj2); - classAtIndexput(o2ClassIndex, tmp); + classAtIndexput(o2ClassIndex, obj1); } else {
- /* o2 wasn't in the table; put it there */ + /* o2 wasn't in the table; set its hash */
/* begin followForwarded: */ assert(isUnambiguouslyForwarder(obj1)); @@ -42714,11 +42731,13 @@ flag("endianness"); assert(((o1ClassIndex >= 0) && (o1ClassIndex <= (identityHashHalfWordMask())))); longAtput(newObj2 + 4, ((((longAt(newObj2 + 4)) | 0x3FFFFF) - 0x3FFFFF)) + o1ClassIndex); - classAtIndexput(o1ClassIndex, newObj2); } } else { if (o2ClassIndex != 0) { + + /* o1 wasn't in the table; set its hash */ + /* begin followForwarded: */ assert(isUnambiguouslyForwarder(obj2)); referent13 = longAt((obj2 + (BaseHeaderSize)) + (0 << 2)); @@ -42732,10 +42751,9 @@ flag("endianness"); assert(((o2ClassIndex >= 0) && (o2ClassIndex <= (identityHashHalfWordMask())))); longAtput(newObj1 + 4, ((((longAt(newObj1 + 4)) | 0x3FFFFF) - 0x3FFFFF)) + o2ClassIndex); - classAtIndexput(o2ClassIndex, newObj1); } } - l9: /* end doBecome:and:copyHash: */; + l8: /* end doBecome:and:copyHash: */; /* begin followField:ofObject: */ objOop = longAt((array1 + (BaseHeaderSize)) + (i << 2)); if (((objOop & 3) == 0) @@ -42861,63 +42879,15 @@ GIV(specialObjectsOop) = referent; } followForwardedObjectFieldstoDepth(GIV(specialObjectsOop), 0); - /* begin postBecomeScanClassTable: */ - assert(validClassTableRootPages()); - if (!(GIV(becomeEffectsFlags) & BecamePointerObjectFlag)) { - goto l7; - } - for (i4 = 0; i4 < GIV(numClassTablePages); i4 += 1) { - page = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i4 << 2)); - assert(!(isForwarded(page))); - for (j = 0, jLimiT = ((numSlotsOf(page)) - 1); j <= jLimiT; j += 1) { - classOrNil = longAt((page + (BaseHeaderSize)) + (j << 2)); - if (classOrNil != GIV(nilObj)) { - if (((longAt(classOrNil)) & (0x3FFFFF - 8)) == 0) { - /* begin followForwarded: */ - assert(isUnambiguouslyForwarder(classOrNil)); - referent8 = longAt((classOrNil + (BaseHeaderSize)) + (0 << 2)); - while (((referent8 & 3) == 0) - && (((longAt(referent8)) & 0x3FFFFF) == 8)) { - referent8 = longAt((referent8 + (BaseHeaderSize)) + (0 << 2)); - } - classOrNil = referent8; - /* begin storePointer:ofObject:withValue: */ - assert(!(isForwarded(page))); - if (isOldObject(page)) { - - /* most stores into young objects */ - - if (((classOrNil & 3) == 0) - && ((((usqInt) classOrNil)) < (((usqInt) GIV(newSpaceLimit))))) { - /* begin possibleRootStoreInto: */ - if (!(((((usqInt) (longAt(page))) >> 29) & 1) != 0)) { - remember(page); - } - } - } - longAtput((page + (BaseHeaderSize)) + (j << 2), classOrNil); - } - if (((longAt(classOrNil + 4)) & 0x3FFFFF) == 0) { - /* begin storePointerUnchecked:ofObject:withValue: */ - assert(!(isForwarded(page))); - longAtput((page + (BaseHeaderSize)) + (j << 2), GIV(nilObj)); - if (((i4 << 10) + j) < GIV(classTableIndex)) { - GIV(classTableIndex) = (i4 << 10) + j; - } - } - } - } - } -l7: /* end postBecomeScanClassTable: */; /* begin postBecomeAction: */ followForwardingPointersInStackZone(GIV(becomeEffectsFlags)); if (GIV(becomeEffectsFlags) != 0) { if (GIV(becomeEffectsFlags) & BecameCompiledMethodFlag) { /* begin followForwardedMethodsInMethodCache */ - for (i2 = 0; i2 < MethodCacheSize; i2 += MethodCacheEntrySize) { - c = GIV(methodCache)[i2 + MethodCacheClass]; - s = GIV(methodCache)[i2 + MethodCacheSelector]; - m = GIV(methodCache)[i2 + MethodCacheMethod]; + for (i4 = 0; i4 < MethodCacheSize; i4 += MethodCacheEntrySize) { + c = GIV(methodCache)[i4 + MethodCacheClass]; + s = GIV(methodCache)[i4 + MethodCacheSelector]; + m = GIV(methodCache)[i4 + MethodCacheMethod]; if ((c != 0) && ((s != 0) && ((m != 0) @@ -42931,12 +42901,31 @@ referent4 = longAt((referent4 + (BaseHeaderSize)) + (0 << 2)); } m = referent4; - GIV(methodCache)[i2 + MethodCacheMethod] = m; + GIV(methodCache)[i4 + MethodCacheMethod] = m; } } /* begin followForwardedMethodsInMethodZone */ followForwardedMethods(); } + if (GIV(becomeEffectsFlags) & BecameActiveClassFlag) { + /* begin flushBecommedClassesInMethodCache */ + for (i2 = 0; i2 < MethodCacheSize; i2 += MethodCacheEntrySize) { + c1 = GIV(methodCache)[i2 + MethodCacheClass]; + s1 = GIV(methodCache)[i2 + MethodCacheSelector]; + if ((c1 != 0) + && ((s1 != 0) + && (isForwarded(classOrNilAtIndex(c1))))) { + GIV(methodCache)[i2 + MethodCacheClass] = 0; + GIV(methodCache)[i2 + MethodCacheSelector] = 0; + } + } + /* begin flushAtCache */ + for (i11 = 1; i11 <= AtCacheTotalSize; i11 += 1) { + GIV(atCache)[i11] = 0; + } + /* begin flushBecommedClassesInMethodZone */ + unlinkSendsToForwardedClasses(); + } /* begin followForwardingPointersInScheduler */
/* the GC follows pointers in the special objects array for us. */ @@ -42957,12 +42946,12 @@ objOop51 = fixFollowedFieldofObjectwithInitialValue(ProcessListsIndex, sched, objOop51); } procLists = objOop51; - for (i11 = 0, iLimiT2 = ((numSlotsOf(procLists)) - 1); i11 <= iLimiT2; i11 += 1) { + for (i3 = 0, iLimiT2 = ((numSlotsOf(procLists)) - 1); i3 <= iLimiT2; i3 += 1) { /* begin followObjField:ofObject: */ - objOop11 = longAt((procLists + (BaseHeaderSize)) + (i11 << 2)); + objOop11 = longAt((procLists + (BaseHeaderSize)) + (i3 << 2)); assert(isNonImmediate(objOop11)); if (((longAt(objOop11)) & (0x3FFFFF - 8)) == 0) { - objOop11 = fixFollowedFieldofObjectwithInitialValue(i11, procLists, objOop11); + objOop11 = fixFollowedFieldofObjectwithInitialValue(i3, procLists, objOop11); } list = objOop11; /* begin followObjField:ofObject: */ @@ -43126,9 +43115,9 @@ } longAtput((GIV(specialObjectsOop) + (BaseHeaderSize)) + (ExternalObjectsArray << 2), xArray); } - for (i3 = 0, iLimiT3 = ((numSlotsOf(xArray)) - 1); i3 <= iLimiT3; i3 += 1) { + for (i5 = 0, iLimiT3 = ((numSlotsOf(xArray)) - 1); i5 <= iLimiT3; i5 += 1) { /* begin followSemaphoreIn:at: */ - obj = longAt((xArray + (BaseHeaderSize)) + (i3 << 2)); + obj = longAt((xArray + (BaseHeaderSize)) + (i5 << 2)); if (((longAt(obj)) & (0x3FFFFF - 8)) == 0) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(obj)); @@ -43152,7 +43141,7 @@ } } } - longAtput((xArray + (BaseHeaderSize)) + (i3 << 2), obj); + longAtput((xArray + (BaseHeaderSize)) + (i5 << 2), obj); } } /* begin followForwardingPointersInProfileState */ @@ -43194,6 +43183,54 @@ cogitPostGCAction(GIV(gcMode)); GIV(lastCoggableInterpretedBlockMethod) = (GIV(lastUncoggableInterpretedBlockMethod) = null); GIV(gcMode) = 0; + /* begin postBecomeScanClassTable: */ + assert(validClassTableRootPages()); + if (!(GIV(becomeEffectsFlags) & BecamePointerObjectFlag)) { + goto l7; + } + for (i6 = 0; i6 < GIV(numClassTablePages); i6 += 1) { + page = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i6 << 2)); + assert(!(isForwarded(page))); + for (j = 0, jLimiT = ((numSlotsOf(page)) - 1); j <= jLimiT; j += 1) { + classOrNil = longAt((page + (BaseHeaderSize)) + (j << 2)); + if (classOrNil != GIV(nilObj)) { + if (((longAt(classOrNil)) & (0x3FFFFF - 8)) == 0) { + /* begin followForwarded: */ + assert(isUnambiguouslyForwarder(classOrNil)); + referent8 = longAt((classOrNil + (BaseHeaderSize)) + (0 << 2)); + while (((referent8 & 3) == 0) + && (((longAt(referent8)) & 0x3FFFFF) == 8)) { + referent8 = longAt((referent8 + (BaseHeaderSize)) + (0 << 2)); + } + classOrNil = referent8; + /* begin storePointer:ofObject:withValue: */ + assert(!(isForwarded(page))); + if (isOldObject(page)) { + + /* most stores into young objects */ + + if (((classOrNil & 3) == 0) + && ((((usqInt) classOrNil)) < (((usqInt) GIV(newSpaceLimit))))) { + /* begin possibleRootStoreInto: */ + if (!(((((usqInt) (longAt(page))) >> 29) & 1) != 0)) { + remember(page); + } + } + } + longAtput((page + (BaseHeaderSize)) + (j << 2), classOrNil); + } + if (((longAt(classOrNil + 4)) & 0x3FFFFF) == 0) { + /* begin storePointerUnchecked:ofObject:withValue: */ + assert(!(isForwarded(page))); + longAtput((page + (BaseHeaderSize)) + (j << 2), GIV(nilObj)); + if (((i6 << 10) + j) < GIV(classTableIndex)) { + GIV(classTableIndex) = (i6 << 10) + j; + } + } + } + } + } +l7: /* end postBecomeScanClassTable: */; GIV(becomeEffectsFlags) = 0; assert(validClassTableHashes()); if ((checkForLeaks & 4) != 0) { @@ -51174,8 +51211,10 @@ printInvalidClassTableEntries(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt classOrNil; + sqInt classOrNil1; sqInt hash; sqInt i; + sqInt index; sqInt j; sqInt jLimiT; sqInt page; @@ -51186,18 +51225,20 @@ printf("\n"); return; } + /* begin classTableEntriesDo: */ for (i = 0; i < GIV(numClassTablePages); i += 1) { page = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + (i << 2)); for (j = 0, jLimiT = ((1 << 10) - 1); j <= jLimiT; j += 1) { - classOrNil = longAt((page + (BaseHeaderSize)) + (j << 2)); - if (classOrNil != GIV(nilObj)) { - if ((((longAt(classOrNil)) & (0x3FFFFF - 8)) == 0) - || ((((hash = (longAt(classOrNil + 4)) & 0x3FFFFF)) == 0) - || ((noCheckClassAtIndex(hash)) != classOrNil))) { + classOrNil1 = longAt((page + (BaseHeaderSize)) + (j << 2)); + if (classOrNil1 != GIV(nilObj)) { + index = (i << 10) + j; + if ((((longAt(classOrNil1)) & (0x3FFFFF - 8)) == 0) + || ((((hash = (longAt(classOrNil1 + 4)) & 0x3FFFFF)) == 0) + || ((noCheckClassAtIndex(hash)) != classOrNil1))) { print("entry "); - printHex((i * (1 << 10)) + j); + printHex(index); print(" oop "); - printHex(classOrNil); + printHex(classOrNil1); print(" hash "); printHex(hash); print(" => "); @@ -51205,6 +51246,7 @@ /* begin cr */ printf("\n"); } + } } }
Modified: branches/Cog/nsspursrc/vm/cointerp.h =================================================================== --- branches/Cog/nsspursrc/vm/cointerp.h 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nsspursrc/vm/cointerp.h 2014-09-25 23:12:18 UTC (rev 3084) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */
@@ -121,6 +121,7 @@ void ensureNoForwardedLiteralsIn(sqInt aMethodObj); usqInt freeStartAddress(void); usqInt getScavengeThreshold(void); +sqInt isForwardedClassIndex(sqInt maybeClassIndex); sqInt isImmediateClass(sqInt classObj); sqInt isReallyYoungObject(sqInt objOop); sqInt methodHeaderOf(sqInt methodObj);
Modified: branches/Cog/nsspursrc/vm/gcc3x-cointerp.c =================================================================== --- branches/Cog/nsspursrc/vm/gcc3x-cointerp.c 2014-09-25 23:02:22 UTC (rev 3083) +++ branches/Cog/nsspursrc/vm/gcc3x-cointerp.c 2014-09-25 23:12:18 UTC (rev 3084) @@ -2,11 +2,11 @@
/* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a from - CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac + CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.886 uuid: fb69945a-ff92-425c-9f6e-e2d9bba462ac " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.885 uuid: 292f0a8d-0afa-4943-90fd-be53fb40772a " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -137,6 +137,7 @@ #define AtCacheSize 2 #define AtCacheTotalSize 64 #define AtPutBase 32 +#define BecameActiveClassFlag 8 #define BecameCompiledMethodFlag 2 #define BecamePointerObjectFlag 1 #define BitsPerByte 8 @@ -806,6 +807,7 @@ usqInt freeStartAddress(void); usqInt getScavengeThreshold(void); static sqLong headerWhileForwardingOf(sqInt aCompiledMethodObjOop) NoDbgRegParms; +sqInt isForwardedClassIndex(sqInt maybeClassIndex); sqInt isImmediateClass(sqInt classObj); sqInt isReallyYoungObject(sqInt objOop); sqInt methodHeaderOf(sqInt methodObj); @@ -1562,11 +1564,11 @@ _iss sqInt tempOop; _iss sqInt classTableIndex; _iss usqInt lastFreeChunk; +_iss sqInt becomeEffectsFlags; _iss SpurNewSpaceSpace eden; _iss sqInt ephemeronList; _iss usqInt freeOldSpaceStart; _iss sqInt tenureThreshold; -_iss sqInt becomeEffectsFlags; _iss sqInt extraRootCount; _iss sqInt invalidObjStackPage; _iss sqInt previousRememberedSetSize; @@ -2329,7 +2331,7 @@ /*540*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /*560*/ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0,-1,-1 }; -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.886"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreterPrimitives_VMMaker.oscog-eem.885"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 40 */; volatile int sendTrace;
@@ -5627,6 +5629,7 @@ GIV(framePointer) = localFP; ceEnterCogCodePopReceiverReg(); + null; goto l293; } localIP = pointerForOop(longAt(localFP + FoxIFSavedIP)); @@ -5644,7 +5647,7 @@ /* begin fetchNextBytecode */ currentBytecode = (byteAtPointer(++localIP)) + GIV(bytecodeSetSelector);
- /* return self */ + null; l293: /* end baseFrameReturn */; goto l292; } @@ -38732,7 +38735,29 @@ return long64At(aCompiledMethodObjOop); }
+ +/* A lenient tester of forwarded class indices for inline cache management in + the Cogit. + */ + sqInt +isForwardedClassIndex(sqInt maybeClassIndex) +{ DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt classTablePage; + sqInt entry; + + if ((((usqInt)maybeClassIndex)) >= (1 << (22 - 10))) { + return 0; + } + classTablePage = longAt((GIV(hiddenRootsObj) + (BaseHeaderSize)) + ((((usqInt) maybeClassIndex) >> 10) << 2)); + if (classTablePage == GIV(nilObj)) { + return 0; + } + entry = longAt((classTablePage + (BaseHeaderSize)) + ((maybeClassIndex & ((1 << 10) - 1)) << 2)); + return ((longAt(entry)) & (0x3FFFFF - 8)) == 0; +} + +sqInt isImmediateClass(sqInt classObj) { return ((((usqInt) (((longAt((classObj + (BaseHeaderSize)) + (InstanceSpecificationIndex << 2))) >> 1))) >> 16) & 0x1F) == 7; @@ -42145,14 +42170,19 @@
/* Answer the appropriate become effect flags for objOop, or 0 if none. - The effect flags affect how much work is done after the become in - following forwarding pointers. */ + The effect flags determine how much work is done after the become + in following forwarding pointers, voiding method caches, etc. */
static sqInt becomeEffectFlagsFor(sqInt objOop) { + sqInt hash; + return (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) <= 5 - ? BecamePointerObjectFlag + ? ((((hash = (longAt(objOop + 4)) & 0x3FFFFF)) != 0) + && ((classAtIndex(hash)) == objOop) + ? BecamePointerObjectFlag + BecameActiveClassFlag + : BecamePointerObjectFlag) : (((((usqInt) (longAt(objOop))) >> 24) & 0x1F) >= 24 ? BecameCompiledMethodFlag : 0)); @@ -42181,8 +42211,8 @@ becomewithtwoWaycopyHash(sqInt array1, sqInt array2, sqInt twoWayFlag, sqInt copyHashFlag) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt c; + sqInt c1; sqInt classOrNil; - sqInt classTablePage; sqInt clone1; sqInt clone2; sqInt contextSize; @@ -42208,6 +42238,8 @@ sqInt i3; sqInt i4; sqInt i5; + sqInt i6; + sqInt i7; sqInt iLimiT; sqInt iLimiT1; sqInt iLimiT2; @@ -42271,13 +42303,13 @@ sqInt referent8; sqInt referent9; sqInt s; + sqInt s1; sqInt sched; sqInt schedAssoc; sqInt sp; sqInt sp1; sqInt temp1; sqInt temp2; - sqInt tmp; sqInt xArray;
assert(GIV(becomeEffectsFlags) == 0); @@ -42342,11 +42374,8 @@ effectsFlags = 0; while (fieldOffset >= (BaseHeaderSize)) { oop = longAt(array1 + fieldOffset); - if ((oop & 3) != 0) { - ec = PrimErrInappropriate; - goto l3; - } - if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) { + if (((oop & 3) == 0) + && (((longAt(oop)) & 0x3FFFFF) == 8)) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(oop)); referent5 = longAt((oop + (BaseHeaderSize)) + (0 << 2)); @@ -42357,17 +42386,18 @@ oop = referent5; longAtput(array1 + fieldOffset, oop); } + if ((oop & 3) != 0) { + ec = PrimErrInappropriate; + goto l3; + } if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) { ec = PrimErrObjectIsPinned; goto l3; } effectsFlags = effectsFlags | (becomeEffectFlagsFor(oop)); oop = longAt(array2 + fieldOffset); - if ((oop & 3) != 0) { - ec = PrimErrInappropriate; - goto l3; - } - if (((longAt(oop)) & (0x3FFFFF - 8)) == 0) { + if (((oop & 3) == 0) + && (((longAt(oop)) & 0x3FFFFF) == 8)) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(oop)); referent11 = longAt((oop + (BaseHeaderSize)) + (0 << 2)); @@ -42378,6 +42408,10 @@ oop = referent11; longAtput(array2 + fieldOffset, oop); } + if ((oop & 3) != 0) { + ec = PrimErrInappropriate; + goto l3; + } if (((((usqInt) (longAt(oop))) >> 30) & 1) != 0) { ec = PrimErrObjectIsPinned; goto l3; @@ -42436,11 +42470,8 @@ effectsFlags1 = 0; while (fieldOffset1 >= (BaseHeaderSize)) { oop1 = longAt(array1 + fieldOffset1); - if ((oop1 & 3) != 0) { - ec = PrimErrInappropriate; - goto l6; - } - if (((longAt(oop1)) & (0x3FFFFF - 8)) == 0) { + if (((oop1 & 3) == 0) + && (((longAt(oop1)) & 0x3FFFFF) == 8)) { /* begin followForwarded: */ assert(isUnambiguouslyForwarder(oop1)); referent6 = longAt((oop1 + (BaseHeaderSize)) + (0 << 2)); @@ -42451,6 +42482,10 @@ oop1 = referent6; longAtput(array1 + fieldOffset1, oop1); }
@@ Diff output truncated at 50000 characters. @@
vm-dev@lists.squeakfoundation.org