Author: eliot Date: 2012-06-21 14:26:01 -0700 (Thu, 21 Jun 2012) New Revision: 2559
Modified: branches/Cog/nscogsrc/vm/cointerp.c branches/Cog/nscogsrc/vm/cointerp.h branches/Cog/nscogsrc/vm/gcc3x-cointerp.c branches/Cog/nscogsrc/vm/interp.h branches/Cog/nscogsrc/vm/vmCallback.h branches/Cog/platforms/Cross/vm/sqSCCSVersion.h branches/Cog/platforms/Mac OS/vm/sqMacMain.c branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c branches/Cog/platforms/unix/vm/sqUnixMain.c branches/Cog/platforms/win32/vm/sqWin32Intel.c branches/Cog/platforms/win32/vm/sqWin32Window.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/src/vm/interp.h branches/Cog/src/vm/vmCallback.h Log: CogVM source as per VMMaker.oscog-eem.163. Make wakeHighestPriority filter-out zombie processes; fixes Newspeak/Glue crash. Add -blockonerror flag to Unix & Mac VMs to allow attaching gdb on error/segv. Make the sigsegv handler catch SIGILL and SIGBUS on Unix and Mac. Move ioExit[WithErrorCode] from sqWin32Window.c to sqWin32Intel.c.
Modified: branches/Cog/nscogsrc/vm/cointerp.c =================================================================== --- branches/Cog/nscogsrc/vm/cointerp.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/nscogsrc/vm/cointerp.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 from - CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -575,7 +575,7 @@ static sqInt iframeSavedIP(char *theFP); void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP); static sqInt imageSegmentVersion(void); -sqInt implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector); +sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector); static sqInt incCompBody(void); static sqInt incCompMakeFwd(void); static sqInt incCompMove(sqInt bytesFreed); @@ -1916,7 +1916,7 @@ /* 575 */ (void (*)(void))0, 0 }; static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.161"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.163"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */; volatile int sendTrace;
@@ -17973,7 +17973,7 @@ implementing: selector <Symbol> ^<Object> */
sqInt -implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector) +implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt aClass; sqInt ccIndex; @@ -18013,9 +18013,9 @@ /* messageSelector is an implicit parameter of lookupMethodInDictionary: */
GIV(messageSelector) = selector; - mixinApplication = findApplicationOfTargetMixinstartingAtBehavior(mixin, fetchClassOf(receiver)); + mixinApplication = findApplicationOfTargetMixinstartingAtBehavior(mixin, fetchClassOf(rcvr)); if (mixinApplication == GIV(nilObj)) { - return receiver; + return rcvr; } dictionary = longAt((mixinApplication + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)); /* begin lookupMethodInDictionary: */ @@ -18155,7 +18155,7 @@ return implicitReceiverOrNil; } } - return receiver; + return rcvr; }
@@ -22670,6 +22670,7 @@ numStack = (((usqInt) ((theFP + FoxMFReceiver) - theSP)) >> ShiftForWord) + numArgs; } else { + /* begin setIFrameHasContext: */ byteAtput((theFP + FoxIFrameFlags) + 2, 1); numArgs = byteAt((theFP + FoxIFrameFlags) + 1); byteSize = (((headerOf(methodFieldOrObj)) & LargeContextBit) != 0 @@ -22682,6 +22683,7 @@ numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs; } theContext = eeInstantiateMethodContextByteSize(byteSize); + /* begin setFrameContext:to: */ longAtput(theFP + FoxThisContext, theContext); /* begin storePointerUnchecked:ofObject:withValue: */ /* begin withSmallIntegerTags: */ @@ -43305,19 +43307,22 @@ object1 = GIV(instructionPointer); longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1); GIV(stackPointer) = sp2; + + /* update state of active process */ + activeContext = voidVMStateForSnapshot(); + activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); + /* begin storePointer:ofObject:withValue: */ + if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { + possibleRootStoreIntovalue(activeProc, activeContext); + } + longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); /* begin pushRemappableOop: */ assert(addressCouldBeOop(activeContext)); GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext; if (!(GIV(remapBufferCount) <= RemapBufferSize)) { error("remapBuffer overflow"); } - activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); - /* begin storePointer:ofObject:withValue: */ - if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { - possibleRootStoreIntovalue(activeProc, activeContext); - } - longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); incrementalGC(); fullGC(); /* begin snapshotCleanUp */ @@ -46124,12 +46129,26 @@ static sqInt wakeHighestPriority(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt ctxt; sqInt header; sqInt p; + sqInt proc; sqInt processList; sqInt schedLists; sqInt sz;
+ /* begin externalWriteBackHeadFramePointers */ + assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize); + assert(GIV(stackPage) == (mostRecentlyUsedPage())); + /* begin setHeadFP:andSP:inPage: */ + assert(GIV(stackPointer) < GIV(framePointer)); + assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize))); + assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1))))); + (GIV(stackPage)->headFP = GIV(framePointer)); + (GIV(stackPage)->headSP = GIV(stackPointer)); + assert(pageListIsWellFormed()); schedLists = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ProcessListsIndex << ShiftForWord)); p = (GIV(highestRunnableProcessPriority) == 0 ? (/* begin fetchWordLengthOf: */ @@ -46140,19 +46159,24 @@ : header & SizeMask)), ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord) : GIV(highestRunnableProcessPriority)); + while (((p -= 1)) >= 0) { + processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); + while (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) {
- /* index of last indexable field */ + /* Only answer processes with a runnable suspendedContext. + Discard those that aren't; the VM would crash otherwise. */
- p -= 1; - while (1) { - processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); - if (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) break; - if (((p -= 1)) < 0) { - error("scheduler could not find a runnable process"); + proc = removeFirstLinkOfList(processList); + ctxt = longAt((proc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)); + if (isLiveContext(ctxt)) { + GIV(highestRunnableProcessPriority) = p + 1; + return proc; + } + warning("evicted zombie process from run queue"); } } - GIV(highestRunnableProcessPriority) = p + 1; - return removeFirstLinkOfList(processList); + error("scheduler could not find a runnable process"); + return null; }
static sqInt
Modified: branches/Cog/nscogsrc/vm/cointerp.h =================================================================== --- branches/Cog/nscogsrc/vm/cointerp.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/nscogsrc/vm/cointerp.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
@@ -83,7 +83,7 @@ sqInt * getStackPointer(void); sqInt headerOf(sqInt methodPointer); void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP); -sqInt implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector); +sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector); sqInt instanceSizeOf(sqInt classObj); sqInt instantiateClassindexableSize(sqInt classPointer, sqInt size); usqInt instructionPointerAddress(void);
Modified: branches/Cog/nscogsrc/vm/gcc3x-cointerp.c =================================================================== --- branches/Cog/nscogsrc/vm/gcc3x-cointerp.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/nscogsrc/vm/gcc3x-cointerp.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -2,11 +2,11 @@
/* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 from - CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -578,7 +578,7 @@ static sqInt iframeSavedIP(char *theFP); void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP); static sqInt imageSegmentVersion(void); -sqInt implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector); +sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector); static sqInt incCompBody(void); static sqInt incCompMakeFwd(void); static sqInt incCompMove(sqInt bytesFreed); @@ -1919,7 +1919,7 @@ /* 575 */ (void (*)(void))0, 0 }; static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); -const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.161"; +const char *interpreterVersion = "Newspeak Virtual Machine CoInterpreter_VMMaker.oscog-eem.163"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */; volatile int sendTrace;
@@ -17977,7 +17977,7 @@ implementing: selector <Symbol> ^<Object> */
sqInt -implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector) +implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector) { DECL_MAYBE_SQ_GLOBAL_STRUCT sqInt aClass; sqInt ccIndex; @@ -18017,9 +18017,9 @@ /* messageSelector is an implicit parameter of lookupMethodInDictionary: */
GIV(messageSelector) = selector; - mixinApplication = findApplicationOfTargetMixinstartingAtBehavior(mixin, fetchClassOf(receiver)); + mixinApplication = findApplicationOfTargetMixinstartingAtBehavior(mixin, fetchClassOf(rcvr)); if (mixinApplication == GIV(nilObj)) { - return receiver; + return rcvr; } dictionary = longAt((mixinApplication + BaseHeaderSize) + (MethodDictionaryIndex << ShiftForWord)); /* begin lookupMethodInDictionary: */ @@ -18159,7 +18159,7 @@ return implicitReceiverOrNil; } } - return receiver; + return rcvr; }
@@ -22674,6 +22674,7 @@ numStack = (((usqInt) ((theFP + FoxMFReceiver) - theSP)) >> ShiftForWord) + numArgs; } else { + /* begin setIFrameHasContext: */ byteAtput((theFP + FoxIFrameFlags) + 2, 1); numArgs = byteAt((theFP + FoxIFrameFlags) + 1); byteSize = (((headerOf(methodFieldOrObj)) & LargeContextBit) != 0 @@ -22686,6 +22687,7 @@ numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs; } theContext = eeInstantiateMethodContextByteSize(byteSize); + /* begin setFrameContext:to: */ longAtput(theFP + FoxThisContext, theContext); /* begin storePointerUnchecked:ofObject:withValue: */ /* begin withSmallIntegerTags: */ @@ -43309,19 +43311,22 @@ object1 = GIV(instructionPointer); longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1); GIV(stackPointer) = sp2; + + /* update state of active process */ + activeContext = voidVMStateForSnapshot(); + activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); + /* begin storePointer:ofObject:withValue: */ + if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { + possibleRootStoreIntovalue(activeProc, activeContext); + } + longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); /* begin pushRemappableOop: */ assert(addressCouldBeOop(activeContext)); GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext; if (!(GIV(remapBufferCount) <= RemapBufferSize)) { error("remapBuffer overflow"); } - activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); - /* begin storePointer:ofObject:withValue: */ - if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { - possibleRootStoreIntovalue(activeProc, activeContext); - } - longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); incrementalGC(); fullGC(); /* begin snapshotCleanUp */ @@ -46128,12 +46133,26 @@ static sqInt wakeHighestPriority(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt ctxt; sqInt header; sqInt p; + sqInt proc; sqInt processList; sqInt schedLists; sqInt sz;
+ /* begin externalWriteBackHeadFramePointers */ + assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize); + assert(GIV(stackPage) == (mostRecentlyUsedPage())); + /* begin setHeadFP:andSP:inPage: */ + assert(GIV(stackPointer) < GIV(framePointer)); + assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize))); + assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1))))); + (GIV(stackPage)->headFP = GIV(framePointer)); + (GIV(stackPage)->headSP = GIV(stackPointer)); + assert(pageListIsWellFormed()); schedLists = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ProcessListsIndex << ShiftForWord)); p = (GIV(highestRunnableProcessPriority) == 0 ? (/* begin fetchWordLengthOf: */ @@ -46144,19 +46163,24 @@ : header & SizeMask)), ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord) : GIV(highestRunnableProcessPriority)); + while (((p -= 1)) >= 0) { + processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); + while (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) {
- /* index of last indexable field */ + /* Only answer processes with a runnable suspendedContext. + Discard those that aren't; the VM would crash otherwise. */
- p -= 1; - while (1) { - processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); - if (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) break; - if (((p -= 1)) < 0) { - error("scheduler could not find a runnable process"); + proc = removeFirstLinkOfList(processList); + ctxt = longAt((proc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)); + if (isLiveContext(ctxt)) { + GIV(highestRunnableProcessPriority) = p + 1; + return proc; + } + warning("evicted zombie process from run queue"); } } - GIV(highestRunnableProcessPriority) = p + 1; - return removeFirstLinkOfList(processList); + error("scheduler could not find a runnable process"); + return null; }
static sqInt
Modified: branches/Cog/nscogsrc/vm/interp.h =================================================================== --- branches/Cog/nscogsrc/vm/interp.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/nscogsrc/vm/interp.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
#define VM_PROXY_MAJOR 1
Modified: branches/Cog/nscogsrc/vm/vmCallback.h =================================================================== --- branches/Cog/nscogsrc/vm/vmCallback.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/nscogsrc/vm/vmCallback.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
#define VM_CALLBACK_INC 1
Property changes on: branches/Cog/platforms/Cross/vm/sqSCCSVersion.h ___________________________________________________________________ Modified: checkindate - Wed Jun 13 14:35:36 PDT 2012 + Thu Jun 21 14:21:32 PDT 2012
Modified: branches/Cog/platforms/Mac OS/vm/sqMacMain.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacMain.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/platforms/Mac OS/vm/sqMacMain.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -241,6 +241,19 @@ fflush(stdout); }
+int blockOnError = 0; /* to allow attaching gdb on fatal error */ + +static void +block() +{ struct timespec while_away_the_hours; + + printf("blocking e.g. to allow attaching debugger\n"); + while (1) { + while_away_the_hours.tv_sec = 3600; + nanosleep(&while_away_the_hours, 0); + } +} + /* Print an error message, possibly a stack trace, and exit. */ /* Disable Intel compiler inlining of error which is used for breakpoints */ #pragma auto_inline off @@ -248,6 +261,7 @@ error(char *msg) { reportStackState(msg,0,0,0); + if (blockOnError) block(); abort(); } #pragma auto_inline on @@ -286,19 +300,32 @@ errno = saved_errno; }
+static int inFault = 0; + static void sigsegv(int sig, siginfo_t *info, void *uap) { time_t now = time(NULL); char ctimebuf[32]; char crashdump[IMAGE_NAME_SIZE+1]; + char *fault = sig == SIGSEGV + ? "Segmentation fault" + : (sig == SIGBUS + ? "Bus error" + : (sig == SIGILL + ? "Illegal instruction" + : "Unknown signal"));
- getCrashDumpFilenameInto(crashdump); - ctime_r(&now,ctimebuf); - pushOutputFile(crashdump); - reportStackState("Segmentation fault", ctimebuf, 0, uap); - popOutputFile(); - reportStackState("Segmentation fault", ctimebuf, 0, uap); + if (!inFault) { + inFault = 1; + getCrashDumpFilenameInto(crashdump); + ctime_r(&now,ctimebuf); + pushOutputFile(crashdump); + reportStackState(fault, ctimebuf, 0, uap); + popOutputFile(); + reportStackState(fault, ctimebuf, 0, uap); + } + if (blockOnError) block(); abort(); }
@@ -369,6 +396,8 @@ sigsegv_handler_action.sa_sigaction = sigsegv; sigsegv_handler_action.sa_flags = SA_NODEFER | SA_SIGINFO; sigemptyset(&sigsegv_handler_action.sa_mask); + (void)sigaction(SIGBUS, &sigsegv_handler_action, 0); + (void)sigaction(SIGILL, &sigsegv_handler_action, 0); (void)sigaction(SIGSEGV, &sigsegv_handler_action, 0);
sigusr1_handler_action.sa_sigaction = sigusr1;
Modified: branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c =================================================================== --- branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/platforms/Mac OS/vm/sqMacUnixCommandLineInterface.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -160,6 +160,10 @@ else if (!strncmp(argv[0], "-psn_", 5)) { return 1; } else if (!strcmp(argv[0], "-headless")) { gSqueakHeadless = true; return 1; } else if (!strcmp(argv[0], "-headfull")) { gSqueakHeadless = false; return 1; } + else if (!strcmp(argv[0], "-blockonerror")) { + extern int blockOnError; + blockOnError = true; + return 1; } #if (STACKVM || NewspeakVM) && !COGVM else if (!strcmp(argv[0], "-sendtrace")) { extern sqInt sendTrace; sendTrace = 1; return 1; } #endif @@ -275,17 +279,28 @@ printf(" -eden <size>[mk] set eden memory to bytes\n"); printf(" -leakcheck num check for leaks in the heap\n"); printf(" -stackpages num use n stack pages\n"); + printf(" -sendtrace[=num] enable send tracing (optionally to a specific value)\n"); + printf(" -numextsems num make the external semaphore table num in size\n"); + printf(" -noheartbeat disable the heartbeat for VM debugging. disables input\n"); + printf(" -pollpip output . on each poll for input\n"); #endif #if COGVM printf(" -codesize <size>[mk] set machine code memory to bytes\n"); - printf(" -sendtrace[=num] enable send tracing (optionally to a specific value)\n"); printf(" -tracestores enable store tracing (assert check stores)\n"); - printf(" -cogmaxlits <n> set max number of literals for methods compiled to machine code\n"); + printf(" -cogmaxlits <n> set max number of literals for methods to be compiled to machine code\n"); printf(" -cogminjumps <n> set min number of backward jumps for interpreted methods to be considered for compilation to machine code\n"); #endif - printf(" -pathenc <enc> set encoding for pathnames (default: macintosh)\n"); +#if STACKVM || NewspeakVM + printf(" -breaksel selector call warning when sending or jitting selector\n"); +#endif + printf(" -pathenc <enc> set encoding for pathnames (default: %s)\n", + getEncodingType(gCurrentVMEncoding)); + printf(" -headless run in headless (no window) mode (default: false)\n"); + printf(" -headfull run in headful (window) mode (default: true)\n"); printf(" -version print version information, then exit\n"); + + printf(" -blockonerror on error or segv block, not exit. useful for attaching gdb\n"); }
static void printUsageNotes(void)
Modified: branches/Cog/platforms/unix/vm/sqUnixMain.c =================================================================== --- branches/Cog/platforms/unix/vm/sqUnixMain.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/platforms/unix/vm/sqUnixMain.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -852,6 +852,19 @@ fflush(stdout); }
+int blockOnError = 0; /* to allow attaching gdb on fatal error */ + +static void +block() +{ struct timespec while_away_the_hours; + + printf("blocking e.g. to allow attaching debugger\n"); + while (1) { + while_away_the_hours.tv_sec = 3600; + nanosleep(&while_away_the_hours, 0); + } +} + /* Print an error message, possibly a stack trace, and exit. */ /* Disable Intel compiler inlining of error which is used for breakpoints */ #pragma auto_inline off @@ -859,6 +872,7 @@ error(char *msg) { reportStackState(msg,0,0,0); + if (blockOnError) block(); abort(); } #pragma auto_inline on @@ -896,19 +910,31 @@ errno = saved_errno; }
+static int inFault = 0; + static void sigsegv(int sig, siginfo_t *info, void *uap) { time_t now = time(NULL); char ctimebuf[32]; char crashdump[IMAGE_NAME_SIZE+1]; + char *fault = sig == SIGSEGV + ? "Segmentation fault" + : (sig == SIGBUS + ? "Bus error" + : (sig == SIGILL + ? "Illegal instruction" + : "Unknown signal"));
- getCrashDumpFilenameInto(crashdump); - ctime_r(&now,ctimebuf); - pushOutputFile(crashdump); - reportStackState("Segmentation fault", ctimebuf, 0, uap); - popOutputFile(); - reportStackState("Segmentation fault", ctimebuf, 0, uap); + if (!inFault) { + getCrashDumpFilenameInto(crashdump); + ctime_r(&now,ctimebuf); + pushOutputFile(crashdump); + reportStackState(fault, ctimebuf, 0, uap); + popOutputFile(); + reportStackState(fault, ctimebuf, 0, uap); + } + if (blockOnError) block(); abort(); }
@@ -1277,6 +1303,7 @@ else if (!strcmp(argv[0], "-nomixer")) { noSoundMixer = 1; return 1; } else if (!strcmp(argv[0], "-notimer")) { useItimer = 0; return 1; } else if (!strcmp(argv[0], "-nohandlers")) { installHandlers= 0; return 1; } + else if (!strcmp(argv[0], "-blockonerror")) { blockOnError = 1; return 1; } #if !STACKVM && !COGVM else if (!strncmp(argv[0],"-jit", 4)) { useJit = jitArgs(argv[0]+4); return 1; } else if (!strcmp(argv[0], "-nojit")) { useJit = 0; return 1; } @@ -1400,6 +1427,7 @@ #endif printf(" -noevents disable event-driven input support\n"); printf(" -nohandlers disable sigsegv & sigusr1 handlers\n"); + printf(" -pollpip output . on each poll for input\n"); printf(" -pathenc <enc> set encoding for pathnames (default: UTF-8)\n"); printf(" -plugins <path> specify alternative plugin location (see manpage)\n"); printf(" -textenc <enc> set encoding for external text (default: UTF-8)\n"); @@ -1412,6 +1440,7 @@ printf(" -cogmaxlits <n> set max number of literals for methods compiled to machine code\n"); printf(" -cogminjumps <n> set min number of backward jumps for interpreted methods to be considered for compilation to machine code\n"); #endif + printf(" -blockonerror on error or segv block, not exit. useful for attaching gdb\n"); #if 1 printf("Deprecated:\n"); # if !STACKVM @@ -1781,6 +1810,8 @@ sigsegv_handler_action.sa_flags = SA_NODEFER | SA_SIGINFO; sigemptyset(&sigsegv_handler_action.sa_mask); (void)sigaction(SIGSEGV, &sigsegv_handler_action, 0); + (void)sigaction(SIGBUS, &sigsegv_handler_action, 0); + (void)sigaction(SIGILL, &sigsegv_handler_action, 0);
sigusr1_handler_action.sa_sigaction = sigusr1; sigusr1_handler_action.sa_flags = SA_NODEFER | SA_SIGINFO;
Modified: branches/Cog/platforms/win32/vm/sqWin32Intel.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Intel.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/platforms/win32/vm/sqWin32Intel.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -786,6 +786,11 @@ return info; }
+/* Calling exit(ec) apparently does NOT provide the correct exit code for the + * terminating process (MinGW bug?). So instead call the shutdown sequence via + * _cexit() and then terminate explicitly. + */ +#define exit(ec) do { _cexit(ec); ExitProcess(ec); } while (0)
static void versionInfo(void) @@ -1003,6 +1008,19 @@ /* dumpStackIfInMainThread(0); */ exit(-1); } + +static int inCleanExit = 0; /* to suppress stack trace in Cleanup */ + +int ioExit(void) { return ioExitWithErrorCode(0); } + +sqInt +ioExitWithErrorCode(int ec) +{ + inCleanExit = 1; + exit(ec); + return ec; +} + #pragma auto_inline on
static void @@ -1126,9 +1144,7 @@ void __cdecl Cleanup(void) { /* not all of these are essential, but they're polite... */
-extern int inCleanExit; /* from platforms/win32/vm/sqWin32Window.c */ - - if(!inCleanExit) { + if (!inCleanExit) { dumpStackIfInMainThread(0); } ioShutdownAllModules();
Modified: branches/Cog/platforms/win32/vm/sqWin32Window.c =================================================================== --- branches/Cog/platforms/win32/vm/sqWin32Window.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/platforms/win32/vm/sqWin32Window.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -1506,24 +1506,6 @@ /****************************************************************************/ /* Misc support primitves */ /****************************************************************************/ -int inCleanExit = 0; - -int ioExit(void) { return ioExitWithErrorCode(0); } - -sqInt -ioExitWithErrorCode(int ec) -{ - inCleanExit = 1; - /* Calling exit(ec) apparently does NOT provide the correct - exit code for the terminating process. So instead call - the shutdown sequence via _cexit() and then terminate - explicitly. */ - _cexit(ec); - ExitProcess(ec); - /* avoid the warnings here */ - return ec; -} - int ioBeep(void) { MessageBeep(0);
Modified: branches/Cog/src/vm/cointerp.c =================================================================== --- branches/Cog/src/vm/cointerp.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/cointerp.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 from - CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -1906,7 +1906,7 @@ /* 575 */ (void (*)(void))0, 0 }; static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); -const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.161]"; +const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.163]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */; volatile int sendTrace;
@@ -21994,6 +21994,7 @@ numStack = (((usqInt) ((theFP + FoxMFReceiver) - theSP)) >> ShiftForWord) + numArgs; } else { + /* begin setIFrameHasContext: */ byteAtput((theFP + FoxIFrameFlags) + 2, 1); numArgs = byteAt((theFP + FoxIFrameFlags) + 1); byteSize = (((headerOf(methodFieldOrObj)) & LargeContextBit) != 0 @@ -22006,6 +22007,7 @@ numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs; } theContext = eeInstantiateMethodContextByteSize(byteSize); + /* begin setFrameContext:to: */ longAtput(theFP + FoxThisContext, theContext); /* begin storePointerUnchecked:ofObject:withValue: */ /* begin withSmallIntegerTags: */ @@ -42616,19 +42618,22 @@ object1 = GIV(instructionPointer); longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1); GIV(stackPointer) = sp2; + + /* update state of active process */ + activeContext = voidVMStateForSnapshot(); + activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); + /* begin storePointer:ofObject:withValue: */ + if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { + possibleRootStoreIntovalue(activeProc, activeContext); + } + longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); /* begin pushRemappableOop: */ assert(addressCouldBeOop(activeContext)); GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext; if (!(GIV(remapBufferCount) <= RemapBufferSize)) { error("remapBuffer overflow"); } - activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); - /* begin storePointer:ofObject:withValue: */ - if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { - possibleRootStoreIntovalue(activeProc, activeContext); - } - longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); incrementalGC(); fullGC(); /* begin snapshotCleanUp */ @@ -45435,12 +45440,26 @@ static sqInt wakeHighestPriority(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt ctxt; sqInt header; sqInt p; + sqInt proc; sqInt processList; sqInt schedLists; sqInt sz;
+ /* begin externalWriteBackHeadFramePointers */ + assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize); + assert(GIV(stackPage) == (mostRecentlyUsedPage())); + /* begin setHeadFP:andSP:inPage: */ + assert(GIV(stackPointer) < GIV(framePointer)); + assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize))); + assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1))))); + (GIV(stackPage)->headFP = GIV(framePointer)); + (GIV(stackPage)->headSP = GIV(stackPointer)); + assert(pageListIsWellFormed()); schedLists = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ProcessListsIndex << ShiftForWord)); p = (GIV(highestRunnableProcessPriority) == 0 ? (/* begin fetchWordLengthOf: */ @@ -45451,19 +45470,24 @@ : header & SizeMask)), ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord) : GIV(highestRunnableProcessPriority)); + while (((p -= 1)) >= 0) { + processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); + while (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) {
- /* index of last indexable field */ + /* Only answer processes with a runnable suspendedContext. + Discard those that aren't; the VM would crash otherwise. */
- p -= 1; - while (1) { - processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); - if (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) break; - if (((p -= 1)) < 0) { - error("scheduler could not find a runnable process"); + proc = removeFirstLinkOfList(processList); + ctxt = longAt((proc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)); + if (isLiveContext(ctxt)) { + GIV(highestRunnableProcessPriority) = p + 1; + return proc; + } + warning("evicted zombie process from run queue"); } } - GIV(highestRunnableProcessPriority) = p + 1; - return removeFirstLinkOfList(processList); + error("scheduler could not find a runnable process"); + return null; }
static sqInt
Modified: branches/Cog/src/vm/cointerp.h =================================================================== --- branches/Cog/src/vm/cointerp.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/cointerp.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
@@ -83,7 +83,7 @@ sqInt * getStackPointer(void); sqInt headerOf(sqInt methodPointer); void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP); -sqInt implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector); +sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector); sqInt instanceSizeOf(sqInt classObj); sqInt instantiateClassindexableSize(sqInt classPointer, sqInt size); usqInt instructionPointerAddress(void);
Modified: branches/Cog/src/vm/cointerpmt.c =================================================================== --- branches/Cog/src/vm/cointerpmt.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/cointerpmt.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,9 +1,9 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 from - CoInterpreterMT VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CoInterpreterMT VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */ -static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc " __DATE__ ; +static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -2005,7 +2005,7 @@ /* 575 */ (void (*)(void))0, 0 }; static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); -const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.161]"; +const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.163]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */; volatile int sendTrace; sqInt willNotThreadWarnCount; @@ -22754,6 +22754,7 @@ numStack = (((usqInt) ((theFP + FoxMFReceiver) - theSP)) >> ShiftForWord) + numArgs; } else { + /* begin setIFrameHasContext: */ byteAtput((theFP + FoxIFrameFlags) + 2, 1); numArgs = byteAt((theFP + FoxIFrameFlags) + 1); byteSize = (((headerOf(methodFieldOrObj)) & LargeContextBit) != 0 @@ -22766,6 +22767,7 @@ numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs; } theContext = eeInstantiateMethodContextByteSize(byteSize); + /* begin setFrameContext:to: */ longAtput(theFP + FoxThisContext, theContext); /* begin storePointerUnchecked:ofObject:withValue: */ /* begin withSmallIntegerTags: */ @@ -44043,19 +44045,22 @@ object1 = GIV(instructionPointer); longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1); GIV(stackPointer) = sp2; + + /* update state of active process */ + activeContext = voidVMStateForSnapshot(); + activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); + /* begin storePointer:ofObject:withValue: */ + if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { + possibleRootStoreIntovalue(activeProc, activeContext); + } + longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); /* begin pushRemappableOop: */ assert(addressCouldBeOop(activeContext)); GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext; if (!(GIV(remapBufferCount) <= RemapBufferSize)) { error("remapBuffer overflow"); } - activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); - /* begin storePointer:ofObject:withValue: */ - if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { - possibleRootStoreIntovalue(activeProc, activeContext); - } - longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); incrementalGC(); fullGC(); /* begin snapshotCleanUp */ @@ -47187,8 +47192,6 @@ runnable process the VM maintains a variable holding the highest priority runnable process. If this variable is 0 then the VM does not know the highest priority and must search all lists. - Note: It is a fatal VM error if there is no runnable process, but - the test can't be done here. Override to answer nil when there is no runnable process instead of aborting. In the threaded VM the abort test is done in transferTo:from: @@ -47199,8 +47202,10 @@ static sqInt wakeHighestPriority(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt ctxt; sqInt header; sqInt p; + sqInt proc; sqInt processList; sqInt schedLists; sqInt sz; @@ -47215,19 +47220,23 @@ : header & SizeMask)), ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord) : GIV(highestRunnableProcessPriority)); + while (((p -= 1)) >= 0) { + processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); + while (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) {
- /* index of last indexable field */ + /* Only answer processes with a runnable suspendedContext. + Discard those that aren't; the VM would crash otherwise. */
- p -= 1; - while (1) { - processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); - if (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) break; - if (((p -= 1)) < 0) { - return null; + proc = removeFirstLinkOfList(processList); + ctxt = longAt((proc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)); + if (isLiveContext(ctxt)) { + GIV(highestRunnableProcessPriority) = p + 1; + return proc; + } + warning("evicted zombie process from run queue"); } } - GIV(highestRunnableProcessPriority) = p + 1; - return removeFirstLinkOfList(processList); + return null; }
Modified: branches/Cog/src/vm/cointerpmt.h =================================================================== --- branches/Cog/src/vm/cointerpmt.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/cointerpmt.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
@@ -85,7 +85,7 @@ sqOSThread getVMOSThread(void); sqInt headerOf(sqInt methodPointer); void ifValidWriteBackStackPointersSaveTo(void *theCFP, void *theCSP, char **savedFPP, char **savedSPP); -sqInt implicitReceiverFormixinimplementing(sqInt receiver, sqInt mixin, sqInt selector); +sqInt implicitReceiverFormixinimplementing(sqInt rcvr, sqInt mixin, sqInt selector); sqInt instanceSizeOf(sqInt classObj); sqInt instantiateClassindexableSize(sqInt classPointer, sqInt size); usqInt instructionPointerAddress(void);
Modified: branches/Cog/src/vm/gcc3x-cointerp.c =================================================================== --- branches/Cog/src/vm/gcc3x-cointerp.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/gcc3x-cointerp.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -2,11 +2,11 @@
/* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 from - CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */ -static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc " __DATE__ ; +static char __buildInfo[] = "CoInterpreter VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -1909,7 +1909,7 @@ /* 575 */ (void (*)(void))0, 0 }; static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); -const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.161]"; +const char *interpreterVersion = "Croquet Closure Cog VM [CoInterpreter VMMaker.oscog-eem.163]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */; volatile int sendTrace;
@@ -21998,6 +21998,7 @@ numStack = (((usqInt) ((theFP + FoxMFReceiver) - theSP)) >> ShiftForWord) + numArgs; } else { + /* begin setIFrameHasContext: */ byteAtput((theFP + FoxIFrameFlags) + 2, 1); numArgs = byteAt((theFP + FoxIFrameFlags) + 1); byteSize = (((headerOf(methodFieldOrObj)) & LargeContextBit) != 0 @@ -22010,6 +22011,7 @@ numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs; } theContext = eeInstantiateMethodContextByteSize(byteSize); + /* begin setFrameContext:to: */ longAtput(theFP + FoxThisContext, theContext); /* begin storePointerUnchecked:ofObject:withValue: */ /* begin withSmallIntegerTags: */ @@ -42620,19 +42622,22 @@ object1 = GIV(instructionPointer); longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1); GIV(stackPointer) = sp2; + + /* update state of active process */ + activeContext = voidVMStateForSnapshot(); + activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); + /* begin storePointer:ofObject:withValue: */ + if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { + possibleRootStoreIntovalue(activeProc, activeContext); + } + longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); /* begin pushRemappableOop: */ assert(addressCouldBeOop(activeContext)); GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext; if (!(GIV(remapBufferCount) <= RemapBufferSize)) { error("remapBuffer overflow"); } - activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); - /* begin storePointer:ofObject:withValue: */ - if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { - possibleRootStoreIntovalue(activeProc, activeContext); - } - longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); incrementalGC(); fullGC(); /* begin snapshotCleanUp */ @@ -45439,12 +45444,26 @@ static sqInt wakeHighestPriority(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt ctxt; sqInt header; sqInt p; + sqInt proc; sqInt processList; sqInt schedLists; sqInt sz;
+ /* begin externalWriteBackHeadFramePointers */ + assert((GIV(framePointer) - GIV(stackPointer)) < LargeContextSize); + assert(GIV(stackPage) == (mostRecentlyUsedPage())); + /* begin setHeadFP:andSP:inPage: */ + assert(GIV(stackPointer) < GIV(framePointer)); + assert((GIV(stackPointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(stackPointer) > (((GIV(stackPage)->realStackLimit)) - LargeContextSize))); + assert((GIV(framePointer) < ((GIV(stackPage)->baseAddress))) + && (GIV(framePointer) > (((GIV(stackPage)->realStackLimit)) - (((sqInt) LargeContextSize >> 1))))); + (GIV(stackPage)->headFP = GIV(framePointer)); + (GIV(stackPage)->headSP = GIV(stackPointer)); + assert(pageListIsWellFormed()); schedLists = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ProcessListsIndex << ShiftForWord)); p = (GIV(highestRunnableProcessPriority) == 0 ? (/* begin fetchWordLengthOf: */ @@ -45455,19 +45474,24 @@ : header & SizeMask)), ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord) : GIV(highestRunnableProcessPriority)); + while (((p -= 1)) >= 0) { + processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); + while (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) {
- /* index of last indexable field */ + /* Only answer processes with a runnable suspendedContext. + Discard those that aren't; the VM would crash otherwise. */
- p -= 1; - while (1) { - processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); - if (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) break; - if (((p -= 1)) < 0) { - error("scheduler could not find a runnable process"); + proc = removeFirstLinkOfList(processList); + ctxt = longAt((proc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)); + if (isLiveContext(ctxt)) { + GIV(highestRunnableProcessPriority) = p + 1; + return proc; + } + warning("evicted zombie process from run queue"); } } - GIV(highestRunnableProcessPriority) = p + 1; - return removeFirstLinkOfList(processList); + error("scheduler could not find a runnable process"); + return null; }
static sqInt
Modified: branches/Cog/src/vm/gcc3x-cointerpmt.c =================================================================== --- branches/Cog/src/vm/gcc3x-cointerpmt.c 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/gcc3x-cointerpmt.c 2012-06-21 21:26:01 UTC (rev 2559) @@ -2,11 +2,11 @@
/* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 from - CoInterpreterMT VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc + CoInterpreterMT VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */ -static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.161 uuid: d9d960b4-9f66-43a2-9d90-4fb58d541adc " __DATE__ ; +static char __buildInfo[] = "CoInterpreterMT VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 " __DATE__ ; char *__interpBuildInfo = __buildInfo;
@@ -2008,7 +2008,7 @@ /* 575 */ (void (*)(void))0, 0 }; static void (*externalPrimitiveTable[MaxExternalPrimitiveTableSize + 1 /* 4097 */])(void); -const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.161]"; +const char *interpreterVersion = "Croquet Closure Cog MT VM [CoInterpreterMT VMMaker.oscog-eem.163]"; sqInt minBackwardJumpCountForCompile = MinBackwardJumpCountForCompile /* 10 */; volatile int sendTrace; sqInt willNotThreadWarnCount; @@ -22758,6 +22758,7 @@ numStack = (((usqInt) ((theFP + FoxMFReceiver) - theSP)) >> ShiftForWord) + numArgs; } else { + /* begin setIFrameHasContext: */ byteAtput((theFP + FoxIFrameFlags) + 2, 1); numArgs = byteAt((theFP + FoxIFrameFlags) + 1); byteSize = (((headerOf(methodFieldOrObj)) & LargeContextBit) != 0 @@ -22770,6 +22771,7 @@ numStack = (((usqInt) ((theFP + FoxIFReceiver) - theSP)) >> ShiftForWord) + numArgs; } theContext = eeInstantiateMethodContextByteSize(byteSize); + /* begin setFrameContext:to: */ longAtput(theFP + FoxThisContext, theContext); /* begin storePointerUnchecked:ofObject:withValue: */ /* begin withSmallIntegerTags: */ @@ -44047,19 +44049,22 @@ object1 = GIV(instructionPointer); longAtput((sp2 = GIV(stackPointer) - BytesPerWord), object1); GIV(stackPointer) = sp2; + + /* update state of active process */ + activeContext = voidVMStateForSnapshot(); + activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); + /* begin storePointer:ofObject:withValue: */ + if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { + possibleRootStoreIntovalue(activeProc, activeContext); + } + longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); /* begin pushRemappableOop: */ assert(addressCouldBeOop(activeContext)); GIV(remapBuffer)[(GIV(remapBufferCount) += 1)] = activeContext; if (!(GIV(remapBufferCount) <= RemapBufferSize)) { error("remapBuffer overflow"); } - activeProc = longAt(((longAt(((longAt((GIV(specialObjectsOop) + BaseHeaderSize) + (SchedulerAssociation << ShiftForWord))) + BaseHeaderSize) + (ValueIndex << ShiftForWord))) + BaseHeaderSize) + (ActiveProcessIndex << ShiftForWord)); - /* begin storePointer:ofObject:withValue: */ - if ((((usqInt) activeProc)) < (((usqInt) GIV(youngStart)))) { - possibleRootStoreIntovalue(activeProc, activeContext); - } - longAtput((activeProc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord), activeContext); incrementalGC(); fullGC(); /* begin snapshotCleanUp */ @@ -47191,8 +47196,6 @@ runnable process the VM maintains a variable holding the highest priority runnable process. If this variable is 0 then the VM does not know the highest priority and must search all lists. - Note: It is a fatal VM error if there is no runnable process, but - the test can't be done here. Override to answer nil when there is no runnable process instead of aborting. In the threaded VM the abort test is done in transferTo:from: @@ -47203,8 +47206,10 @@ static sqInt wakeHighestPriority(void) { DECL_MAYBE_SQ_GLOBAL_STRUCT + sqInt ctxt; sqInt header; sqInt p; + sqInt proc; sqInt processList; sqInt schedLists; sqInt sz; @@ -47219,19 +47224,23 @@ : header & SizeMask)), ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord) : GIV(highestRunnableProcessPriority)); + while (((p -= 1)) >= 0) { + processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); + while (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) {
- /* index of last indexable field */ + /* Only answer processes with a runnable suspendedContext. + Discard those that aren't; the VM would crash otherwise. */
- p -= 1; - while (1) { - processList = longAt((schedLists + BaseHeaderSize) + (p << ShiftForWord)); - if (!((longAt((processList + BaseHeaderSize) + (FirstLinkIndex << ShiftForWord))) == GIV(nilObj))) break; - if (((p -= 1)) < 0) { - return null; + proc = removeFirstLinkOfList(processList); + ctxt = longAt((proc + BaseHeaderSize) + (SuspendedContextIndex << ShiftForWord)); + if (isLiveContext(ctxt)) { + GIV(highestRunnableProcessPriority) = p + 1; + return proc; + } + warning("evicted zombie process from run queue"); } } - GIV(highestRunnableProcessPriority) = p + 1; - return removeFirstLinkOfList(processList); + return null; }
Modified: branches/Cog/src/vm/interp.h =================================================================== --- branches/Cog/src/vm/interp.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/interp.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
#define VM_PROXY_MAJOR 1
Modified: branches/Cog/src/vm/vmCallback.h =================================================================== --- branches/Cog/src/vm/vmCallback.h 2012-06-13 21:36:38 UTC (rev 2558) +++ branches/Cog/src/vm/vmCallback.h 2012-06-21 21:26:01 UTC (rev 2559) @@ -1,5 +1,5 @@ /* Automatically generated by - CCodeGeneratorGlobalStructure VMMaker.oscog-eem.159 uuid: cbf7f95a-6fe2-4578-898e-47afb8524be4 + CCodeGeneratorGlobalStructure VMMaker.oscog-eem.163 uuid: 886d6e40-a3f6-4483-bdfc-f71a846f0737 */
#define VM_CALLBACK_INC 1
vm-dev@lists.squeakfoundation.org