Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3087.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3087 Author: eem Time: 13 October 2021, 3:32:02.224265 pm UUID: 27c5bd11-8d79-40f2-b273-5794bb04cea2 Ancestors: VMMaker.oscog-eem.3086
CoInterpreter prim trace log: - record the primitive method instead of the message selector - add the class of the receiver as a parameter in printing TracePrimitiveFailure events
Fix an anachronism in SpurMemoryManager's class comment. Fix a slip in Slang revealled by the prim trace log changes.
=============== Diff against VMMaker.oscog-eem.3086 ===============
Item was changed: ----- Method: CoInterpreter>>ceCheckAndMaybeRetryPrimitive: (in category 'primitive support') ----- ceCheckAndMaybeRetryPrimitive: primIndex "Log failure and then retry if there's an accessorDepth or failure due to no memory." <api> <option: #SpurObjectMemory> | retried | (cogit recordPrimTrace and: [primTracePluginName isNil]) ifTrue: + [self fastLogPrim: TracePrimitiveFailure. + self fastLogPrim: (objectMemory fetchClassOf: (self stackValue: argumentCount))]. - [self fastLogPrim: TracePrimitiveFailure]. retried := self retryPrimitiveOnFailure. (retried and: [cogit recordPrimTrace]) ifTrue: [self fastLogPrim: TracePrimitiveRetry]!
Item was changed: ----- Method: CoInterpreter>>checkForAndFollowForwardedPrimitiveState (in category 'primitive support') ----- checkForAndFollowForwardedPrimitiveState "Override to log and export to Cogit" <api> <option: #SpurObjectMemory> | found | (cogit recordPrimTrace and: [primTracePluginName isNil]) ifTrue: + [self fastLogPrim: TracePrimitiveFailure. + self fastLogPrim: (objectMemory fetchClassOf: (self stackValue: argumentCount))]. - [self fastLogPrim: TracePrimitiveFailure]. found := super checkForAndFollowForwardedPrimitiveState. (found and: [cogit recordPrimTrace]) ifTrue: [self fastLogPrim: TracePrimitiveRetry]. ^found!
Item was changed: ----- Method: CoInterpreter>>dumpPrimTraceLog (in category 'debug support') ----- dumpPrimTraceLog "The prim trace log is a circular buffer of entries. If there is an entry at primTraceLogIndex \ PrimTraceLogSize it has entries. If there is something at primTraceLogIndex it has wrapped."
<api> <inline: false> + | hasParameter | (primTraceLog at: (self safe: primTraceLogIndex - 1 mod: PrimTraceLogSize)) = 0 ifTrue: [^self]. + hasParameter := false. (primTraceLog at: primTraceLogIndex) ~= 0 ifTrue: [primTraceLogIndex to: PrimTraceLogSize - 1 do: + [:i | hasParameter := self printPrimLogEntryAt: i hasParameter: hasParameter]]. - [:i | self printPrimLogEntryAt: i; cr]]. 0 to: primTraceLogIndex - 1 do: + [:i | hasParameter := self printPrimLogEntryAt: i hasParameter: hasParameter]! - [:i | self printPrimLogEntryAt: i; cr]!
Item was changed: ----- Method: CoInterpreter>>fastLogPrim: (in category 'debug support') ----- + fastLogPrim: aMethodSelectorOrImmediate - fastLogPrim: aSelectorOrImmediate "Fast tracing of named primitives. primTraceLogIndex is a byte variable. + aMethodSelectorOrImmediate is a method oop, a selector oop or one of TraceCodeCompaction et al. - aSelectorOrImmediate is a selector oop or one of TraceCodeCompaction et al. primTraceLog has 256 entries. In C the + 1 below is hence implicitly modulo 256." <inline: true> + primTraceLog at: primTraceLogIndex put: aMethodSelectorOrImmediate. - primTraceLog at: primTraceLogIndex put: aSelectorOrImmediate. self primTraceLogIndex: primTraceLogIndex + 1!
Item was changed: ----- Method: CoInterpreter>>mapPrimTraceLog (in category 'debug support') ----- mapPrimTraceLog + "The prim trace log is a circular buffer of objects. If there is - "The prim trace log is a circular buffer of selectors. If there is an entry at primTraceLogIndex - 1 \ PrimTraceBufferSize it has entries. If there is something at primTraceLogIndex it has wrapped." <inline: false> + | entryOop | (primTraceLog at: (self safe: primTraceLogIndex - 1 mod: PrimTraceLogSize)) = 0 ifTrue: [^self]. (primTraceLog at: primTraceLogIndex) ~= 0 ifTrue: [primTraceLogIndex to: PrimTraceLogSize - 1 do: + [:i| + entryOop := primTraceLog at: i. + (entryOop ~= 0 + and: [objectMemory shouldRemapOop: entryOop]) ifTrue: + [primTraceLog at: i put: (objectMemory remapObj: entryOop)]]]. - [:i| | selector | - selector := primTraceLog at: i. - (selector ~= 0 - and: [objectMemory shouldRemapOop: selector]) ifTrue: - [primTraceLog at: i put: (objectMemory remapObj: selector)]]]. 0 to: primTraceLogIndex - 1 do: + [:i| + entryOop := primTraceLog at: i. + (entryOop ~= 0 + and: [objectMemory shouldRemapOop: entryOop]) ifTrue: + [primTraceLog at: i put: (objectMemory remapObj: entryOop)]]! - [:i| | selector | - selector := primTraceLog at: i. - (selector ~= 0 - and: [objectMemory shouldRemapOop: selector]) ifTrue: - [primTraceLog at: i put: (objectMemory remapObj: selector)]]!
Item was changed: ----- Method: CoInterpreter>>markAndTracePrimTraceLog (in category 'debug support') ----- markAndTracePrimTraceLog + "The prim trace log is a circular buffer of objects. If there is - "The prim trace log is a circular buffer of selectors. If there is an entry at primTraceLogIndex - 1 \ PrimTraceBufferSize it has entries. If there is something at primTraceLogIndex it has wrapped." <inline: false> + | entryOop | (primTraceLog at: (self safe: primTraceLogIndex - 1 mod: PrimTraceLogSize)) = 0 ifTrue: [^self]. (primTraceLog at: primTraceLogIndex) ~= 0 ifTrue: [primTraceLogIndex to: PrimTraceLogSize - 1 do: + [:i| + entryOop := primTraceLog at: i. + (entryOop ~= 0 + and: [objectMemory isNonImmediate: entryOop]) ifTrue: + [objectMemory markAndTrace: entryOop]]]. - [:i| | selector | - selector := primTraceLog at: i. - (selector ~= 0 - and: [objectMemory isNonImmediate: selector]) ifTrue: - [objectMemory markAndTrace: selector]]]. 0 to: primTraceLogIndex - 1 do: + [:i| + entryOop := primTraceLog at: i. + (entryOop ~= 0 + and: [objectMemory isNonImmediate: entryOop]) ifTrue: + [objectMemory markAndTrace: entryOop]]! - [:i| | selector | - selector := primTraceLog at: i. - (selector ~= 0 - and: [objectMemory isNonImmediate: selector]) ifTrue: - [objectMemory markAndTrace: selector]]!
Item was removed: - ----- Method: CoInterpreter>>printPrimLogEntryAt: (in category 'debug support') ----- - printPrimLogEntryAt: i - <inline: false> - | intOrSelector | - intOrSelector := primTraceLog at: i. - (objectMemory isImmediate: intOrSelector) - ifTrue: - [intOrSelector = TraceIncrementalGC ifTrue: - [self print: '**IncrementalGC**'. ^nil]. - intOrSelector = TraceFullGC ifTrue: - [self print: '**FullGC**'. ^nil]. - intOrSelector = TraceCodeCompaction ifTrue: - [self print: '**CompactCode**'. ^nil]. - intOrSelector = TraceStackOverflow ifTrue: - [self print: '**StackOverflow**'. ^nil]. - intOrSelector = TracePrimitiveFailure ifTrue: - [self print: '**PrimitiveFailure**'. ^nil]. - intOrSelector = TracePrimitiveRetry ifTrue: - [self print: '**PrimitiveRetry**'. ^nil]. - self print: '???'] - ifFalse: - [intOrSelector = 0 - ifTrue: ['%d!!!!!!' f: transcript printf: i] - ifFalse: [objectMemory safePrintStringOf: intOrSelector]]!
Item was added: + ----- Method: CoInterpreter>>printPrimLogEntryAt:hasParameter: (in category 'debug support') ----- + printPrimLogEntryAt: i hasParameter: hasParameter + <inline: false> + "print the entry and answer if it takes a parameter (as the following entry)" + | entryOop className length | + entryOop := primTraceLog at: i. + hasParameter ifTrue: + [(objectMemory addressCouldBeObj: entryOop) + ifTrue: [className := self nameOfClass: entryOop lengthInto: (self addressOf: length put: [:v| length := v])] + ifFalse: [className := 'bad class'. length := 9]. + '%.*s\n' f: transcript printf: { length. className }. + ^false]. + (objectMemory isImmediate: entryOop) + ifTrue: + [entryOop = TraceIncrementalGC ifTrue: + [self print: '**IncrementalGC**\n'. ^false]. + entryOop = TraceFullGC ifTrue: + [self print: '**FullGC**\n'. ^false]. + entryOop = TraceCodeCompaction ifTrue: + [self print: '**CompactCode**\n'. ^false]. + entryOop = TraceStackOverflow ifTrue: + [self print: '**StackOverflow**\n'. ^false]. + entryOop = TracePrimitiveFailure ifTrue: + [self print: '**PrimitiveFailure** '. ^true]. + entryOop = TracePrimitiveRetry ifTrue: + [self print: '**PrimitiveRetry**\n'. ^false]. + self print: '???\n'] + ifFalse: + [(objectMemory addressCouldBeObj: entryOop) + ifFalse: ['%d!!!!!!\n' f: transcript printf: i] + ifTrue: + [(objectMemory isCompiledMethod: entryOop) + ifTrue: + [| methodClass methodSel | + className := '???'. length := 3. + methodClass := self safeMethodClassOf: entryOop. + methodClass ~= objectMemory nilObject ifTrue: + [className := self nameOfClass: methodClass lengthInto: (self addressOf: length put: [:v| length := v])]. + methodSel := self findSelectorOfMethod: entryOop. + methodSel = objectMemory nilObject + ifTrue: + ['%.*s>>bad selector %p\n' + f: transcript + printf: { length. className. methodSel }] + ifFalse: + ['%.*s>>#%.*s\n' + f: transcript + printf: { length. className. + objectMemory numBytesOfBytes: methodSel. objectMemory firstIndexableField: methodSel }]] + ifFalse: [objectMemory safePrintStringOf: entryOop. self cr]]]. + ^false!
Item was changed: ----- Method: CoInterpreter>>slowPrimitiveResponse (in category 'primitive support') ----- slowPrimitiveResponse "Invoke a normal (non-quick) primitive. Called under the assumption that primFunctionPointer has been preloaded. Override to log primitive." (self recordPrimTraceForMethod: newMethod) ifTrue: + [self fastLogPrim: newMethod]. - [self fastLogPrim: messageSelector]. ^super slowPrimitiveResponse!
Item was changed: ----- Method: InterpreterPrimitives>>primitiveSetOrHasIdentityHash (in category 'object access primitives') ----- primitiveSetOrHasIdentityHash | hash oldHash thisReceiver isReceiverAClass | argumentCount = 0 ifTrue: [| hasHash | hasHash := (objectMemory isNonImmediate: self stackTop) and: [objectMemory hasIdentityHash: self stackTop]. ^self methodReturnBool: hasHash]. isReceiverAClass := false. argumentCount = 2 ifTrue: [| lastArg | lastArg := self stackTop. (objectMemory isIntegerObject: lastArg) ifTrue: "e.g. Symbol primitiveSetIdentityHashOf: aSymbol to: hash" [hash := lastArg. thisReceiver := self stackValue: 1] ifFalse: "anObject primitiveSetIdentityHash: hashValue isBehavior: boolean" [thisReceiver := self stackValue: 2. hash := self stackValue: 1. lastArg = objectMemory trueObject ifTrue: [isReceiverAClass := true] ifFalse: [lastArg = objectMemory falseObject ifFalse: [^self primitiveFailFor: PrimErrBadArgument]]]] ifFalse: "anObject primitiveSetIdentityHashTo: hash" [thisReceiver := self stackValue: 1. hash := self stackTop]. ((objectMemory isIntegerObject: hash) + and: [hash := objectMemory integerValueOf: hash. "if written naturally, clang warns: unsequenced modification and access to 'hash' " + (hash bitAnd: objectMemory maxIdentityHash) = hash]) ifFalse: + [^self primitiveFailFor: PrimErrBadArgument]. - and: [((hash := objectMemory integerValueOf: hash) bitAnd: objectMemory maxIdentityHash) = hash]) ifFalse: - [^self primitiveFailFor: PrimErrBadArgument]. (objectMemory isNonImmediate: thisReceiver) ifFalse: [^self primitiveFailFor: (thisReceiver = (self stackValue: argumentCount) ifTrue: [PrimErrBadReceiver] ifFalse: [PrimErrBadArgument])]. oldHash := objectMemory hashBitsOf: thisReceiver. objectMemory setHashBitsOf: thisReceiver to: hash. (isReceiverAClass and: [objectMemory hasSpurMemoryManagerAPI]) ifTrue: [objectMemory classAtIndex: hash put: thisReceiver. "this figures out if the index is ambiguous and fixes all the instances if needed" objectMemory allInstancesOf: thisReceiver]. self methodReturnInteger: oldHash!
Item was changed: ----- Method: SimpleStackBasedCogit>>genFastPrimTraceUsing:and: (in category 'primitive generators') ----- genFastPrimTraceUsing: r1 and: r2 + "Suport for compileInterpreterPrimitive. Generate inline code + so as to record the primitive trace as fast as possible." - "Suport for compileInterpreterPrimitive. Generate inline code so as to record the primitive - trace as fast as possible." backEnd byteReadsZeroExtend ifFalse: [self MoveCq: 0 R: r2]. self MoveAb: coInterpreter primTraceLogIndexAddress R: r2. self LoadEffectiveAddressMw: 1 r: r2 R: r1. self MoveR: r1 Ab: coInterpreter primTraceLogIndexAddress. methodLabel addDependent: (self annotateAbsolutePCRef: (self MoveCw: methodLabel asInteger R: r1)). + self MoveMw: (self offset: CogMethod of: #methodObject) r: r1 R: TempReg. - self MoveMw: (self offset: CogMethod of: #selector) r: r1 R: TempReg. self MoveCw: coInterpreter primTraceLogAddress asInteger R: r1. self MoveR: TempReg Xwr: r2 R: r1!
Item was changed: CogClass subclass: #SpurMemoryManager (excessive size, no diff calculated)
Item was added: + ----- Method: TVarArgsSendNode>>isSameAs: (in category 'comparing') ----- + isSameAs: aTParseNode + (aTParseNode isSend + and: [self numArgs = aTParseNode numArgs]) ifFalse: + [^false]. + ^super isSameAs: aTParseNode!
vm-dev@lists.squeakfoundation.org