Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.561.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.561 Author: eem Time: 12 December 2013, 2:36:45.762 pm UUID: 13467880-93b9-4137-9bbc-7ebfd22436ab Ancestors: VMMaker.oscog-eem.560 Fix swizzling of Spur objStacks on start-up. Spur now snapshots and resumes. Beef up the objStack asserts and printing to identify my prior malfeasance. Add some interpreter proxy plumbing to SpurMemoryManager. Simplify StackInterpreter>>arrayValueOf: (isWordsOrBytes: already filters-out immediates). Change ensureMultiThreadingOverridesAreUpToDate to the new trunk initPattern:return: from initPattern:notifying:return:. If this bites you just implement initPattern:return: on Parser supplying nil as the thing to notify. =============== Diff against VMMaker.oscog-eem.560 =============== Item was changed: ----- Method: CogVMSimulator>>ensureMultiThreadingOverridesAreUpToDate (in category 'initialization') ----- ensureMultiThreadingOverridesAreUpToDate "Make sure the CoInterpreterMT switch methods are implemented. These methods select between CoInterpreterMT's implementation or CoInterpreter's implementation depending on cogThreadManager being non-nil or nil respectively. i.e. they allow us to use this one simulator class to simulate for both CoInterpreterMT and CoInterpreter." | thisClass me mtInterpreterClass | thisClass := thisContext methodClass. mtInterpreterClass := thisClass superclass. me := thisClass name, '>>', thisContext method selector. "We want override switches for everything implemented by CoInterpreter and CoInterpreterMT that is either not implemented by CogVMSimulator or already implemented by CogVMSimulator as an override switch." (mtInterpreterClass selectors select: [:sel| (mtInterpreterClass superclass whichClassIncludesSelector: sel) notNil and: [(thisClass organization categoryOfElement: sel) ifNil: [true] ifNotNil: [:cat| cat == #'multi-threading simulation switch']]]) do: [:sel| | argNames desiredSource | argNames := Parser new initPattern: (mtInterpreterClass sourceCodeAt: sel) - notifying: nil return: [:pattern| pattern second]. desiredSource := String streamContents: [:str| argNames isEmpty ifTrue: [str nextPutAll: sel] ifFalse: [sel keywords with: argNames do: [:kw :arg| str nextPutAll: kw; space; nextPutAll: arg; space]. str skip: -1]. str crtab; nextPutAll: '"This method includes or excludes ', mtInterpreterClass name, ' methods as required.'; crtab; nextPutAll: ' Auto-generated by ', me, '"'; cr; crtab; nextPutAll: '^self perform: '; store: sel; crtab: 2; nextPutAll: 'withArguments: {'. argNames do: [:arg| str nextPutAll: arg] separatedBy: [str nextPut: $.; space]. str nextPut: $}; crtab: 2; nextPutAll: 'inSuperclass: (cogThreadManager ifNil: ['; print: mtInterpreterClass superclass; nextPutAll: '] ifNotNil: ['; print: mtInterpreterClass; nextPutAll: '])']. desiredSource ~= (thisClass sourceCodeAt: sel ifAbsent: ['']) asString ifTrue: [((thisClass includesSelector: sel) and: [(thisClass compiledMethodAt: sel) messages includesAnyOf: #(halt halt:)]) ifTrue: [self transcript cr; nextPutAll: 'WARNING, because of halts, not generating '; nextPutAll: desiredSource; cr; flush] ifFalse: [thisClass compile: desiredSource classified: #'multi-threading simulation switch']]]. "Make sure obsolete CoInterpreterMT switch methods are deleted." ((thisContext methodClass organization listAtCategoryNamed: #'multi-threading simulation switch') select: [:sel| (mtInterpreterClass whichClassIncludesSelector: sel) isNil]) do: [:sel| thisClass removeSelector: sel]! Item was changed: ----- Method: Spur32BitMMLECoSimulator>>isIntegerObject: (in category 'object testing') ----- isIntegerObject: oop "This list records the valid senders of isIntegerObject: as we replace uses of isIntegerObject: by isImmediate: where appropriate." | sel | sel := thisContext sender method selector. (#( DoIt DoItIn: on:do: "from the debugger" makeBaseFrameFor: quickFetchInteger:ofObject: frameOfMarriedContext: objCouldBeClassObj: isMarriedOrWidowedContext: shortPrint: bytecodePrimAt bytecodePrimAtPut commonAt: commonAtPut: loadFloatOrIntFrom: positive32BitValueOf: primitiveExternalCall checkedIntegerValueOf: bytecodePrimAtPut commonAtPut: primitiveVMParameter checkIsStillMarriedContext:currentFP: displayBitsOf:Left:Top:Right:Bottom: fetchStackPointerOf: primitiveContextAt primitiveContextAtPut subscript:with:storing:format: printContext: compare31or32Bits:equal: signed64BitValueOf: primDigitMultiply:negative: digitLength: isNegativeIntegerValueOf: magnitude64BitValueOf: primitiveMakePoint primitiveAsCharacter primitiveInputSemaphore baseFrameReturn primitiveExternalCall primDigitCompare: isLiveContext: numPointerSlotsOf: fileValueOf: loadBitBltDestForm fetchIntOrFloat:ofObject:ifNil: fetchIntOrFloat:ofObject: loadBitBltSourceForm loadPoint:from: primDigitAdd: primDigitSubtract: positive64BitValueOf: digitBitLogic:with:opIndex: signed32BitValueOf: isNormalized: primDigitDiv:negative: bytesOrInt:growTo: primitiveNewMethod isCogMethodReference: functionForPrimitiveExternalCall: genSpecialSelectorArithmetic genSpecialSelectorComparison ensureContextHasBytecodePC: instVar:ofContext: ceBaseFrameReturn: inlineCacheTagForInstance: primitiveObjectAtPut commonVariable:at:put:cacheIndex: primDigitBitShiftMagnitude: externalInstVar:ofContext: primitiveGrowMemoryByAtLeast primitiveFileSetPosition cogMethodDoesntLookKosher: shortPrintOop: primitiveSizeInBytesOfInstance + bereaveAllMarriedContextsForSnapshotFlushingExternalPrimitivesIf: + primitiveForwardSignalToSemaphore) includes: sel) ifFalse: - bereaveAllMarriedContextsForSnapshotFlushingExternalPrimitivesIf:) includes: sel) ifFalse: [self halt]. ^super isIntegerObject: oop! Item was added: + ----- Method: SpurMemoryManager>>arrayValueOf: (in category 'simulation only') ----- + arrayValueOf: arrayOop + "hack around the CoInterpreter/ObjectMemory split refactoring" + <doNotGenerate> + ^coInterpreter arrayValueOf: arrayOop! Item was added: + ----- Method: SpurMemoryManager>>getThisSessionID (in category 'simulation only') ----- + getThisSessionID + "hack around the CoInterpreter/ObjectMemory split refactoring" + <doNotGenerate> + ^coInterpreter getThisSessionID! Item was changed: ----- Method: SpurMemoryManager>>isValidObjStackPage:myIndex:firstPage: (in category 'obj stacks') ----- isValidObjStackPage: objStackPage myIndex: myx firstPage: isFirstPage "Answer if the obj stack at stackRootIndex is valid." + | page freeOrNextPage index | - | freeOrNextPage index | <inline: false> (self isValidObjStackPage: objStackPage myIndex: myx) ifFalse: [^false]. freeOrNextPage := self fetchPointer: ObjStackFreex ofObject: objStackPage. [freeOrNextPage ~= 0] whileTrue: [isFirstPage ifFalse: [objStackInvalidBecause := 'free page on other than first page'. invalidObjStackPage := objStackPage. ^false]. + freeOrNextPage = (self fetchPointer: ObjStackNextx ofObject: objStackPage) ifTrue: + [objStackInvalidBecause := 'free page = next page'. + invalidObjStackPage := freeOrNextPage. + ^false]. (self isValidObjStackPage: freeOrNextPage myIndex: myx) ifFalse: [objStackInvalidBecause := self stretch: objStackInvalidBecause cat: ', on next page'. ^false]. + page := self fetchPointer: ObjStackFreex ofObject: freeOrNextPage. + (page = freeOrNextPage + or: [page = objStackPage]) ifTrue: + [objStackInvalidBecause := 'circularity in free page list'. + invalidObjStackPage := page. + ^false]. + freeOrNextPage := page]. - freeOrNextPage := self fetchPointer: ObjStackFreex ofObject: freeOrNextPage]. isFirstPage ifTrue: [(myx between: self classTableRootSlots and: self classTableRootSlots + self hiddenRootSlots - 1) ifFalse: [objStackInvalidBecause := 'myx out of range'. invalidObjStackPage := objStackPage. ^false]. (self fetchPointer: myx ofObject: hiddenRootsObj) = objStackPage ifFalse: [objStackInvalidBecause := 'firstPage is not root'. invalidObjStackPage := objStackPage. ^false]]. index := self fetchPointer: ObjStackTopx ofObject: objStackPage. (index between: 0 and: ObjStackLimit) ifFalse: [objStackInvalidBecause := 'bad topx'. invalidObjStackPage := objStackPage. ^false]. freeOrNextPage := self fetchPointer: ObjStackNextx ofObject: objStackPage. + freeOrNextPage = 0 ifTrue: + [^true]. + freeOrNextPage = objStackPage ifTrue: + [objStackInvalidBecause := 'circularity in objStack page list'. + invalidObjStackPage := objStackPage. + ^false]. + ^self isValidObjStackPage: freeOrNextPage myIndex: myx firstPage: false! - ^freeOrNextPage = 0 - or: [self isValidObjStackPage: freeOrNextPage myIndex: myx firstPage: false]! Item was changed: ----- Method: SpurMemoryManager>>printObjStackPage:myIndex:pageType: (in category 'obj stacks') ----- printObjStackPage: objStackPage myIndex: myx pageType: pageType + | freeOrNextPage page isFirstPage isNextPage isFreePage | - | freeOrNextPage isFirstPage isNextPage isFreePage | <inline: false> isFirstPage := pageType = ObjStackMyx. isNextPage := pageType = ObjStackNextx. isFreePage := pageType = ObjStackFreex. self printObjStackPage: objStackPage myIndex: myx tag: (isFirstPage ifTrue: ['head'] ifFalse: [isFreePage ifTrue: ['free'] ifFalse: ['next']]). (isFirstPage or: [isNextPage]) ifTrue: [coInterpreter tab; print: 'topx: '; printNum: (self fetchPointer: ObjStackTopx ofObject: objStackPage); print: ' next: '; printHex: (self fetchPointer: ObjStackNextx ofObject: objStackPage). isFirstPage ifTrue: [coInterpreter print: ' free: '; printHex: (self fetchPointer: ObjStackFreex ofObject: objStackPage)]. coInterpreter cr]. + isFirstPage ifTrue: + [freeOrNextPage := self fetchPointer: ObjStackFreex ofObject: objStackPage. + [freeOrNextPage ~= 0] whileTrue: + [self printObjStackPage: freeOrNextPage myIndex: myx pageType: ObjStackFreex. + page := self fetchPointer: ObjStackFreex ofObject: freeOrNextPage. + (page = freeOrNextPage + or: [page = objStackPage]) ifTrue: + [coInterpreter print: 'circularity in free page list!!!!'; cr. + page := 0]. + freeOrNextPage := page]]. - freeOrNextPage := self fetchPointer: ObjStackFreex ofObject: objStackPage. - [freeOrNextPage ~= 0] whileTrue: - [self printObjStackPage: freeOrNextPage myIndex: myx pageType: ObjStackFreex. - freeOrNextPage := self fetchPointer: ObjStackFreex ofObject: freeOrNextPage]. freeOrNextPage := self fetchPointer: ObjStackNextx ofObject: objStackPage. freeOrNextPage ~= 0 ifTrue: [self printObjStackPage: freeOrNextPage myIndex: myx pageType: ObjStackNextx]! Item was changed: ----- Method: SpurMemoryManager>>swizzleObjStackAt: (in category 'obj stacks') ----- swizzleObjStackAt: objStackRootIndex "On load, swizzle the pointers in an obj stack. Answer the obj stack's oop." + | firstPage page stackOrNil index field | - | firstPage stackOrNil index field | firstPage := stackOrNil := self fetchPointer: objStackRootIndex ofObject: hiddenRootsObj. stackOrNil = nilObj ifTrue: [^stackOrNil]. [self assert: (self numSlotsOfAny: stackOrNil) = ObjStackPageSlots. self assert: (self fetchPointer: ObjStackMyx ofObject: stackOrNil) = objStackRootIndex. "There are four fixed slots in an obj stack, and a Topx of 0 indicates empty, so if there were 5 slots in an oop stack, full would be 2, and the last 0-rel index is 4. Hence the last index is topx + fixed slots - 1, or topx + ObjStackNextx" index := (self fetchPointer: ObjStackTopx ofObject: stackOrNil) + ObjStackNextx. "swizzle fields including ObjStackNextx and leave field containing the next link." [field := self fetchPointer: index ofObject: stackOrNil. (field = 0 or: [self isImmediate: field]) ifFalse: [field := segmentManager swizzleObj: field. + self storePointer: index ofObjStack: stackOrNil withValue: field]. - self storePointer: ObjStackNextx ofObjStack: stackOrNil withValue: field]. (index := index - 1) > ObjStackMyx] whileTrue. (stackOrNil := field) ~= 0] whileTrue. + (stackOrNil := self fetchPointer: ObjStackFreex ofObject: firstPage) ~= 0 ifTrue: + [[page := self fetchPointer: ObjStackFreex ofObject: stackOrNil. + page ~= 0] whileTrue: + [field := segmentManager swizzleObj: page. + self storePointer: ObjStackFreex ofObjStack: stackOrNil withValue: field. + stackOrNil := field]]. + (stackOrNil := self fetchPointer: ObjStackNextx ofObject: firstPage) ~= 0 ifTrue: + [[page := self fetchPointer: ObjStackNextx ofObject: stackOrNil. + page ~= 0] whileTrue: + [field := segmentManager swizzleObj: page. + self storePointer: ObjStackNextx ofObjStack: stackOrNil withValue: field. + stackOrNil := field]]. - [stackOrNil := self fetchPointer: ObjStackFreex ofObject: firstPage. - stackOrNil ~= 0] whileTrue: - [field := segmentManager swizzleObj: stackOrNil. - self storePointer: ObjStackFreex ofObjStack: firstPage withValue: field. - firstPage := field]. self assert: (self isValidObjStackAt: objStackRootIndex). ^self fetchPointer: objStackRootIndex ofObject: hiddenRootsObj! Item was changed: ----- Method: StackInterpreter>>arrayValueOf: (in category 'utilities') ----- arrayValueOf: arrayOop "Return the address of first indexable field of resulting array object, or fail if the instance variable does not contain an indexable bytes or words object." "Note: May be called by translated primitive code." <returnTypeC: #'void *'> + (objectMemory isWordsOrBytes: arrayOop) ifTrue: - ((objectMemory isNonIntegerObject: arrayOop) - and: [objectMemory isWordsOrBytes: arrayOop]) ifTrue: [^self cCoerceSimple: (self pointerForOop: arrayOop + BaseHeaderSize) to: #'void *']. self primitiveFail! |
Free forum by Nabble | Edit this page |