Tom Braun uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog.seperateMarking-WoC.3304.mcz
==================== Summary ====================
Name: VMMaker.oscog.seperateMarking-WoC.3304
Author: WoC
Time: 12 January 2023, 11:55:24.18587 pm
UUID: da8e55d1-1ff6-4125-8be0-dd141c51396a
Ancestors: VMMaker.oscog.seperateMarking-WoC.3303
When migrating an object replace the old reference in the remembered set with the new one. Otherwise the forwarder would be kept there for no real reason and maybe even would stay alive for quite a long time (imagine the forwarder being in an image we freed completetly. It is hidden inside a free chunk and the sweeper will not be able to find and let the scavenger forget the forwarder -> forget it directly)
=============== Diff against VMMaker.oscog.seperateMarking-WoC.3303 ===============
Item was added:
+ ----- Method: SpurGenerationScavenger>>remember:insteadOf: (in category 'gc - global') -----
+ remember: newObjOop insteadOf: oldObjOop
+ "Replace a forwarder by the object it is pointing to in the remembered set. This method is designed to
+ work with migrate:sized:to: from the SpurIncrementalCompactor family"
+ self assert: rememberedSetSize > 0.
+ self assert: (manager isRemembered: oldObjOop).
+ self assert: (manager isRemembered: newObjOop).
+
+ manager setIsRememberedOf: oldObjOop to: false.
+
+ [| index |
+ index := 0.
+ [index < rememberedSetSize] whileTrue:
+ [oldObjOop = (rememberedSet at: index)
+ ifTrue:
+ [rememberedSet at: index put: newObjOop.
+ index := rememberedSetSize]
+ ifFalse: [index := index + 1]]].!
Item was changed:
----- Method: SpurIncrementalCompactingSweeper>>migrate:sized:to: (in category 'incremental compact') -----
migrate: obj sized: bytesToCopy to: address
| copy |
self assert: (manager isPinned: obj) not.
manager memcpy: address asVoidPointer _: (manager startOfObject: obj) asVoidPointer _: bytesToCopy.
copy := manager objectStartingAt: address.
(manager isRemembered: copy) ifTrue:
+ [scavenger remember: copy insteadOf: obj].
- ["copy has the remembered bit set, but is not in the remembered table."
- manager setIsRememberedOf: copy to: false.
- scavenger remember: copy].
manager forward: obj to: (manager objectStartingAt: address).
^ copy!
Tom Braun uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog.seperateMarking-WoC.3303.mcz
==================== Summary ====================
Name: VMMaker.oscog.seperateMarking-WoC.3303
Author: WoC
Time: 12 January 2023, 11:43:30.923995 pm
UUID: b4c2b3e1-ea83-416b-9846-5eb06f6d112a
Ancestors: VMMaker.oscog.seperateMarking-eem.3302
assert segmentToFill is in the segments array and update segmentToFill when the segments array shifts position
=============== Diff against VMMaker.oscog.seperateMarking-eem.3302 ===============
Item was added:
+ ----- Method: SpurGarbageCollector>>noteReallocOfSegmentsArray: (in category 'as yet unclassified') -----
+ noteReallocOfSegmentsArray: aBlock
+
+ self shouldBeImplemented!
Item was added:
+ ----- Method: SpurIncrementalCompactingSweeper>>assertSegmentToFillIsInSegmentsArray (in category 'as yet unclassified') -----
+ assertSegmentToFillIsInSegmentsArray
+
+ | segInfo |
+ segmentToFill ifNil: [^ self].
+
+ segInfo := manager segInfoAt: manager numSegments - 1.
+
+ self assert: (manager segmentManager segments <= segmentToFill and: [segmentToFill <= segInfo]).
+
+ (manager segmentManager segments <= segmentToFill and: [segmentToFill <= segInfo])
+ ifFalse: [manager debugger]!
Item was changed:
----- Method: SpurIncrementalCompactingSweeper>>findAndSetSegmentToFill (in category 'segment to fill') -----
findAndSetSegmentToFill
<var: 'segInfo' type: #'SpurSegmentInfo *'>
| segInfo |
0 to: manager numSegments - 1
do: [:i |
segInfo := manager segInfoAt: i.
(self segmentIsEmpty: segInfo)
ifTrue: [segmentToFill := segInfo.
+ self assertSegmentToFillIsInSegmentsArray.
^ i]].
^ -1!
Item was changed:
----- Method: SpurIncrementalCompactingSweeper>>freePastSegmentsAndSetSegmentToFill (in category 'api') -----
freePastSegmentsAndSetSegmentToFill
"The first segment being claimed met becomes the segmentToFill. The others are just freed."
<var: 'segInfo' type: #'SpurSegmentInfo *'>
0 to: manager numSegments - 1 do:
[:i| | segInfo |
segInfo := manager segInfoAt: i.
(self wasSegmentsCompactionAborted: segInfo)
ifTrue: [ | freeUntil chunkBytes |
freeUntil := manager startOfObject: (self getEndOfCompaction: segInfo).
chunkBytes := freeUntil - segInfo segStart.
"maybe we could not even move one object out of the segment. Make sure we do not produce an invalid free chunk"
chunkBytes > 0
ifTrue: [coInterpreter
cr; print: 'partially freeing segment from: '; printHex: segInfo segStart;
print: ' to: '; printHex: freeUntil ;tab; flush.
manager
addFreeChunkWithBytes: chunkBytes
at: segInfo segStart]].
(self isSegmentBeingCompacted: segInfo) ifTrue:
[ | freeChunk chunkBytes |
self assert: (manager segmentManager allObjectsAreForwardedInSegment: segInfo includingFreeSpace: false).
self assert: (manager noElementOfFreeSpaceIsInSegment: segInfo).
coInterpreter
cr; print: 'freeing segment from: '; printHex: segInfo segStart;
print: ' to: '; printHex: segInfo segStart + segInfo segSize ;tab; flush.
chunkBytes := segInfo segSize - manager bridgeSize.
freeChunk := manager
addFreeChunkWithBytes: chunkBytes
at: segInfo segStart.
self unmarkSegmentAsBeingCompacted: segInfo.
segmentToFill ifNil:
[manager detachFreeObject: freeChunk.
+ segmentToFill := segInfo.
+ self assertSegmentToFillIsInSegmentsArray]]]!
- segmentToFill := segInfo]]]!
Item was changed:
----- Method: SpurIncrementalCompactingSweeper>>incrementalSweepAndCompact (in category 'api') -----
incrementalSweepAndCompact
scStartTime := coInterpreter ioUTCMicrosecondsNow.
self initIfNecessary.
+ self assertSegmentToFillIsInSegmentsArray.
+
"should in between sweeper calls segments be removed the index would not be correct anymore. Reset it here so we can be sure it is correct"
currentSegmentsIndex := manager segmentManager segmentIndexContainingObj: currentObject.
"if the bridge between segments was small before and the segment directly after the current one was removed the position of the bridge moved. Update
the current position to avoid this case"
currentSegmentsBridge := manager segmentManager bridgeAt: currentSegmentsIndex.
" so expensive :(
self assert: manager validObjectColors."
coInterpreter cr;
print: 'Starting up ';
printNum: coInterpreter ioUTCMicrosecondsNow - scStartTime ; tab.
self doincrementalSweepAndCompact
ifTrue: [self finishSweepAndCompact.
^ true].
"do not end on a bridge!! If a segment behind the current one currentObject is removed the size of the bridge can change from 8 bytes to 16 bytes and
therefore invalidating currentObject that is now pointing to the overflow header instad of the bridges body. To not hove to implement some finicky update
mechanism in the removal of segments just make sure we never reference the bridge before giving back the control to the mutator"
self assert: (manager isSegmentBridge: currentObject) not.
"skip empty segments. There is no work for us to do + they can be removed. As currentObject is always in the current segment
it won't be valid anymore"
self assert: (manager segmentManager isEmptySegment: self currentSegment) not.
coInterpreter cr; print: 'current position: '; printHex: currentObject; tab; flush.
^ false!
Item was changed:
----- Method: SpurIncrementalCompactingSweeper>>setSegmentToFillToAddress: (in category 'segment to fill') -----
setSegmentToFillToAddress: segInfo
"part of canReactToShiftSegment:to:. We cannot make any assertions, as the segment still has to be moved in the segments array
and right at this moment we do not point to the right address, but we will in a moment (see removeSegment: and canReactToShiftSegment:to: or insertSegmentFor: that brings us to this method to understand better)"
<var: 'segInfo' type: #'SpurSegmentInfo *'>
+ segmentToFill := segInfo.
+
+ self assertSegmentToFillIsInSegmentsArray!
- segmentToFill := segInfo!
Item was changed:
+ ----- Method: SpurIncrementalGarbageCollector>>canReactToShiftSegment:to: (in category 'compactor support') -----
- ----- Method: SpurIncrementalGarbageCollector>>canReactToShiftSegment:to: (in category 'as yet unclassified') -----
canReactToShiftSegment: segmentAddress to: anIndex
"because we have a pointer to segmentToFill changes in the segments array (where segmentToFill is pointing to) can
invalidate our pointer (it now points to an incorrect segment). Therefore react to this change and set the segmentToFill to
the new address"
segmentAddress = compactor segmentToFill
ifTrue: [
compactor setSegmentToFillToAddress: (manager segInfoAt: anIndex)]!
Item was added:
+ ----- Method: SpurIncrementalGarbageCollector>>noteReallocOfSegmentsArray: (in category 'compactor support') -----
+ noteReallocOfSegmentsArray: aBlock
+ "when the segments array gets bigger than a certain size it has to be resized, i.e. reallocated which can (probably will) move
+ the segments array to another location in memory. As the compactor sometimes holds a pointer to one of the elements of
+ this array we need to update the pointer in this case "
+
+ <inline: #always>
+ compactor segmentToFill
+ ifNil: [aBlock value]
+ ifNotNil: [| segmentToFillIndex |
+ segmentToFillIndex := manager segmentManager indexOfSegment: compactor segmentToFill.
+ aBlock value.
+ compactor setSegmentToFillToAddress: (manager segInfoAt: segmentToFillIndex)]!
Item was changed:
----- Method: SpurSegmentManager>>allocateOrExtendSegmentInfos (in category 'private') -----
allocateOrExtendSegmentInfos
"Increase the number of allocated segInfos by 16."
+
+ manager gc noteReallocOfSegmentsArray: [| newNumSegs |
+ numSegInfos = 0 ifTrue:
+ [numSegInfos := 16.
+ segments := self
+ cCode: [self calloc: numSegInfos _: (self sizeof: SpurSegmentInfo)]
+ inSmalltalk: [CArrayAccessor on: ((1 to: numSegInfos) collect: [:i| SpurSegmentInfo new])].
+ ^self].
+ newNumSegs := numSegInfos + 16.
+ segments := self
+ cCode: [self realloc: segments _: newNumSegs * (self sizeof: SpurSegmentInfo)]
+ inSmalltalk: [CArrayAccessor on: segments object,
+ ((numSegInfos to: newNumSegs) collect: [:i| SpurSegmentInfo new])].
+ self cCode:
+ [segments = 0 ifTrue:
+ [self error: 'out of memory; cannot allocate more segments'].
+ self
+ memset: segments + numSegInfos
+ _: 0
+ _: newNumSegs - numSegInfos * (self sizeof: SpurSegmentInfo)].
+ numSegInfos := newNumSegs]!
- | newNumSegs |
- numSegInfos = 0 ifTrue:
- [numSegInfos := 16.
- segments := self
- cCode: [self calloc: numSegInfos _: (self sizeof: SpurSegmentInfo)]
- inSmalltalk: [CArrayAccessor on: ((1 to: numSegInfos) collect: [:i| SpurSegmentInfo new])].
- ^self].
- newNumSegs := numSegInfos + 16.
- segments := self
- cCode: [self realloc: segments _: newNumSegs * (self sizeof: SpurSegmentInfo)]
- inSmalltalk: [CArrayAccessor on: segments object,
- ((numSegInfos to: newNumSegs) collect: [:i| SpurSegmentInfo new])].
- self cCode:
- [segments = 0 ifTrue:
- [self error: 'out of memory; cannot allocate more segments'].
- self
- memset: segments + numSegInfos
- _: 0
- _: newNumSegs - numSegInfos * (self sizeof: SpurSegmentInfo)].
- numSegInfos := newNumSegs!
Item was added:
+ ----- Method: SpurStopTheWorldGarbageCollector>>noteReallocOfSegmentsArray: (in category 'as yet unclassified') -----
+ noteReallocOfSegmentsArray: aBlock
+
+ <inline: #always>
+ aBlock value!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3292.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3292
Author: eem
Time: 12 January 2023, 1:22:56.040899 pm
UUID: 18300d37-96c7-4570-9b62-1660bd97f6f2
Ancestors: VMMaker.oscog-eem.3291
And update storeLiteralVariable:withValue: to match.
=============== Diff against VMMaker.oscog-eem.3291 ===============
Item was changed:
----- Method: StackInterpreter>>storeLiteralVariable:withValue: (in category 'stack bytecodes') -----
storeLiteralVariable: literalIndex withValue: anObject
| litVar |
+ "In Spur:
+ push/store/popLiteralVariable all fetch a literal, and either read or write the literal's value field.
+ The fetch of the literal needs an explicit check (otherwise we would have to scan all literals in
+ all methods in the stack zone, and the entire method on return, and global variables are relatively
+ rare; in my work image 8.7% of literals are globals)."
+ litVar := self followLiteral: literalIndex ofMethod: method.
- litVar := self literal: literalIndex.
- "push/store/popLiteralVariable all fetch a literal, and either read or write the literal's value field.
- The fetch of the literal needs an explicit check (otherwise we would have to scan all literals in
- all methods in the stack zone, and the entire method on return, and global variables are relatively
- rare; in my work image 8.7% of literals are globals)."
-
- (objectMemory isForwarded: litVar) ifTrue:
- [litVar := self unfollow: litVar atIndex: literalIndex].
objectMemory storePointerImmutabilityCheck: ValueIndex ofObject: litVar withValue: anObject!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3291.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3291
Author: eem
Time: 12 January 2023, 1:03:12.565231 pm
UUID: 815cbacd-2865-4024-987d-0b4974af3ed1
Ancestors: VMMaker.oscog-eem.3290
Merge VMMaker.oscog.seperateMarking-eem.3301
Given that better forwarding machinery was written over time, neaten StackInterpreter>>pushLiteralVariable: to use it. This is prompted by VMMaker.oscog.seperateMarking-eem.3300/VMMaker.oscog-eem.3290.
=============== Diff against VMMaker.oscog-eem.3290 ===============
Item was changed:
----- Method: StackInterpreter>>pushLiteralVariable: (in category 'stack bytecodes') -----
pushLiteralVariable: literalIndex
+ | litVar |
+ "In Spur:
+ push/store/popLiteralVariable all fetch a literal, and either read or write the literal's value field.
+ The fetch of the literal needs an explicit check (otherwise we would have to scan all literals in
+ all methods in the stack zone, and the entire method on return, and global variables are relatively
+ rare; in my work image 8.7% of literals are globals)."
+ litVar := self followLiteral: literalIndex ofMethod: method.
+ self internalPush: (objectMemory fetchPointer: ValueIndex ofObject: litVar)!
- objectMemory hasSpurMemoryManagerAPI
- ifTrue:
- [| litVar |
- "push/store/popLiteralVariable all fetch a literal, and either read or write the literal's value field.
- The fetch of the literal needs an explicit check (otherwise we would have to scan all literals in
- all methods in the stack zone, and the entire method on return, and global variables are relatively
- rare; in my work image 8.7% of literals are globals)."
- litVar := self literal: literalIndex.
- (objectMemory isForwarded: litVar) ifTrue:
- [litVar := self unfollow: litVar atIndex: literalIndex].
- self internalPush:
- (objectMemory fetchPointer: ValueIndex ofObject: litVar)]
- ifFalse:
- [self internalPush:
- (objectMemory fetchPointer: ValueIndex ofObject: (self literal: literalIndex))]!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog.seperateMarking-eem.3301.mcz
==================== Summary ====================
Name: VMMaker.oscog.seperateMarking-eem.3301
Author: eem
Time: 12 January 2023, 12:45:06.067847 pm
UUID: 42a7426f-a347-409b-9e2c-911d651d009c
Ancestors: VMMaker.oscog.seperateMarking-eem.3300
Given that better forwarding machinery was written over time, neaten StackInterpreter>>pushLiteralVariable: to use it. This is prompted by VMMaker.oscog.seperateMarking-eem.3300.
=============== Diff against VMMaker.oscog.seperateMarking-eem.3298 ===============
Item was changed:
----- Method: StackInterpreter>>pushLiteralVariable: (in category 'stack bytecodes') -----
pushLiteralVariable: literalIndex
+ | litVar |
+ "In Spur:
+ push/store/popLiteralVariable all fetch a literal, and either read or write the literal's value field.
+ The fetch of the literal needs an explicit check (otherwise we would have to scan all literals in
+ all methods in the stack zone, and the entire method on return, and global variables are relatively
+ rare; in my work image 8.7% of literals are globals)."
+ litVar := self followLiteral: literalIndex ofMethod: method.
+ self internalPush: (objectMemory fetchPointer: ValueIndex ofObject: litVar)!
- objectMemory hasSpurMemoryManagerAPI
- ifTrue:
- [| litVar |
- "push/store/popLiteralVariable all fetch a literal, and either read or write the literal's value field.
- The fetch of the literal needs an explicit check (otherwise we would have to scan all literals in
- all methods in the stack zone, and the entire method on return, and global variables are relatively
- rare; in my work image 8.7% of literals are globals)."
- litVar := self literal: literalIndex.
- (objectMemory isForwarded: litVar) ifTrue:
- [litVar := self unfollow: litVar atIndex: literalIndex].
- self internalPush:
- (objectMemory fetchPointer: ValueIndex ofObject: litVar)]
- ifFalse:
- [self internalPush:
- (objectMemory fetchPointer: ValueIndex ofObject: (self literal: literalIndex))]!
Item was removed:
- ----- Method: TMethod>>checkForRequiredInlinability (in category 'testing') -----
- checkForRequiredInlinability
- "This is used in methods answering inlinability.
- Always answer false. But if the receiver is marked as something that must be inlined (inline == #always) raise an error."
- (inline == #always and: [complete]) ifTrue:
- [self error: 'cannot inline method ', selector, ' marked as <inline: #always>'].
- ^false!
Item was added:
+ ----- Method: TMethod>>checkForRequiredInlinabilityIn: (in category 'testing') -----
+ checkForRequiredInlinabilityIn: aMethod
+ "This is used in methods answering inlinability.
+ Always answer false. But if the receiver is marked as something that must be inlined (inline == #always) raise an error."
+ (inline == #always and: [complete]) ifTrue:
+ [self error: 'cannot inline method ', selector, ' marked as <inline: #always> into: ', aMethod asString].
+ ^false!
Item was changed:
----- Method: TMethod>>inlineableFunctionCall:in: (in category 'inlining') -----
inlineableFunctionCall: aNode in: aCodeGen
"Answer if the given send node is a call to a 'functional' method--a method whose body is a single return statement of some expression and whose actual parameters can all be directly substituted."
aCodeGen maybeBreakForTestToInline: aNode in: self.
aNode isSend ifFalse:
[^false].
((aCodeGen shouldGenerateAsInterpreterProxySend: aNode)
or: [aCodeGen isStructSend: aNode]) ifTrue:
[^false].
^(aCodeGen methodNamed: aNode selector)
ifNil:
[aNode asTransformedConstantPerform
ifNil: [self isInlineableConditional: aNode in: aCodeGen]
ifNotNil: [:n| self inlineableFunctionCall: n in: aCodeGen]]
ifNotNil:
[:m|
(m ~~ self
and: [((m isFunctionalIn: aCodeGen) or: [m mustBeInlined and: [m isComplete]])
and: [m mayBeInlined
and: [(aCodeGen mayInline: m selector)
and: [aNode args allSatisfy: [:a| self isSubstitutableNode: a intoMethod: m in: aCodeGen]]]]])
+ or: [m checkForRequiredInlinabilityIn: self]]!
- or: [m checkForRequiredInlinability]]!
Item was changed:
----- Method: TMethod>>inlineableSend:in: (in category 'inlining') -----
inlineableSend: aNode in: aCodeGen
"Answer if the given send node is a call to a method that can be inlined."
| m |
aCodeGen maybeBreakForTestToInline: aNode in: self.
aNode isSend ifFalse: [^false].
m := aCodeGen methodNamed: aNode selector. "nil if builtin or external function"
^m ~= nil
and: [m ~~ self
and: [m unmodifiedSelector ~= self unmodifiedSelector
and: [m mayBeInlined
and: [(m isComplete and: [aCodeGen mayInline: m selector])
+ or: [m checkForRequiredInlinabilityIn: self]]]]]!
- or: [m checkForRequiredInlinability]]]]]!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog.seperateMarking-eem.3298.mcz
==================== Summary ====================
Name: VMMaker.oscog.seperateMarking-eem.3298
Author: eem
Time: 12 January 2023, 12:18:14.125099 pm
UUID: ad8f08f9-a95a-41cd-a29b-802277030e3a
Ancestors: VMMaker.oscog.seperateMarking-WoC.3297
Merge VMMaker.oscog-eem.3290:
Use a slightly better form for dealing with potential forwarding in the pushFullClosure bytecode.
=============== Diff against VMMaker.oscog.seperateMarking-WoC.3297 ===============
Item was changed:
----- Method: StackInterpreter>>extPushFullClosureBytecode (in category 'stack bytecodes') -----
extPushFullClosureBytecode
"255 11111111 xxxxxxxx siyyyyyy
push Closure Compiled block literal index xxxxxxxx (+ Extend A * 256)
numCopied yyyyyy
receiverOnStack: s = 1
ignoreOuterContext: i = 1
The compiler has pushed the values to be copied, if any. The receiver has been pushed on stack before if specified.
Create a Closure with space for the copiedValues and pop numCopied values off the stack into the closure.
Sets outerContext, compiledBlock, numArgs and receiver as specified.."
| compiledBlockLiteralIndex compiledBlock byte numArgs numCopied receiverIsOnStack ignoreContext |
compiledBlockLiteralIndex := self fetchByte + (extA << 8).
extA := 0.
+ compiledBlock := self followLiteral: compiledBlockLiteralIndex ofMethod: method.
- compiledBlock := self literal: compiledBlockLiteralIndex.
self assert: (objectMemory isOopCompiledMethod: compiledBlock).
numArgs := self argumentCountOf: compiledBlock.
byte := self fetchByte.
numCopied := byte bitAnd: 1<< 6 - 1.
receiverIsOnStack := byte anyMask: 1 << 7.
ignoreContext := byte anyMask: 1 << 6.
self pushFullClosureNumArgs: numArgs copiedValues: numCopied compiledBlock: compiledBlock receiverIsOnStack: receiverIsOnStack ignoreContext: ignoreContext!
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3290.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3290
Author: eem
Time: 12 January 2023, 12:15:15.665547 pm
UUID: 32a7e113-db4f-49be-889c-3b889248f0b6
Ancestors: VMMaker.oscog-eem.3289
Use a slightly better form for dealing with potential forwarding in the pushFullClosure bytecode.
=============== Diff against VMMaker.oscog-eem.3289 ===============
Item was changed:
----- Method: StackInterpreter>>extPushFullClosureBytecode (in category 'stack bytecodes') -----
extPushFullClosureBytecode
"255 11111111 xxxxxxxx siyyyyyy
push Closure Compiled block literal index xxxxxxxx (+ Extend A * 256)
numCopied yyyyyy
receiverOnStack: s = 1
ignoreOuterContext: i = 1
The compiler has pushed the values to be copied, if any. The receiver has been pushed on stack before if specified.
Create a Closure with space for the copiedValues and pop numCopied values off the stack into the closure.
Sets outerContext, compiledBlock, numArgs and receiver as specified.."
| compiledBlockLiteralIndex compiledBlock byte numArgs numCopied receiverIsOnStack ignoreContext |
compiledBlockLiteralIndex := self fetchByte + (extA << 8).
extA := 0.
+ compiledBlock := self followLiteral: compiledBlockLiteralIndex ofMethod: method.
- compiledBlock := objectMemory followMaybeForwarded: (self literal: compiledBlockLiteralIndex).
self assert: (objectMemory isOopCompiledMethod: compiledBlock).
numArgs := self argumentCountOf: compiledBlock.
byte := self fetchByte.
numCopied := byte bitAnd: 1<< 6 - 1.
receiverIsOnStack := byte anyMask: 1 << 7.
ignoreContext := byte anyMask: 1 << 6.
self pushFullClosureNumArgs: numArgs copiedValues: numCopied compiledBlock: compiledBlock receiverIsOnStack: receiverIsOnStack ignoreContext: ignoreContext!