Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3160.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3160 Author: eem Time: 18 February 2022, 12:07:33.23046 pm UUID: 56010400-c0d0-407a-aed4-55432c452571 Ancestors: VMMaker.oscog-eem.3159
...and update a few primitives that use PrimCallMayEndureCodeCompaction to also supply the required PrimCallNeedsNewMethod.
=============== Diff against VMMaker.oscog-eem.3159 ===============
Item was changed: ----- Method: CoInterpreterPrimitives>>primitiveProfileSemaphore (in category 'process primitives') ----- primitiveProfileSemaphore "Primitive. Install the semaphore to be used for profiling, or nil if no semaphore should be used. See also primitiveProfileStart." <export: true> + <primitiveMetadata: #(PrimCallMayEndureCodeCompaction PrimCallNeedsNewMethod)> - <primitiveMetadata: #PrimCallMayEndureCodeCompaction> | sema flushState | sema := self stackValue: 0. sema = objectMemory nilObject ifTrue: [flushState := profileSemaphore ~= objectMemory nilObject] ifFalse: [flushState := profileSemaphore = objectMemory nilObject. (objectMemory isSemaphoreOop: sema) ifFalse: [^self primitiveFailFor: PrimErrBadArgument]]. profileSemaphore := sema. profileProcess := profileMethod := objectMemory nilObject. "If we've switched profiling on or off we must void machine code (and machine code pcs in contexts) since we will start or stop testing the profile clock in machine code primitive invocations, and so generate slightly different code from here on in." flushState ifTrue: [self flushExternalPrimitives] ifFalse: [self methodReturnReceiver]!
Item was changed: ----- Method: CoInterpreterPrimitives>>primitiveUnloadModule (in category 'plugin primitives') ----- primitiveUnloadModule "Primitive. Unload the module with the given name. Reloading of the module will happen *later* automatically, when a function from it is called. This is forced by invalidating all external primitive methods and activations in flushExternalPrimitives. N.B. since this is most likely a development time activity we don't care about performance." + <primitiveMetadata: #(PrimCallMayEndureCodeCompaction PrimCallNeedsNewMethod)> - <primitiveMetadata: #PrimCallMayEndureCodeCompaction> | moduleName moduleLength | moduleName := self stackTop. (objectMemory isBytes: moduleName) ifFalse:[^self primitiveFail]. moduleLength := objectMemory numBytesOfBytes: moduleName. (self ioUnloadModule: (self oopForPointer: (objectMemory firstIndexableField: moduleName)) OfLength: moduleLength) ifFalse:[^self primitiveFail]. (self object: moduleName equalsString: 'SqueakFFIPrims' ofSize: moduleLength) ifTrue: [primitiveCalloutPointer := self cCoerceSimple: -1 to: #'void *']. "N.B. flushExternalPrimitives continues. Do *not* do anything after flushExternalPrimitives in the CoInterpreter" self forceInterruptCheck. self flushExternalPrimitives "NOTREACHED"!
Item was changed: ----- Method: StackInterpreterPrimitives>>primitiveClone (in category 'object access primitives') ----- primitiveClone "Return a shallow copy of the receiver. Special-case non-single contexts (because of context-to-stack mapping). Can't fail for contexts cuz of image context instantiation code (sigh)."
+ <primitiveMetadata: #(PrimCallMayEndureCodeCompaction PrimCallNeedsNewMethod)> "because of cloneContext: below" - <primitiveMetadata: #PrimCallMayEndureCodeCompaction> "because of cloneContext: below" | rcvr newCopy | rcvr := self stackTop. (objectMemory isImmediate: rcvr) ifTrue: [newCopy := rcvr] ifFalse: [(objectMemory isContextNonImm: rcvr) ifTrue: [newCopy := self cloneContext: rcvr] ifFalse: [(argumentCount = 0 or: [(objectMemory isForwarded: rcvr) not]) ifTrue: [newCopy := objectMemory cloneObject: rcvr] ifFalse: [newCopy := 0]]. newCopy = 0 ifTrue: [^self primitiveFailFor: PrimErrNoMemory]]. self methodReturnValue: newCopy!
Item was changed: ----- Method: StackInterpreterPrimitives>>primitiveInstVarAt (in category 'object access primitives') ----- primitiveInstVarAt + <primitiveMetadata: #(PrimCallMayEndureCodeCompaction PrimCallNeedsNewMethod)> "because of externalInstVar:ofContext: below" - <primitiveMetadata: #PrimCallMayEndureCodeCompaction> "because of externalInstVar:ofContext: below" | index rcvr hdr fmt totalLength fixedFields value | index := self stackTop. rcvr := self stackValue: 1. ((objectMemory isNonIntegerObject: index) or: [argumentCount > 1 "e.g. object:instVarAt:" and: [objectMemory isOopForwarded: rcvr]]) ifTrue: [^self primitiveFailFor: PrimErrBadArgument]. (objectMemory isImmediate: rcvr) ifTrue: [^self primitiveFailFor: PrimErrInappropriate]. index := objectMemory integerValueOf: index. hdr := objectMemory baseHeader: rcvr. fmt := objectMemory formatOfHeader: hdr. totalLength := objectMemory lengthOf: rcvr baseHeader: hdr format: fmt. fixedFields := objectMemory fixedFieldsOf: rcvr format: fmt length: totalLength. (index >= 1 and: [index <= fixedFields]) ifFalse: [^self primitiveFailFor: PrimErrBadIndex]. (fmt = objectMemory indexablePointersFormat and: [objectMemory isContextHeader: hdr]) ifTrue: [value := self externalInstVar: index - 1 ofContext: rcvr] ifFalse: [value := self subscript: rcvr with: index format: fmt]. self pop: argumentCount + 1 thenPush: value!
Item was changed: ----- Method: StackInterpreterPrimitives>>primitiveSlotAt (in category 'object access primitives') ----- primitiveSlotAt "Answer a slot in an object. This numbers all slots from 1, ignoring the distinction between named and indexed inst vars. In objects with both named and indexed inst vars, the named inst vars precede the indexed ones. In non-object indexed objects (objects that contain bits, not object references) this primitive answers the raw integral value at each slot. e.g. for Strings it answers the character code, not the Character object at each slot." + <primitiveMetadata: #(PrimCallMayEndureCodeCompaction PrimCallNeedsNewMethod)> "because of externalInstVar:ofContext: below" - <primitiveMetadata: #PrimCallMayEndureCodeCompaction> "because of externalInstVar:ofContext: below" | index rcvr fmt numSlots | index := self stackTop. rcvr := self stackValue: 1. (objectMemory isIntegerObject: index) ifFalse: [^self primitiveFailFor: PrimErrBadArgument]. (objectMemory isImmediate: rcvr) ifTrue: [^self primitiveFailFor: PrimErrBadReceiver]. fmt := objectMemory formatOf: rcvr. index := (objectMemory integerValueOf: index) - 1.
fmt <= objectMemory lastPointerFormat ifTrue: [numSlots := objectMemory numSlotsOf: rcvr. (self asUnsigned: index) < numSlots ifTrue: [| value numLiveSlots | (objectMemory isContextNonImm: rcvr) ifTrue: [self externalWriteBackHeadFramePointers. numLiveSlots := (self stackPointerForMaybeMarriedContext: rcvr) + CtxtTempFrameStart. value := (self asUnsigned: index) < numLiveSlots ifTrue: [self externalInstVar: index ofContext: rcvr] ifFalse: [objectMemory nilObject]] ifFalse: [value := objectMemory fetchPointer: index ofObject: rcvr]. self pop: argumentCount + 1 thenPush: value. ^0]. ^self primitiveFailFor: PrimErrBadIndex].
fmt >= objectMemory firstByteFormat ifTrue: [fmt >= objectMemory firstCompiledMethodFormat ifTrue: [^self primitiveFailFor: PrimErrUnsupported]. numSlots := objectMemory numBytesOfBytes: rcvr. (self asUnsigned: index) < numSlots ifTrue: [self pop: argumentCount + 1 thenPushInteger: (objectMemory fetchByte: index ofObject: rcvr). ^0]. ^self primitiveFailFor: PrimErrBadIndex].
(objectMemory hasSpurMemoryManagerAPI and: [fmt >= objectMemory firstShortFormat]) ifTrue: [numSlots := objectMemory num16BitUnitsOf: rcvr. (self asUnsigned: index) < numSlots ifTrue: [self pop: argumentCount + 1 thenPushInteger: (objectMemory fetchUnsignedShort16: index ofObject: rcvr). ^0]. ^self primitiveFailFor: PrimErrBadIndex].
fmt = objectMemory sixtyFourBitIndexableFormat ifTrue: [numSlots := objectMemory num64BitUnitsOf: rcvr. (self asUnsigned: index) < numSlots ifTrue: [self pop: argumentCount + 1 thenPush: (self positive64BitIntegerFor: (objectMemory fetchLong64: index ofObject: rcvr)). ^0]. ^self primitiveFailFor: PrimErrBadIndex].
fmt >= objectMemory firstLongFormat ifTrue: [numSlots := objectMemory num32BitUnitsOf: rcvr. (self asUnsigned: index) < numSlots ifTrue: [self pop: argumentCount + 1 thenPush: (self positive32BitIntegerFor: (objectMemory fetchLong32: index ofObject: rcvr)). ^0]. ^self primitiveFailFor: PrimErrBadIndex].
^self primitiveFailFor: PrimErrBadReceiver!
Item was changed: ----- Method: StackInterpreterPrimitives>>primitiveUnloadModule (in category 'plugin primitives') ----- primitiveUnloadModule "Primitive. Unload the module with the given name. Reloading of the module will happen *later* automatically, when a function from it is called. This is forced by invalidating all external primitive methods and activations in flushExternalPrimitives. N.B. since this is most likely a development time activity we don't care about performance." - <primitiveMetadata: #PrimCallMayEndureCodeCompaction> | moduleName moduleLength | moduleName := self stackTop. (objectMemory isBytes: moduleName) ifFalse:[^self primitiveFail]. moduleLength := objectMemory numBytesOfBytes: moduleName. (self ioUnloadModule: (self oopForPointer: (objectMemory firstIndexableField: moduleName)) OfLength: moduleLength) ifFalse:[^self primitiveFail]. (self object: moduleName equalsString: 'SqueakFFIPrims' ofSize: moduleLength) ifTrue: [primitiveCalloutPointer := self cCoerceSimple: -1 to: #'void *']. self forceInterruptCheck. self flushExternalPrimitives. self pop: 1 "pop moduleName; return receiver"!
vm-dev@lists.squeakfoundation.org