Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2245.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.2245 Author: eem Time: 21 June 2017, 4:44:55.649472 pm UUID: 3ab740bb-02ca-46f8-a814-d0f45134fafb Ancestors: VMMaker.oscog-eem.2244
Newspeak: For the Cadence debugger allow CompiledCode>>voidCogVMState to a) take an optional boolean which can be used to suppress the heap scan for contexts with machine code pcs into the receiver/method arg and b) funciton as a VMMirror primitive.
Hence extract the body of primitiveFlushCacheByMethod to flushMethodCacheForMethod:.
Too lazy to update primitiveFlushCacheByMethod to match. This new facility is used only in Cogit Cadence VMs as yet.
VMMaker: Make sure generateAllSpurConfigurations generates the Lowcode VMs and the 64-bit Newspeak StackInterpreter.
=============== Diff against VMMaker.oscog-eem.2244 ===============
Item was changed: ----- Method: CoInterpreterPrimitives>>primitiveVoidVMStateForMethod (in category 'system control primitives') ----- primitiveVoidVMStateForMethod + "The receiver (or first argument) must be a compiledMethod. The optional (or second) argument must be a + boolean. Clear all VM state associated with the method, including any machine code, or machine code pcs + in context objects. If the optional boolean argument is false do not scan the heap looking for contexts." + | activeContext methodObj scanHeapForContexts hasCogMethod theFrame thePage | - "The receiver is a compiledMethod. Clear all VM state associated with the method, - including any machine code, or machine code pcs in context objects." - | activeContext methodObj hasCogMethod theFrame thePage | <var: #theFrame type: #'char *'> <var: #thePage type: #'StackPage *'> + scanHeapForContexts := true. "See comment ''One might think...'' below" + "In Smalltalk allow both aMethod voidCogVMState and aMethod voidCogVMStateScanningContextsIf: aBoolean" + argumentCount = 0 + ifTrue: + [methodObj := self stackTop] + ifFalse: + [methodObj := self stackValue: 1. + scanHeapForContexts := self booleanValueOf: self stackTop. + self failed ifTrue: + [^self primitiveFailFor: PrimErrBadArgument]]. + NewspeakVM + ifFalse: + [argumentCount > 1 ifTrue: + [^self primitiveFailFor: PrimErrBadNumArgs]] + ifTrue: "In the NewspeakVM we allow VMMirror voidStateFor: method scanningIf: aBoolean as well as the Smalltalk forms." + [argumentCount >= 2 ifTrue: + [argumentCount > 2 ifTrue: + [^self primitiveFailFor: PrimErrBadNumArgs]. + (objectMemory isOopCompiledMethod: methodObj) ifFalse: + [^self primitiveFailFor: PrimErrBadArgument]]]. + self flushMethodCacheForMethod: methodObj. - super primitiveFlushCacheByMethod. - "One might think (as this author did) that the heap scan is unnecessary if the method does not - have a cog method. But it could be the case that the code zone has recently been reclaimed - and so not having a cog method is no indication that it didn't have a cog method some time in - the recent past, and that there are indeed still contexts with machine code pcs out there. The - only steps that can be avoided is divorcing frames in the stack zone, and scanning to unlink and - free if there isn't a cog method." - methodObj := self stackTop. activeContext := self ensureFrameIsMarried: framePointer SP: stackPointer. self ensurePushedInstructionPointer. self externalWriteBackHeadFramePointers. (hasCogMethod := self methodHasCogMethod: methodObj) ifTrue: [self divorceMachineCodeFramesWithMethod: methodObj]. + "One might think (as this author did) that the heap scan is unnecessary if the method does not + have a cog method. But it could be the case that the code zone has recently been reclaimed + and so not having a cog method is no indication that it didn't have a cog method some time in + the recent past, and that there are indeed still contexts with machine code pcs out there. The + only steps that can be avoided are divorcing frames in the stack zone, and scanning to unlink and + free if there isn't a cog method, unless we are told otherwise." + scanHeapForContexts ifTrue: + [self ensureAllContextsWithMethodHaveBytecodePCs: methodObj]. - self ensureAllContextsWithMethodHaveBytecodePCs: methodObj. hasCogMethod ifTrue: [cogit unlinkSendsTo: methodObj andFreeIf: true]. + + "If flushing led to divorce continue in the interpreter." + (self isStillMarriedContext: activeContext) ifFalse: + [self zeroStackPage. "to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters:" + self marryContextInNewStackPageAndInitializeInterpreterRegisters: activeContext. + self popStack. "pop bogus machine-code instructionPointer" + self assert: (methodObj = self stackTop or: [argumentCount > 0 and: [methodObj = (self stackValue: 1)]]). + self pop: argumentCount. + self siglong: reenterInterpreter jmp: ReturnToInterpreter. + "NOTREACHED"]. + "If not, work out where we are and continue" + theFrame := self frameOfMarriedContext: activeContext. + thePage := stackPages stackPageFor: theFrame. + self assert: thePage headFP = theFrame. + self setStackPageAndLimit: thePage. + self setStackPointersFromPage: thePage. + instructionPointer := self popStack. + self assert: (methodObj = self stackTop or: [argumentCount > 0 and: [methodObj = (self stackValue: 1)]]). + self pop: argumentCount! - (self isStillMarriedContext: activeContext) - ifTrue: - [theFrame := self frameOfMarriedContext: activeContext. - thePage := stackPages stackPageFor: theFrame. - self assert: thePage headFP = theFrame. - self setStackPageAndLimit: thePage. - self setStackPointersFromPage: thePage. - instructionPointer := self popStack. - self assert: methodObj = self stackTop] - ifFalse: - [self zeroStackPage. "to avoid assert in marryContextInNewStackPageAndInitializeInterpreterRegisters:" - self marryContextInNewStackPageAndInitializeInterpreterRegisters: activeContext. - self popStack. "pop bogus machine-code instructionPointer" - self assert: methodObj = self stackTop. - self siglong: reenterInterpreter jmp: ReturnToInterpreter]!
Item was added: + ----- Method: StackInterpreter>>flushMethodCacheForMethod: (in category 'method lookup cache') ----- + flushMethodCacheForMethod: oldMethod + "Flush the method caches of references to oldMethod." + | probe | + probe := 0. + 1 to: MethodCacheEntries do: + [:i | + (methodCache at: probe + MethodCacheMethod) = oldMethod ifTrue: + [methodCache at: probe + MethodCacheSelector put: 0]. + probe := probe + MethodCacheEntrySize]. + self flushExternalPrimitiveOf: oldMethod. + self flushAtCache!
Item was changed: ----- Method: StackInterpreterPrimitives>>primitiveFlushCacheByMethod (in category 'system control primitives') ----- primitiveFlushCacheByMethod "The receiver is a compiledMethod. Clear all entries in the method lookup cache that refer to this method, presumably because it has been redefined, overridden or removed." + self flushMethodCacheForMethod: self stackTop! - | probe oldMethod | - oldMethod := self stackTop. - probe := 0. - 1 to: MethodCacheEntries do: - [:i | - (methodCache at: probe + MethodCacheMethod) = oldMethod ifTrue: - [methodCache at: probe + MethodCacheSelector put: 0]. - probe := probe + MethodCacheEntrySize]. - self flushExternalPrimitiveOf: oldMethod. - self flushAtCache!
Item was changed: ----- Method: VMMaker class>>generateAllSpurConfigurations (in category 'configurations') ----- generateAllSpurConfigurations + self generateAllNewspeakConfigurationsUnderVersionControl; - self generateNewspeakSpurCogVM; - generateNewspeakSpurCog64VM; - generateNewspeakSpurStackVM; generateSqueakSpurCogVM; generateSqueakSpurCog64VM; generateSqueakSpurCogSistaVM; generateSqueakSpurCogSista64VM; generateSqueakSpurStackVM; + generateSqueakSpurStack64VM; + generateAllSpurLowcodeConfigurations! - generateSqueakSpurStack64VM!
vm-dev@lists.squeakfoundation.org