[Vm-dev] VM Maker: VMMaker.oscog-rsf.2077.mcz

Eliot Miranda eliot.miranda at gmail.com
Mon Jan 9 01:35:38 UTC 2017


Hi Ronie,

On Sun, Jan 8, 2017 at 2:48 PM, Ronie Salgado <roniesalg at gmail.com> wrote:

>
> Hello,
>
> This time I applied the suggestion made by Nicolas Cellier for this bug. I
> also tested with the Newspeak bootstrapping system and tests in 32 bits
> Linux. I got the same number of successful, failing and passing tests as
> the CI log available at: https://travis-ci.org/
> newspeaklanguage/bootimage-ci/jobs/189887252 . Hopefully this is not
> breaking Newspeak again.
>
> However, similar changes are required to EncoderForNewsqueakV4 >>
> #extensionsAt:in:into: and EncoderFoSistaV1 >> #extensionsAt:in:into:, for
> these methods to correctly decode the extB extensions.
>

Excellent, thank you!  And thank you Nicolas!   I'll get to these two
tomorrow (unless you beat me to it).


>
> 2017-01-08 19:40 GMT-03:00 <commits at source.squeak.org>:
>
>>
>> Ronie Salgado Faila uploaded a new version of VMMaker to project VM Maker:
>> http://source.squeak.org/VMMaker/VMMaker.oscog-rsf.2077.mcz
>>
>> ==================== Summary ====================
>>
>> Name: VMMaker.oscog-rsf.2077
>> Author: rsf
>> Time: 8 January 2017, 5:41:56.129158 pm
>> UUID: d009eb6f-01c9-4fb4-b022-2f73c6e8ca5c
>> Ancestors: VMMaker.oscog-eem.2076
>>
>> ExtB 00000000 1xxxxxxx constant decoding bug fix.
>>
>> =============== Diff against VMMaker.oscog-eem.2076 ===============
>>
>> Item was changed:
>>   CogClass subclass: #Cogit
>> +       instanceVariableNames: 'coInterpreter objectMemory
>> objectRepresentation processor threadManager methodZone methodZoneBase
>> codeBase minValidCallAddress lastNInstructions simulatedAddresses
>> simulatedTrampolines simulatedVariableGetters simulatedVariableSetters
>> printRegisters printInstructions compilationTrace clickConfirm breakPC
>> breakBlock singleStep guardPageSize traceFlags traceStores breakMethod
>> methodObj enumeratingCogMethod methodHeader initialPC endPC
>> methodOrBlockNumArgs inBlock needsFrame hasYoungReferent primitiveIndex
>> backEnd literalsManager postCompileHook methodLabel stackCheckLabel
>> blockEntryLabel blockEntryNoContextSwitch blockNoContextSwitchOffset
>> stackOverflowCall sendMiss missOffset entryPointMask checkedEntryAlignment
>> uncheckedEntryAlignment cmEntryOffset entry cmNoCheckEntryOffset
>> noCheckEntry fullBlockEntry cbEntryOffset fullBlockNoContextSwitchEntry
>> cbNoSwitchEntryOffset picMNUAbort picInterpretAbort endCPICCase0
>> endCPICCase1 firstCPICCaseOffset cPICCaseSize cP
>>  ICEndSize closedPICSize openPICSize fixups abstractOpcodes
>> generatorTable byte0 byte1 byte2 byte3 bytecodePC bytecodeSetOffset
>> opcodeIndex numAbstractOpcodes blockStarts blockCount labelCounter
>> cStackAlignment expectedSPAlignment expectedFPAlignment codeModified
>> maxLitIndex ceMethodAbortTrampoline cePICAbortTrampoline
>> ceCheckForInterruptTrampoline ceCPICMissTrampoline
>> ceReturnToInterpreterTrampoline ceBaseFrameReturnTrampoline
>> ceSendMustBeBooleanAddTrueTrampoline ceSendMustBeBooleanAddFalseTrampoline
>> ceCannotResumeTrampoline ceEnterCogCodePopReceiverReg
>> ceCallCogCodePopReceiverReg ceCallCogCodePopReceiverAndClassRegs
>> cePrimReturnEnterCogCode cePrimReturnEnterCogCodeProfiling
>> ceNonLocalReturnTrampoline ceFetchContextInstVarTrampoline
>> ceStoreContextInstVarTrampoline ceEnclosingObjectTrampoline
>> ceFlushICache ceCheckFeaturesFunction ceTraceLinkedSendTrampoline
>> ceTraceBlockActivationTrampoline ceTraceStoreTrampoline ceGetFP ceGetSP
>> ceCaptureCStackPointers ordinarySendTrampolines superSen
>>  dTrampolines directedSuperSendTrampolines dynamicSuperSendTrampolines
>> outerSendTrampolines selfSendTrampolines firstSend lastSend
>> realCEEnterCogCodePopReceiverReg realCECallCogCodePopReceiverReg
>> realCECallCogCodePopReceiverAndClassRegs trampolineTableIndex
>> trampolineAddresses objectReferencesInRuntime runtimeObjectRefIndex
>> cFramePointerInUse debugPrimCallStackOffset ceTryLockVMOwner
>> ceUnlockVMOwner extA extB numExtB tempOop numIRCs indexOfIRC theIRCs
>> implicitReceiverSendTrampolines cogMethodSurrogateClass
>> cogBlockMethodSurrogateClass nsSendCacheSurrogateClass CStackPointer
>> CFramePointer cPICPrototype cPICEndOfCodeOffset cPICEndOfCodeLabel
>> maxCPICCases debugBytecodePointers debugOpcodeIndices disassemblingMethod
>> ceMallocTrampoline ceFreeTrampoline ceFFICalloutTrampoline'
>> -       instanceVariableNames: 'coInterpreter objectMemory
>> objectRepresentation processor threadManager methodZone methodZoneBase
>> codeBase minValidCallAddress lastNInstructions simulatedAddresses
>> simulatedTrampolines simulatedVariableGetters simulatedVariableSetters
>> printRegisters printInstructions compilationTrace clickConfirm breakPC
>> breakBlock singleStep guardPageSize traceFlags traceStores breakMethod
>> methodObj enumeratingCogMethod methodHeader initialPC endPC
>> methodOrBlockNumArgs inBlock needsFrame hasYoungReferent primitiveIndex
>> backEnd literalsManager postCompileHook methodLabel stackCheckLabel
>> blockEntryLabel blockEntryNoContextSwitch blockNoContextSwitchOffset
>> stackOverflowCall sendMiss missOffset entryPointMask checkedEntryAlignment
>> uncheckedEntryAlignment cmEntryOffset entry cmNoCheckEntryOffset
>> noCheckEntry fullBlockEntry cbEntryOffset fullBlockNoContextSwitchEntry
>> cbNoSwitchEntryOffset picMNUAbort picInterpretAbort endCPICCase0
>> endCPICCase1 firstCPICCaseOffset cPICCaseSize cP
>>  ICEndSize closedPICSize openPICSize fixups abstractOpcodes
>> generatorTable byte0 byte1 byte2 byte3 bytecodePC bytecodeSetOffset
>> opcodeIndex numAbstractOpcodes blockStarts blockCount labelCounter
>> cStackAlignment expectedSPAlignment expectedFPAlignment codeModified
>> maxLitIndex ceMethodAbortTrampoline cePICAbortTrampoline
>> ceCheckForInterruptTrampoline ceCPICMissTrampoline
>> ceReturnToInterpreterTrampoline ceBaseFrameReturnTrampoline
>> ceSendMustBeBooleanAddTrueTrampoline ceSendMustBeBooleanAddFalseTrampoline
>> ceCannotResumeTrampoline ceEnterCogCodePopReceiverReg
>> ceCallCogCodePopReceiverReg ceCallCogCodePopReceiverAndClassRegs
>> cePrimReturnEnterCogCode cePrimReturnEnterCogCodeProfiling
>> ceNonLocalReturnTrampoline ceFetchContextInstVarTrampoline
>> ceStoreContextInstVarTrampoline ceEnclosingObjectTrampoline
>> ceFlushICache ceCheckFeaturesFunction ceTraceLinkedSendTrampoline
>> ceTraceBlockActivationTrampoline ceTraceStoreTrampoline ceGetFP ceGetSP
>> ceCaptureCStackPointers ordinarySendTrampolines superSen
>>  dTrampolines directedSuperSendTrampolines dynamicSuperSendTrampolines
>> outerSendTrampolines selfSendTrampolines firstSend lastSend
>> realCEEnterCogCodePopReceiverReg realCECallCogCodePopReceiverReg
>> realCECallCogCodePopReceiverAndClassRegs trampolineTableIndex
>> trampolineAddresses objectReferencesInRuntime runtimeObjectRefIndex
>> cFramePointerInUse debugPrimCallStackOffset ceTryLockVMOwner
>> ceUnlockVMOwner extA extB tempOop numIRCs indexOfIRC theIRCs
>> implicitReceiverSendTrampolines cogMethodSurrogateClass
>> cogBlockMethodSurrogateClass nsSendCacheSurrogateClass CStackPointer
>> CFramePointer cPICPrototype cPICEndOfCodeOffset cPICEndOfCodeLabel
>> maxCPICCases debugBytecodePointers debugOpcodeIndices disassemblingMethod
>> ceMallocTrampoline ceFreeTrampoline ceFFICalloutTrampoline'
>>         classVariableNames: 'AltBlockCreationBytecodeSize
>> AltFirstSpecialSelector AltNSSendIsPCAnnotated AltNumSpecialSelectors
>> AnnotationConstantNames AnnotationShift AnnotationsWithBytecodePCs
>> BlockCreationBytecodeSize Debug DisplacementMask DisplacementX2N
>> EagerInstructionDecoration FirstAnnotation FirstSpecialSelector
>> HasBytecodePC IsAbsPCReference IsAnnotationExtension IsDirectedSuperSend
>> IsDisplacementX2N IsNSDynamicSuperSend IsNSImplicitReceiverSend
>> IsNSSelfSend IsNSSendCall IsObjectReference IsRelativeCall IsSendCall
>> IsSuperSend MapEnd MaxCPICCases MaxCompiledPrimitiveIndex MaxStackAllocSize
>> MaxX2NDisplacement NSCClassTagIndex NSCEnclosingObjectIndex NSCNumArgsIndex
>> NSCSelectorIndex NSCTargetIndex NSSendIsPCAnnotated NeedsFixupFlag
>> NumObjRefsInRuntime NumOopsPerNSC NumSpecialSelectors NumTrampolines
>> ProcessorClass RRRName'
>>         poolDictionaries: 'CogAbstractRegisters CogCompilationConstants
>> CogMethodConstants CogRTLOpcodes VMBasicConstants VMBytecodeConstants
>> VMObjectIndices VMStackFrameOffsets'
>>         category: 'VMMaker-JIT'!
>>   Cogit class
>>         instanceVariableNames: 'generatorTable primitiveTable'!
>>
>>   !Cogit commentStamp: 'eem 4/6/2015 15:56' prior: 0!
>>   I am the code generator for the Cog VM.  My job is to produce machine
>> code versions of methods for faster execution and to manage inline caches
>> for faster send performance.  I can be tested in the current image using my
>> class-side in-image compilation facilities.  e.g. try
>>
>>         StackToRegisterMappingCogit genAndDis: (Integer >> #benchFib)
>>
>>   I have concrete subclasses that implement different levels of
>> optimization:
>>         SimpleStackBasedCogit is the simplest code generator.
>>
>>         StackToRegisterMappingCogit is the current production code
>> generator  It defers pushing operands
>>         to the stack until necessary and implements a register-based
>> calling convention for low-arity sends.
>>
>>         StackToRegisterMappingCogit is an experimental code generator
>> with support for counting
>>         conditional branches, intended to support adaptive optimization.
>>
>>   coInterpreter <CoInterpreterSimulator>
>>         the VM's interpreter with which I cooperate
>>   methodZoneManager <CogMethodZoneManager>
>>         the manager of the machine code zone
>>   objectRepresentation <CogObjectRepresentation>
>>         the object used to generate object accesses
>>   processor <BochsIA32Alien|?>
>>         the simulator that executes the IA32/x86 machine code I generate
>> when simulating execution in Smalltalk
>>   simulatedTrampolines <Dictionary of Integer -> MessageSend>
>>         the dictionary mapping trap jump addresses to run-time routines
>> used to warp from simulated machine code in to the Smalltalk run-time.
>>   simulatedVariableGetters <Dictionary of Integer -> MessageSend>
>>         the dictionary mapping trap read addresses to variables in
>> run-time objects used to allow simulated machine code to read variables in
>> the Smalltalk run-time.
>>   simulatedVariableSetters <Dictionary of Integer -> MessageSend>
>>         the dictionary mapping trap write addresses to variables in
>> run-time objects used to allow simulated machine code to write variables in
>> the Smalltalk run-time.
>>   printRegisters printInstructions clickConfirm <Boolean>
>>         flags controlling debug printing and code simulation
>>   breakPC <Integer>
>>         machine code pc breakpoint
>>   cFramePointer cStackPointer <Integer>
>>         the variables representing the C stack & frame pointers, which
>> must change on FFI callback and return
>>   selectorOop <sqInt>
>>         the oop of the methodObj being compiled
>>   methodObj <sqInt>
>>         the bytecode method being compiled
>>   initialPC endPC <Integer>
>>         the start and end pcs of the methodObj being compiled
>>   methodOrBlockNumArgs <Integer>
>>         argument count of current method or block being compiled
>>   needsFrame <Boolean>
>>         whether methodObj or block needs a frame to execute
>>   primitiveIndex <Integer>
>>         primitive index of current method being compiled
>>   methodLabel <CogAbstractOpcode>
>>         label for the method header
>>   blockEntryLabel <CogAbstractOpcode>
>>         label for the start of the block dispatch code
>>   stackOverflowCall <CogAbstractOpcode>
>>         label for the call of ceStackOverflow in the method prolog
>>   sendMissCall <CogAbstractOpcode>
>>         label for the call of ceSICMiss in the method prolog
>>   entryOffset <Integer>
>>         offset of method entry code from start (header) of method
>>   entry <CogAbstractOpcode>
>>         label for the first instruction of the method entry code
>>   noCheckEntryOffset <Integer>
>>         offset of the start of a method proper (after the method entry
>> code) from start (header) of method
>>   noCheckEntry <CogAbstractOpcode>
>>         label for the first instruction of start of a method proper
>>   fixups <Array of <AbstractOpcode Label | nil>>
>>         the labels for forward jumps that will be fixed up when reaching
>> the relevant bytecode.  fixup shas one element per byte in methodObj's
>> bytecode
>>   abstractOpcodes <Array of <AbstractOpcode>>
>>         the code generated when compiling methodObj
>>   byte0 byte1 byte2 byte3 <Integer>
>>         individual bytes of current bytecode being compiled in methodObj
>>   bytecodePointer <Integer>
>>         bytecode pc (same as Smalltalk) of the current bytecode being
>> compiled
>>   opcodeIndex <Integer>
>>         the index of the next free entry in abstractOpcodes (this code is
>> translated into C where OrderedCollection et al do not exist)
>>   numAbstractOpcodes <Integer>
>>         the number of elements in abstractOpcocdes
>>   blockStarts <Array of <BlockStart>>
>>         the starts of blocks in the current method
>>   blockCount
>>         the index into blockStarts as they are being noted, and hence
>> eventually the total number of blocks in the current method
>>   labelCounter <Integer>
>>         a nicety for numbering labels not needed in the production system
>> but probably not expensive enough to worry about
>>   ceStackOverflowTrampoline <Integer>
>>   ceSend0ArgsTrampoline <Integer>
>>   ceSend1ArgsTrampoline <Integer>
>>   ceSend2ArgsTrampoline <Integer>
>>   ceSendNArgsTrampoline <Integer>
>>   ceSendSuper0ArgsTrampoline <Integer>
>>   ceSendSuper1ArgsTrampoline <Integer>
>>   ceSendSuper2ArgsTrampoline <Integer>
>>   ceSendSuperNArgsTrampoline <Integer>
>>   ceSICMissTrampoline <Integer>
>>   ceCPICMissTrampoline <Integer>
>>   ceStoreCheckTrampoline <Integer>
>>   ceReturnToInterpreterTrampoline <Integer>
>>   ceBaseFrameReturnTrampoline <Integer>
>>   ceSendMustBeBooleanTrampoline <Integer>
>>   ceClosureCopyTrampoline <Integer>
>>         the various trampolines (system-call-like jumps from machine code
>> to the run-time).
>>         See Cogit>>generateTrampolines for the mapping from trampoline to
>> run-time
>>         routine and then read the run-time routine for a funcitonal
>> description.
>>   ceEnterCogCodePopReceiverReg <Integer>
>>         the enilopmart (jump from run-time to machine-code)
>>   methodZoneBase <Integer>
>>   !
>>   Cogit class
>>         instanceVariableNames: 'generatorTable primitiveTable'!
>>
>> Item was changed:
>>   ----- Method: Cogit>>assertExtsAreConsumed: (in category 'compile
>> abstract instructions') -----
>>   assertExtsAreConsumed: descriptor
>>          "extended bytecodes must consume their extensions"
>>          <inline: true>
>>          descriptor isExtension ifFalse:
>> +               [self assert: (extA = 0 and: [extB = 0 and: [numExtB =
>> 0]])].!
>> -               [self assert: (extA = 0 and: [extB = 0])].!
>>
>> Item was changed:
>>   ----- Method: Cogit>>extBBytecode (in category 'bytecode generators')
>> -----
>>   extBBytecode
>>         "225            11100001        sbbbbbbb        Extend B (Ext B =
>> Ext B prev * 256 + Ext B)"
>> +       extB := (numExtB = 0 and: [byte1 > 127])
>> -       extB := (extB = 0 and: [byte1 > 127])
>>                                 ifTrue: [byte1 - 256]
>>                                 ifFalse: [(extB bitShift: 8) + byte1].
>> +       numExtB := numExtB + 1.
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: Cogit>>nextDescriptorAndExtensionsInto: (in category
>> 'bytecode generator support') -----
>>   nextDescriptorAndExtensionsInto: aTrinaryBlock
>>         "Peek ahead and deliver the next descriptor plus extension bytes."
>>         <inline: true>
>> +       | savedB0 savedB1 savedB2 savedB3 savedEA savedEB savedNEB
>> descriptor bcpc |
>> -       | savedB0 savedB1 savedB2 savedB3 savedEA savedEB descriptor bcpc
>> |
>>         <var: #descriptor type: #'BytecodeDescriptor *'>
>>         descriptor := self generatorAt: byte0.
>>         savedB0 := byte0. savedB1 := byte1. savedB2 := byte2. savedB3 :=
>> byte3.
>> +       savedEA := extA. savedEB := extB. savedNEB := numExtB.
>> -       savedEA := extA. savedEB := extB.
>>         bcpc := bytecodePC + descriptor numBytes.
>>         [bcpc > endPC ifTrue:
>>                 [^aTrinaryBlock value: nil value: 0 value: 0].
>>          byte0 := (objectMemory fetchByte: bcpc ofObject: methodObj)  +
>> bytecodeSetOffset.
>>          descriptor := self generatorAt: byte0.
>>          self loadSubsequentBytesForDescriptor: descriptor at: bcpc.
>>          descriptor isExtension ifFalse:
>>                 [| eA eB |
>>                  eA := extA. eB := extB.
>> +                extA := savedEA. extB := savedEB. numExtB := savedNEB.
>> -                extA := savedEA. extB := savedEB.
>>                  byte0 := savedB0. byte1 := savedB1. byte2 := savedB2.
>> byte3 := savedB3.
>>                  ^aTrinaryBlock value: descriptor value: eA value: eB].
>>          self perform: descriptor generator.
>>          bcpc := bcpc + descriptor numBytes.
>>          true] whileTrue!
>>
>> Item was changed:
>>   ----- Method: Cogit>>scanBlock: (in category 'compile abstract
>> instructions') -----
>>   scanBlock: blockStart
>>         "Scan the block to determine if the block needs a frame or not"
>>         | descriptor pc end framelessStackDelta nExts |
>>         <var: #blockStart type: #'BlockStart *'>
>>         <var: #descriptor type: #'BytecodeDescriptor *'>
>>         needsFrame := false.
>>         methodOrBlockNumArgs := blockStart numArgs.
>>         inBlock := InVanillaBlock.
>>         pc := blockStart startpc.
>>         end := blockStart startpc + blockStart span.
>> +       framelessStackDelta := nExts := extA := numExtB := extB := 0.
>> -       framelessStackDelta := nExts := extA := extB := 0.
>>         [pc < end] whileTrue:
>>                 [byte0 := (objectMemory fetchByte: pc ofObject:
>> methodObj) + bytecodeSetOffset.
>>                  descriptor := self generatorAt: byte0.
>>                  descriptor isExtension ifTrue:
>>                         [self loadSubsequentBytesForDescriptor:
>> descriptor at: pc.
>>                          self perform: descriptor generator].
>>                  needsFrame ifFalse:
>>                         [(descriptor needsFrameFunction isNil
>>                           or: [self perform: descriptor
>> needsFrameFunction with: framelessStackDelta])
>>                                 ifTrue: [needsFrame := true]
>>                                 ifFalse: [framelessStackDelta :=
>> framelessStackDelta + descriptor stackDelta]].
>>                  objectRepresentation maybeNoteDescriptor: descriptor
>> blockStart: blockStart.
>>                  pc := self nextBytecodePCFor: descriptor at: pc exts:
>> nExts in: methodObj.
>>                  descriptor isExtension
>>                         ifTrue: [nExts := nExts + 1]
>> +                       ifFalse: [nExts := extA := numExtB := 0. extB :=
>> 0]].
>> -                       ifFalse: [nExts := extA := extB := 0]].
>>         needsFrame ifFalse:
>>                 [framelessStackDelta < 0 ifTrue:
>>                         [self error: 'negative stack delta in block;
>> block contains bogus code or internal error'].
>>                  [framelessStackDelta > 0] whileTrue:
>>                         [descriptor := self generatorAt: (objectMemory
>> fetchByte: blockStart startpc ofObject: methodObj) + bytecodeSetOffset.
>>                          descriptor generator ~~
>> #genPushConstantNilBytecode ifTrue:
>>                                 [self error: 'frameless block doesn''t
>> start with enough pushNils'].
>>                          blockStart
>>                                 startpc: blockStart startpc + descriptor
>> numBytes;
>>                                 span: blockStart span - descriptor
>> numBytes.
>>                          framelessStackDelta := framelessStackDelta - 1]].
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: Cogit>>scanMethod (in category 'compile abstract
>> instructions') -----
>>   scanMethod
>>         "Scan the method (and all embedded blocks) to determine
>>                 - what the last bytecode is; extra bytes at the end of a
>> method are used to encode things like source pointers or temp names
>>                 - if the method needs a frame or not
>>                 - what are the targets of any backward branches.
>>                 - how many blocks it creates
>>                 - if it contans an unknown bytecode
>>          Answer the block count or on error a negative error code"
>>         | latestContinuation nExts descriptor pc numBlocks distance
>> targetPC framelessStackDelta |
>>         <var: #descriptor type: #'BytecodeDescriptor *'>
>>         needsFrame := false.
>>         NewspeakVM ifTrue:
>>                 [numIRCs := 0].
>>         (primitiveIndex > 0
>>          and: [coInterpreter isQuickPrimitiveIndex: primitiveIndex])
>> ifTrue:
>>                 [^0].
>>         pc := latestContinuation := initialPC.
>> +       numBlocks := framelessStackDelta := nExts := extA := numExtB :=
>> extB := 0.
>> -       numBlocks := framelessStackDelta := nExts := extA := extB := 0.
>>         [pc <= endPC] whileTrue:
>>                 [byte0 := (objectMemory fetchByte: pc ofObject:
>> methodObj) + bytecodeSetOffset.
>>                  descriptor := self generatorAt: byte0.
>>                  descriptor isExtension ifTrue:
>>                         [descriptor opcode = Nop ifTrue: "unknown
>> bytecode tag; see Cogit class>>#generatorTableFrom:"
>>                                 [^EncounteredUnknownBytecode].
>>                          self loadSubsequentBytesForDescriptor:
>> descriptor at: pc.
>>                          self perform: descriptor generator].
>>                  (descriptor isReturn
>>                   and: [pc >= latestContinuation]) ifTrue:
>>                         [endPC := pc].
>>                  needsFrame ifFalse:
>>                         [(descriptor needsFrameFunction isNil
>>                           or: [self perform: descriptor
>> needsFrameFunction with: framelessStackDelta])
>>                                 ifTrue: [needsFrame := true]
>>                                 ifFalse: [framelessStackDelta :=
>> framelessStackDelta + descriptor stackDelta]].
>>                  descriptor isBranch ifTrue:
>>                         [distance := self spanFor: descriptor at: pc
>> exts: nExts in: methodObj.
>>                          targetPC := pc + descriptor numBytes + distance.
>>                          (self isBackwardBranch: descriptor at: pc exts:
>> nExts in: methodObj)
>>                                 ifTrue: [self initializeFixupAt: targetPC
>> - initialPC]
>>                                 ifFalse: [latestContinuation :=
>> latestContinuation max: targetPC]].
>>                  descriptor isBlockCreation ifTrue:
>>                         [numBlocks := numBlocks + 1.
>>                          distance := self spanFor: descriptor at: pc
>> exts: nExts in: methodObj.
>>                          targetPC := pc + descriptor numBytes + distance.
>>                          latestContinuation := latestContinuation max:
>> targetPC].
>>                  NewspeakVM ifTrue:
>>                         [descriptor hasIRC ifTrue:
>>                                 [numIRCs := numIRCs + 1]].
>>                  pc := pc + descriptor numBytes.
>>                  descriptor isExtension
>>                         ifTrue: [nExts := nExts + 1]
>> +                       ifFalse: [nExts := extA := numExtB := extB := 0]].
>> -                       ifFalse: [nExts := extA := extB := 0]].
>>         ^numBlocks!
>>
>> Item was changed:
>>   ----- Method: Cogit>>setInterpreter: (in category 'initialization')
>> -----
>>   setInterpreter: aCoInterpreter
>>         "Initialization of the code generator in the simulator.
>>          These objects already exist in the generated C VM
>>          or are used only in the simulation."
>>         <doNotGenerate>
>>         coInterpreter := aCoInterpreter.
>>         objectMemory := aCoInterpreter objectMemory.
>>         threadManager := aCoInterpreter threadManager. "N.B. may be nil"
>>         methodZone := CogMethodZone new.
>>         objectRepresentation := objectMemory objectRepresentationClass
>>                                                                 forCogit:
>> self methodZone: methodZone.
>>         methodZone setInterpreter: aCoInterpreter
>>                                 objectRepresentation: objectRepresentation
>>                                 cogit: self.
>>         generatorTable := self class generatorTable.
>>         processor := ProcessorClass new.
>>         simulatedAddresses := Dictionary new.
>>         simulatedTrampolines := Dictionary new.
>>         simulatedVariableGetters := Dictionary new.
>>         simulatedVariableSetters := Dictionary new.
>>         traceStores := 0.
>>         traceFlags := (self class initializationOptions at:
>> #recordPrimTrace ifAbsent: [true])
>>                                         ifTrue: [8] "record prim trace on
>> by default (see Cogit class>>decareCVarsIn:)"
>>                                         ifFalse: [0].
>>         debugPrimCallStackOffset := 0.
>>         singleStep := printRegisters := printInstructions := clickConfirm
>> := false.
>>         backEnd := CogCompilerClass for: self.
>>         methodLabel := CogCompilerClass for: self.
>>         (literalsManager := backEnd class literalsManagerClass new)
>> cogit: self.
>>         ordinarySendTrampolines := CArrayAccessor on: (Array new:
>> NumSendTrampolines).
>>         superSendTrampolines := CArrayAccessor on: (Array new:
>> NumSendTrampolines).
>>         BytecodeSetHasDirectedSuperSend ifTrue:
>>                 [directedSuperSendTrampolines := CArrayAccessor on:
>> (Array new: NumSendTrampolines)].
>>         NewspeakVM ifTrue:
>>                 [selfSendTrampolines := CArrayAccessor on: (Array new:
>> NumSendTrampolines).
>>                 dynamicSuperSendTrampolines := CArrayAccessor on: (Array
>> new: NumSendTrampolines).
>>                 implicitReceiverSendTrampolines := CArrayAccessor on:
>> (Array new: NumSendTrampolines).
>>                 outerSendTrampolines := CArrayAccessor on: (Array new:
>> NumSendTrampolines)].
>>         "debug metadata"
>>         objectReferencesInRuntime := CArrayAccessor on: (Array new:
>> NumObjRefsInRuntime).
>>         runtimeObjectRefIndex := 0.
>>         "debug metadata"
>>         trampolineAddresses := CArrayAccessor on: (Array new:
>> NumTrampolines * 2).
>>         trampolineTableIndex := 0.
>>
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0.
>>
>>         compilationTrace ifNil: [compilationTrace := self class
>> initializationOptions at: #compilationTrace ifAbsent: [0]].
>>         debugOpcodeIndices := self class initializationOptions at:
>> #debugOpcodeIndices ifAbsent: [Set new].
>>         debugBytecodePointers := self class initializationOptions at:
>> #debugBytecodePointers ifAbsent: [Set new]!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtJumpIfFalse (in category
>> 'bytecode generators') -----
>>   genExtJumpIfFalse
>>         "244            11110100        i i i i i i i i Pop and Jump 0n
>> False i i i i i i i i (+ Extend B * 256, where Extend B >= 0)"
>>         | distance target |
>>         distance := byte1 + (extB << 8).
>>         self assert: distance = (self v4: (self generatorAt: byte0)
>>
>> LongForward: bytecodePC
>>                                                                 Branch:
>> (extA ~= 0 ifTrue: [1] ifFalse: [0]) + (extB ~= 0 ifTrue: [1] ifFalse: [0])
>>                                                                 Distance:
>> methodObj).
>>         extB := 0.
>> +       numExtB := 0.
>>         target := distance + 2 + bytecodePC.
>>         ^self genJumpIf: objectMemory falseObject to: target!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtJumpIfTrue (in category
>> 'bytecode generators') -----
>>   genExtJumpIfTrue
>>         "243            11110011        i i i i i i i i Pop and Jump 0n
>> True i i i i i i i i (+ Extend B * 256, where Extend B >= 0)"
>>         | distance target |
>>         distance := byte1 + (extB << 8).
>>         self assert: distance = (self v4: (self generatorAt: byte0)
>>
>> LongForward: bytecodePC
>>                                                                 Branch:
>> (extA ~= 0 ifTrue: [1] ifFalse: [0]) + (extB ~= 0 ifTrue: [1] ifFalse: [0])
>>                                                                 Distance:
>> methodObj).
>>         extB := 0.
>> +       numExtB := 0.
>>         target := distance + 2 + bytecodePC.
>>         ^self genJumpIf: objectMemory trueObject to: target!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtNopBytecode (in category
>> 'bytecode generators') -----
>>   genExtNopBytecode
>>         "NewspeakV4: 221                11011101                Nop"
>>         "SistaV1:                91             01011011'
>>  Nop"
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0.
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtPushCharacterBytecode (in
>> category 'bytecode generators') -----
>>   genExtPushCharacterBytecode
>>         "SistaV1:               233             11101001        iiiiiiii
>>               Push Character #iiiiiiii (+ Extend B * 256)"
>>         | value |
>>         value := byte1 + (extB << 8).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^self genPushLiteral: (objectMemory characterObjectOf: value)!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtPushClosureBytecode (in
>> category 'bytecode generators') -----
>>   genExtPushClosureBytecode
>>         "Block compilation.  At this point in the method create the
>> block.  Note its start
>>          and defer generating code for it until after the method and any
>> other preceding
>>          blocks.  The block's actual code will be compiled later."
>>         "253            11111101 eei i i kkk    jjjjjjjj
>> Push Closure Num Copied iii (+ Ext A // 16 * 8) Num Args kkk (+ Ext A \\ 16
>> * 8) BlockSize jjjjjjjj (+ Ext B * 256). ee = num extensions"
>>         | numArgs numCopied |
>>         self assert: needsFrame.
>>         self addBlockStartAt: bytecodePC + 3 "0 relative"
>>                 numArgs: (numArgs := (byte1 bitAnd: 16r7) + (extA \\ 16 *
>> 8))
>>                 numCopied: (numCopied := ((byte1 >> 3) bitAnd: 7) + (extA
>> // 16 * 8))
>>                 span: byte2 + (extB << 8).
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0.
>>         objectRepresentation
>>                 genCreateClosureAt: bytecodePC + 4 "1 relative"
>>                 numArgs: numArgs
>>                 numCopied: numCopied
>>                 contextNumArgs: methodOrBlockNumArgs
>>                 large: (coInterpreter methodNeedsLargeContext: methodObj)
>>                 inBlock: inBlock.
>>         self PushR: ReceiverResultReg.
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtPushIntegerBytecode (in
>> category 'bytecode generators') -----
>>   genExtPushIntegerBytecode
>>         "NewsqueakV4:   229             11100101        iiiiiiii
>> Push Integer #iiiiiiii (+ Extend B * 256, where bbbbbbbb = sddddddd, e.g.
>> -32768 = i=0, a=0, s=1)
>>         SistaV1:                232             11101000        iiiiiiii
>>       Push Integer #iiiiiiii (+ Extend B * 256, where bbbbbbbb = sddddddd,
>> e.g. -32768 = i=0, a=0, s=1)"
>>         | value |
>>         value := byte1 + (extB << 8).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^self genPushLiteral: (objectMemory integerObjectOf: value)!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtPushPseudoVariable (in
>> category 'bytecode generators') -----
>>   genExtPushPseudoVariable
>>         "SistaV1: *     82                      01010010
>>       Push thisContext, (then Extend B = 1 => push thisProcess)"
>>         | ext |
>>         ext := extB.
>>         extB := 0.
>> +       numExtB := 0.
>>         ext caseOf: {
>>                 [0]     ->      [^self genPushActiveContextBytecode].
>>                 }
>>                 otherwise:
>>                         [^self unknownBytecode].
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtP
>> ushPseudoVariableOrOuterBytecode (in category 'bytecode generators')
>> -----
>>   genExtPushPseudoVariableOrOuterBytecode
>>         "77                     01001101                Push false [*
>> 1:true, 2:nil, 3:thisContext, ..., -N: pushEnclosingObjectAt: N, N = Extend
>> B]"
>>         | ext |
>>         ext := extB.
>>         extB := 0.
>> +       numExtB := 0.
>>         ext caseOf: {
>>                 [0]     ->      [^self genPushLiteral: objectMemory
>> falseObject].
>>                 [1]     ->      [^self genPushLiteral: objectMemory
>> trueObject].
>>                 [2]     ->      [^self genPushLiteral: objectMemory
>> nilObject].
>>                 [3]     ->      [^self genPushActiveContextBytecode]
>>                 }
>>                 otherwise:
>>                         [ext < 0 ifTrue:
>>                                 [^self genPushEnclosingObjectAt: 0 - ext].
>>                          self warning: 'undefined extension for
>> extPushPseudoVariableOrOuter'.
>>                          ^self unknownBytecode].
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtP
>> ushRemoteTempOrInstVarLongBytecode (in category 'bytecode generators')
>> -----
>>   genExtPushRemoteTempOrInstVarLongBytecode
>>         | index |
>>         ^ (byte2 noMask: coInterpreter remoteIsInstVarAccess)
>>                 ifTrue: [ self genPushRemoteTempLongBytecode ]
>>                 ifFalse:
>>                         [ index := byte1 + (extA << 8).
>>                         extA := 0.
>>                         extB := 0. "don't use flags in the simple cogit"
>> +                       numExtB := 0.
>>                         (coInterpreter isReadMediatedContextInstVarIndex:
>> index)
>>                                 ifTrue: [self
>>
>> genPushMaybeContextRemoteInstVar: index
>>                                                         inObjectAt: byte2
>> - coInterpreter remoteIsInstVarAccess]
>>                                 ifFalse: [self
>>
>> genPushRemoteInstVar: index
>>                                                         inObjectAt: byte2
>> - coInterpreter remoteIsInstVarAccess]]!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtSendAbsentDynamicSuperBytecode
>> (in category 'bytecode generators') -----
>>   genExtSendAbsentDynamicSuperBytecode
>>         "241            11110001        i i i i i j j j Send To Absent
>> Dynamic Superclass Literal Selector #iiiii (+ Extend A * 32) with jjj (+
>> Extend B * 8) Arguments"
>>         | litIndex nArgs |
>>         litIndex := (byte1 >> 3) + (extA << 5).
>>         extA := 0.
>>         nArgs := (byte1 bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^self genSendAbsentDynamicSuper: litIndex numArgs: nArgs!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtSendAbsentImplicitBytecode
>> (in category 'bytecode generators') -----
>>   genExtSendAbsentImplicitBytecode
>>         "240            11110000        i i i i i j j j Send To Absent
>> Implicit Receiver Literal Selector #iiiii (+ Extend A * 32) with jjj (+
>> Extend B * 8) Arguments"
>>         | litIndex nArgs |
>>         litIndex := (byte1 >> 3) + (extA << 5).
>>         extA := 0.
>>         nArgs := (byte1 bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^self genSendAbsentImplicit: litIndex numArgs: nArgs!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtSendAbsentOuterBytecode (in
>> category 'bytecode generators') -----
>>   genExtSendAbsentOuterBytecode
>>         "254             11111110       i i i i i j j j kkkkkkkk
>> Send To Absent Outer Literal Selector #iiiii (+ Extend A * 32) with jjj (+
>> Extend B * 8) Arguments at Depth kkkkkkkk "
>>         | litIndex nArgs depth |
>>         litIndex := (byte1 >> 3) + (extA << 5).
>>         extA := 0.
>>         nArgs := (byte1 bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         depth := byte2.
>>         ^self genSendAbsentOuter: litIndex numArgs: nArgs depth: depth
>>   !
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtSendAbsentSelfBytecode (in
>> category 'bytecode generators') -----
>>   genExtSendAbsentSelfBytecode
>>         "245            11110101        i i i i i j j j Send To Absent
>> Self Literal Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8)
>> Arguments"
>>         | litIndex nArgs |
>>         litIndex := (byte1 >> 3) + (extA << 5).
>>         extA := 0.
>>         nArgs := (byte1 bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^self genSendAbsentSelf: litIndex numArgs: nArgs!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtSendBytecode (in category
>> 'bytecode generators') -----
>>   genExtSendBytecode
>>         "238            11101110        i i i i i j j j Send Literal
>> Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments"
>>         | litIndex nArgs |
>>         litIndex := (byte1 >> 3) + (extA << 5).
>>         extA := 0.
>>         nArgs := (byte1 bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^self genSend: litIndex numArgs: nArgs!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtSendSuperBytecode (in
>> category 'bytecode generators') -----
>>   genExtSendSuperBytecode
>>         "239            11101111        i i i i i j j j Send To
>> Superclass Literal Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B *
>> 8) Arguments"
>>         | isDirected litIndex nArgs |
>>         (isDirected := extB >= 64) ifTrue:
>>                 [extB := extB bitAnd: 63].
>>         litIndex := (byte1 >> 3) + (extA << 5).
>>         extA := 0.
>>         nArgs := (byte1 bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         ^isDirected
>>                 ifTrue: [self genSendDirectedSuper: litIndex numArgs:
>> nArgs]
>>                 ifFalse: [self genSendSuper: litIndex numArgs: nArgs]!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtS
>> torePopRemoteTempOrInstVarLongBytecodePopBoolean: (in category 'bytecode
>> generators') -----
>>   genExtStorePopRemoteTempOrInstVarLongBytecodePopBoolean: popBoolean
>>         | index |
>>         extB := 0. "simple cogit don't use the extra flag"
>> +       numExtB := 0.
>>         (byte2 noMask: coInterpreter remoteIsInstVarAccess)
>>                 ifTrue:
>>                         [ self genStorePop: popBoolean RemoteTemp: byte1
>> At: byte2.
>>                         self cppIf: IMMUTABILITY ifTrue: [ self
>> annotateBytecode: self Label ] ]
>>                 ifFalse:
>>                         [ index := byte1 + (extA << 8).
>>                         extA := 0.
>>                         (coInterpreter isWriteMediatedContextInstVarIndex:
>> index)
>>                                 ifTrue: [ self
>>                                                 genStorePop: popBoolean
>>
>> MaybeContextRemoteInstVar: index
>>                                                 ofObjectAt: byte2 -
>> coInterpreter remoteIsInstVarAccess ]
>>                                 ifFalse: [ self
>>                                                 genStorePop: popBoolean
>>                                                 RemoteInstVar: index
>>                                                 ofObjectAt: byte2 -
>> coInterpreter remoteIsInstVarAccess  ] ].
>>         ^ 0!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genExtUnconditionalJump (in
>> category 'bytecode generators') -----
>>   genExtUnconditionalJump
>>         "242            11110010        i i i i i i i i Jump i i i i i i
>> i i (+ Extend B * 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0,
>> s=1)"
>>         | distance target |
>>         distance := byte1 + (extB << 8).
>>         self assert: distance = (self v4: (self generatorAt: byte0)
>>                                                                 Long:
>> bytecodePC
>>                                                                 Branch:
>> (extA ~= 0 ifTrue: [1] ifFalse: [0]) + (extB ~= 0 ifTrue: [1] ifFalse: [0])
>>                                                                 Distance:
>> methodObj).
>>         extB := 0.
>> +       numExtB := 0.
>>         target := distance + 2 + bytecodePC.
>>         distance < 0 ifTrue:
>>                 [^self genJumpBackTo: target].
>>         self genJumpTo: target.
>>         "The bytecode must be mapped since it can be either forward or
>> backward, and
>>           backwards branches must be mapped. So if forward, we need to
>> map."
>>         self annotateBytecode: self lastOpcode.
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genSist
>> aExtStoreAndPopReceiverVariableBytecodePopBoolean: (in category
>> 'bytecode generators') -----
>>   genSistaExtStoreAndPopReceiverVariableBytecodePopBoolean: boolean
>>         | index |
>>         extB := 0. "Simple cogit don't use the extra flags"
>> +       numExtB := 0.
>>         index := byte1 + (extA << 8).
>>         extA := 0.
>>         ^(coInterpreter isWriteMediatedContextInstVarIndex: index)
>>                 ifTrue: [self genStorePop: boolean
>> MaybeContextReceiverVariable: index ]
>>                 ifFalse: [self genStorePop: boolean ReceiverVariable:
>> index ]!
>>
>> Item was changed:
>>   ----- Method: SimpleStackBasedCogit>>genSist
>> aExtStoreLiteralVariableBytecodePopBoolean: (in category 'bytecode
>> generators') -----
>>   genSistaExtStoreLiteralVariableBytecodePopBoolean: boolean
>>         | index |
>>         extB := 0. "SimpleCogit don't use the extra flags"
>> +       numExtB := 0.
>>         index := byte1 + (extA << 8).
>>         extA := 0.
>>         ^ self genStorePop: boolean LiteralVariable: index!
>>
>> Item was changed:
>>   ----- Method: SistaCogit>>genExtJumpIfNotInstanceOfBehaviorsBytecode
>> (in category 'bytecode generators') -----
>>   genExtJumpIfNotInstanceOfBehaviorsBytecode
>>         "SistaV1: *     254             11111110        kkkkkkkk
>> jjjjjjjj                branch If Not Instance Of Behavior/Array Of
>> Behavior kkkkkkkk (+ Extend A * 256, where Extend A >= 0) distance jjjjjjjj
>> (+ Extend B * 256, where Extend B >= 0)"
>>
>>         | reg literal distance targetFixUp inverse |
>>
>>         "We loose the information of in which register is stack top
>>         when jitting the branch target so we need to flush everything.
>>         We could use a fixed register here...."
>>         reg := self allocateRegForStackEntryAt: 0.
>>         self ssTop popToReg: reg.
>>         self ssFlushTo: simStackPtr. "flushed but the value is still in
>> reg"
>>
>>         self genPopStackBytecode.
>>
>>         literal := self getLiteral: (extA * 256 + byte1).
>>         extA := 0.
>>         extB < 0
>>                 ifTrue: [extB := extB + 128. inverse := true]
>>                 ifFalse: [inverse := false].
>>         distance := extB * 256 + byte2.
>>         extB := 0.
>> +       numExtB := 0.
>>
>>         targetFixUp := self cCoerceSimple: (self ensureFixupAt:
>> bytecodePC + 3 + distance - initialPC) to: #'AbstractInstruction *'.
>>         inverse
>>                 ifFalse:
>>                         [(objectMemory isArrayNonImm: literal)
>>                                 ifTrue: [objectRepresentation branchIf:
>> reg notInstanceOfBehaviors: literal target: targetFixUp]
>>                                 ifFalse: [objectRepresentation branchIf:
>> reg notInstanceOfBehavior: literal target: targetFixUp] ]
>>                 ifTrue:
>>                         [(objectMemory isArrayNonImm: literal)
>>                                 ifTrue: [objectRepresentation branchIf:
>> reg instanceOfBehaviors: literal target: targetFixUp]
>>                                 ifFalse: [objectRepresentation branchIf:
>> reg instanceOfBehavior: literal target: targetFixUp]].
>>
>>
>>
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SistaCogit>>genUnaryInlinePrimitive: (in category
>> 'inline primitive generators') -----
>>   genUnaryInlinePrimitive: prim
>>         "Unary inline primitives."
>>         "SistaV1: 248           11111000        iiiiiiii
>> mjjjjjjj                Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1
>> means inlined primitive, no hard return after execution.
>>          See EncoderForSistaV1's class comment and
>> StackInterpreter>>#unaryInlinePrimitive:"
>>         | rcvrReg resultReg |
>>         rcvrReg := self allocateRegForStackEntryAt: 0.
>>         resultReg := self allocateRegNotConflictingWith: (self
>> registerMaskFor: rcvrReg).
>>         prim
>>                 caseOf: {
>>                                         "00             unchecked class"
>>                         [1] ->  "01             unchecked pointer
>> numSlots"
>>                                 [self ssTop popToReg: rcvrReg.
>>                                  self ssPop: 1.
>>                                  objectRepresentation
>>                                         genGetNumSlotsOf: rcvrReg into:
>> resultReg;
>>                                         genConvertIntegerToSmallIntegerInReg:
>> resultReg].
>>                                         "02             unchecked pointer
>> basicSize"
>>                         [3] ->  "03             unchecked byte numBytes"
>>                                 [self ssTop popToReg: rcvrReg.
>>                                  self ssPop: 1.
>>                                  objectRepresentation
>>                                         genGetNumBytesOf: rcvrReg into:
>> resultReg;
>>                                         genConvertIntegerToSmallIntegerInReg:
>> resultReg].
>>                                         "04             unchecked
>> short16Type format numShorts"
>>                                         "05             unchecked
>> word32Type format numWords"
>>                                         "06             unchecked
>> doubleWord64Type format numDoubleWords"
>>                         [11] -> "11             unchecked fixed pointer
>> basicNew"
>>                                 [self ssTop type ~= SSConstant ifTrue:
>>                                         [^EncounteredUnknownBytecode].
>>                                  (objectRepresentation
>>                                         genGetInstanceOf: self ssTop
>> constant
>>                                                 into: resultReg
>>                                                         initializingIf:
>> self extBSpecifiesInitializeInstance) ~= 0 ifTrue:
>>                                         [^ShouldNotJIT]. "e.g. bad class"
>>                                  self ssPop: 1] .
>>                         [20] -> "20     identityHash"
>>                                 [self ssTop popToReg: rcvrReg.
>>                                  objectRepresentation
>> genGetHashFieldNonImmOf: rcvrReg asSmallIntegerInto: resultReg.
>>                                  self ssPop: 1]
>>                                         "21             identityHash
>> (SmallInteger)"
>>                                         "22             identityHash
>> (Character)"
>>                                         "23             identityHash
>> (SmallFloat64)"
>>                                         "24             identityHash
>> (Behavior)"
>>                                   }
>>                 otherwise:
>>                         [^EncounteredUnknownBytecode].
>>         extB := 0.
>> +       numExtB := 0.
>>         self ssPushRegister: resultReg.
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SistaCogitClone>>genExtJumpIfNotInstanceOfBehaviorsBytecode
>> (in category 'bytecode generators') -----
>>   genExtJumpIfNotInstanceOfBehaviorsBytecode
>>         "SistaV1: *     254             11111110        kkkkkkkk
>> jjjjjjjj                branch If Not Instance Of Behavior/Array Of
>> Behavior kkkkkkkk (+ Extend A * 256, where Extend A >= 0) distance jjjjjjjj
>> (+ Extend B * 256, where Extend B >= 0)"
>>
>>         | reg literal distance targetFixUp inverse |
>>
>>         "We loose the information of in which register is stack top
>>         when jitting the branch target so we need to flush everything.
>>         We could use a fixed register here...."
>>         reg := self allocateRegForStackEntryAt: 0.
>>         self ssTop popToReg: reg.
>>         self ssFlushTo: simStackPtr. "flushed but the value is still in
>> reg"
>>
>>         self genPopStackBytecode.
>>
>>         literal := self getLiteral: (extA * 256 + byte1).
>>         extA := 0.
>>         extB < 0
>>                 ifTrue: [extB := extB + 128. inverse := true]
>>                 ifFalse: [inverse := false].
>>         distance := extB * 256 + byte2.
>>         extB := 0.
>> +       numExtB := 0.
>>
>>         targetFixUp := self cCoerceSimple: (self ensureFixupAt:
>> bytecodePC + 3 + distance - initialPC) to: #'AbstractInstruction *'.
>>         inverse
>>                 ifFalse:
>>                         [(objectMemory isArrayNonImm: literal)
>>                                 ifTrue: [objectRepresentation branchIf:
>> reg notInstanceOfBehaviors: literal target: targetFixUp]
>>                                 ifFalse: [objectRepresentation branchIf:
>> reg notInstanceOfBehavior: literal target: targetFixUp] ]
>>                 ifTrue:
>>                         [(objectMemory isArrayNonImm: literal)
>>                                 ifTrue: [objectRepresentation branchIf:
>> reg instanceOfBehaviors: literal target: targetFixUp]
>>                                 ifFalse: [objectRepresentation branchIf:
>> reg instanceOfBehavior: literal target: targetFixUp]].
>>
>>
>>
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: SistaCogitClone>>genUnaryInlinePrimitive: (in category
>> 'inline primitive generators') -----
>>   genUnaryInlinePrimitive: prim
>>         "Unary inline primitives."
>>         "SistaV1: 248           11111000        iiiiiiii
>> mjjjjjjj                Call Primitive #iiiiiiii + (jjjjjjj * 256) m=1
>> means inlined primitive, no hard return after execution.
>>          See EncoderForSistaV1's class comment and
>> StackInterpreter>>#unaryInlinePrimitive:"
>>         | rcvrReg resultReg |
>>         rcvrReg := self allocateRegForStackEntryAt: 0.
>>         resultReg := self allocateRegNotConflictingWith: (self
>> registerMaskFor: rcvrReg).
>>         prim
>>                 caseOf: {
>>                                         "00             unchecked class"
>>                         [1] ->  "01             unchecked pointer
>> numSlots"
>>                                 [self ssTop popToReg: rcvrReg.
>>                                  self ssPop: 1.
>>                                  objectRepresentation
>>                                         genGetNumSlotsOf: rcvrReg into:
>> resultReg;
>>                                         genConvertIntegerToSmallIntegerInReg:
>> resultReg].
>>                                         "02             unchecked pointer
>> basicSize"
>>                         [3] ->  "03             unchecked byte numBytes"
>>                                 [self ssTop popToReg: rcvrReg.
>>                                  self ssPop: 1.
>>                                  objectRepresentation
>>                                         genGetNumBytesOf: rcvrReg into:
>> resultReg;
>>                                         genConvertIntegerToSmallIntegerInReg:
>> resultReg].
>>                                         "04             unchecked
>> short16Type format numShorts"
>>                                         "05             unchecked
>> word32Type format numWords"
>>                                         "06             unchecked
>> doubleWord64Type format numDoubleWords"
>>                         [11] -> "11             unchecked fixed pointer
>> basicNew"
>>                                 [self ssTop type ~= SSConstant ifTrue:
>>                                         [^EncounteredUnknownBytecode].
>>                                  (objectRepresentation
>>                                         genGetInstanceOf: self ssTop
>> constant
>>                                                 into: resultReg
>>                                                         initializingIf:
>> self extBSpecifiesInitializeInstance) ~= 0 ifTrue:
>>                                         [^ShouldNotJIT]. "e.g. bad class"
>>                                  self ssPop: 1]
>>                                   }
>>                 otherwise:
>>                         [^EncounteredUnknownBytecode].
>>         extB := 0.
>> +       numExtB := 0.
>>         self ssPushRegister: resultReg.
>>         ^0!
>>
>> Item was changed:
>>   InterpreterPrimitives subclass: #StackInterpreter
>> +       instanceVariableNames: 'currentBytecode bytecodeSetSelector
>> localFP localIP localSP stackLimit stackPage stackPages method
>> instructionPointer stackPointer framePointer localReturnValue
>> localAbsentReceiver localAbsentReceiverOrZero extA extB numExtB
>> primitiveFunctionPointer methodCache nsMethodCache atCache lkupClassTag
>> lkupClass methodDictLinearSearchLimit highestRunnableProcessPriority
>> nextWakeupUsecs nextPollUsecs inIOProcessEvents interruptKeycode
>> interruptPending savedWindowSize imageHeaderFlags fullScreenFlag
>> deferDisplayUpdates pendingFinalizationSignals extraVMMemory
>> interpreterProxy showSurfaceFn primitiveTable primitiveAccessorDepthTable
>> externalPrimitiveTable externalPrimitiveTableFirstFreeIndex
>> overflowedPage extraFramesToMoveOnOverflow globalSessionID jmpBuf jmpDepth
>> suspendedCallbacks suspendedMethods numStackPages desiredNumStackPages
>> desiredEdenBytes classNameIndex thisClassIndex metaclassNumSlots
>> interruptCheckChain suppressHeartbeatFlag breakSelector breakSelector
>>  Length longRunningPrimitiveCheckMethod longRunningPrimitiveCheckSemaphore
>> longRunningPrimitiveStartUsecs longRunningPrimitiveStopUsecs
>> longRunningPrimitiveGCUsecs longRunningPrimitiveCheckSequenceNumber
>> longRunningPrimitiveSignalUndelivered checkAllocFiller tempOop tempOop2
>> tempOop3 theUnknownShort the2ndUnknownShort imageFloatsBigEndian
>> maxExtSemTabSizeSet lastMethodCacheProbeWrite gcSemaphoreIndex
>> classByteArrayCompactIndex checkedPluginName statForceInterruptCheck
>> statStackOverflow statStackPageDivorce statCheckForEvents statProcessSwitch
>> statIOProcessEvents statPendingFinalizationSignals nativeSP
>> nativeStackPointer lowcodeCalloutState shadowCallStackPointer'
>> -       instanceVariableNames: 'currentBytecode bytecodeSetSelector
>> localFP localIP localSP stackLimit stackPage stackPages method
>> instructionPointer stackPointer framePointer localReturnValue
>> localAbsentReceiver localAbsentReceiverOrZero extA extB
>> primitiveFunctionPointer methodCache nsMethodCache atCache lkupClassTag
>> lkupClass methodDictLinearSearchLimit highestRunnableProcessPriority
>> nextWakeupUsecs nextPollUsecs inIOProcessEvents interruptKeycode
>> interruptPending savedWindowSize imageHeaderFlags fullScreenFlag
>> deferDisplayUpdates pendingFinalizationSignals extraVMMemory
>> interpreterProxy showSurfaceFn primitiveTable primitiveAccessorDepthTable
>> externalPrimitiveTable externalPrimitiveTableFirstFreeIndex
>> overflowedPage extraFramesToMoveOnOverflow globalSessionID jmpBuf jmpDepth
>> suspendedCallbacks suspendedMethods numStackPages desiredNumStackPages
>> desiredEdenBytes classNameIndex thisClassIndex metaclassNumSlots
>> interruptCheckChain suppressHeartbeatFlag breakSelector breakSelectorLength
>> l
>>  ongRunningPrimitiveCheckMethod longRunningPrimitiveCheckSemaphore
>> longRunningPrimitiveStartUsecs longRunningPrimitiveStopUsecs
>> longRunningPrimitiveGCUsecs longRunningPrimitiveCheckSequenceNumber
>> longRunningPrimitiveSignalUndelivered checkAllocFiller tempOop tempOop2
>> tempOop3 theUnknownShort the2ndUnknownShort imageFloatsBigEndian
>> maxExtSemTabSizeSet lastMethodCacheProbeWrite gcSemaphoreIndex
>> classByteArrayCompactIndex checkedPluginName statForceInterruptCheck
>> statStackOverflow statStackPageDivorce statCheckForEvents statProcessSwitch
>> statIOProcessEvents statPendingFinalizationSignals nativeSP
>> nativeStackPointer lowcodeCalloutState shadowCallStackPointer'
>>         classVariableNames: 'AccessModifierPrivate
>> AccessModifierProtected AccessModifierPublic AltBytecodeEncoderClassName
>> AltLongStoreBytecode AlternateHeaderHasPrimFlag
>> AlternateHeaderIsOptimizedFlag AlternateHeaderNumLiteralsMask
>> AtCacheFixedFields AtCacheFmt AtCacheMask AtCacheOop AtCacheSize
>> AtCacheTotalSize AtPutBase BytecodeEncoderClassName BytecodeTable
>> CacheProbeMax DirBadPath DirEntryFound DirNoMoreEntries DumpStackOnLowSpace
>> EnclosingMixinIndex EnclosingObjectIndex EnforceAccessControl
>> FailImbalancedPrimitives LongStoreBytecode MaxExternalPrimitiveTableSize
>> MaxJumpBuf MaxPrimitiveIndex MaxQuickPrimitiveIndex
>> MethodHeaderArgCountShift MethodHeaderFlagBitPosition
>> MethodHeaderTempCountShift MixinIndex PrimNumberDoExternalCall
>> PrimNumberExternalCall PrimNumberFFICall PrimitiveExternalCallIndex
>> PrimitiveTable StackPageReachedButUntraced StackPageTraceInvalid
>> StackPageTraced StackPageUnreached V3PrimitiveBitsMask'
>>         poolDictionaries: 'VMBasicConstants VMBytecodeConstants
>> VMMethodCacheConstants VMObjectIndices VMSpurObjectRepresentationConstants
>> VMSqueakClassIndices VMStackFrameOffsets'
>>         category: 'VMMaker-Interpreter'!
>>
>>   !StackInterpreter commentStamp: 'eem 12/5/2014 11:32' prior: 0!
>>   This class is a complete implementation of the Smalltalk-80 virtual
>> machine, derived originally from the Blue Book specification but quite
>> different in some areas.  This VM supports Closures but *not* old-style
>> BlockContexts.
>>
>>   It has been modernized with 32-bit pointers, better management of
>> Contexts (see next item), and attention to variable use that allows the
>> CCodeGenerator (qv) to keep, eg, the instruction pointer and stack pointer
>> in registers as well as keeping most simple variables in a global array
>> that seems to improve performance for most platforms.
>>
>>   The VM does not use Contexts directly.  Instead Contexts serve as
>> proxies for a more conventional stack format that is invisible to the
>> image.  There is considerable explanation at
>> http://www.mirandabanda.org/cogblog/2009/01/14/under-cover-
>> contexts-and-the-big-frame-up.  The VM maintains a fixed-size stack zone
>> divided into pages, each page being capable of holding several method/block
>> activations.  A send establishes a new frame in the current stack page, a
>> return returns to the previous frame.  This eliminates
>> allocation/deallocation of contexts and the moving of receiver and
>> arguments from caller to callee on each send/return.  Contexts are created
>> lazily when an activation needs a context (creating a block, explicit use
>> of thisContext, access to sender when sender is a frame, or linking of
>> stack pages together).  Contexts are either conventional and heap-resident
>> ("single") or "married" and serve as proxies for their corresponding frame
>> or "widowed", meaning that their spouse f
>>  rame has been returned from (died).  A married context is specially
>> marked (more details in the code) and refers to its frame.  Likewise a
>> married frame is specially marked and refers to its context.
>>
>>   In addition to SmallInteger arithmetic and Floats, the VM supports
>> logic on 32-bit PositiveLargeIntegers, thus allowing it to simulate itself
>> much more effectively than would otherwise be the case.
>>
>>   StackInterpreter and subclasses support multiple memory managers.
>> Currently there are two.  NewMemoryManager is a slightly refined version of
>> ObjectMemory, and is the memory manager and garbage collector for the
>> original Squeak object representation as described in "Back to the Future
>> The Story of Squeak, A Practical Smalltalk Written in Itself", see
>> http://ftp.squeak.org/docs/OOPSLA.Squeak.html.  Spur is a faster, more
>> regular object representation that is designed for more performance and
>> functionality, and to have a common header format for both 32-bit and
>> 64-bit versions.  You can read about it in SpurMemoryManager's class
>> comment.  There is also a video of a presentation at ESUG 2014 (
>> https://www.youtube.com/watch?v=k0nBNS1aHZ4), along with slides (
>> http://www.slideshare.net/esug/spur-a-new-object-representa
>> tion-for-cog?related=1).!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extBBytecode (in category
>> 'miscellaneous bytecodes') -----
>>   extBBytecode
>>         "225            11100001        sbbbbbbb        Extend B (Ext B =
>> Ext B prev * 256 + Ext B)"
>>         | byte |
>>         byte := self fetchByte.
>>         self fetchNextBytecode.
>> +       extB := (numExtB = 0 and: [byte > 127])
>> -       extB := (extB = 0 and: [byte > 127])
>>                                 ifTrue: [byte - 256]
>> +                               ifFalse: [(extB bitShift: 8) + byte].
>> +       numExtB := numExtB + 1!
>> -                               ifFalse: [(extB bitShift: 8) + byte]!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extJumpIfFalse (in category 'jump
>> bytecodes') -----
>>   extJumpIfFalse
>>         "244            11110100        i i i i i i i i Pop and Jump 0n
>> False i i i i i i i i (+ Extend B * 256, where Extend B >= 0)"
>>         | byte offset |
>>         byte := self fetchByte.
>>         offset := byte + (extB << 8).
>> +       numExtB := extB := extA := 0.
>> -       extB := extA := 0.
>>         self jumplfFalseBy: offset!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extJumpIfNotInstanceOfBehaviorsBytecode
>> (in category 'sista bytecodes') -----
>>   extJumpIfNotInstanceOfBehaviorsBytecode
>>         "254            11111110        kkkkkkkk        jjjjjjjj
>>       branch If Not Instance Of Behavior/Array Of Behavior kkkkkkkk (+
>> Extend A * 256, where Extend A >= 0) distance jjjjjjjj (+ Extend B * 256,
>> where Extend B >= 0)"
>>         | tosClassTag literal distance inverse |
>>         SistaVM ifFalse: [^self respondToUnknownBytecode].
>>         extB < 0
>>                 ifTrue: [extB := extB + 128. inverse := true]
>>                 ifFalse: [inverse := false].
>>         tosClassTag := objectMemory fetchClassTagOf: self
>> internalPopStack.
>>         literal := self literal: extA << 8 + self fetchByte.
>>         distance := extB << 8 + self fetchByte.
>>         extA := 0.
>>         extB := 0.
>> +       numExtB := 0.
>>         (objectMemory isArrayNonImm: literal)
>>                 ifTrue:
>>                         [0 to: (objectMemory numSlotsOf: literal)
>> asInteger - 1 do: [:i |
>>                                 tosClassTag = (objectMemory
>> rawClassTagForClass: (objectMemory fetchPointer: i ofObject: literal))
>>                                         ifTrue: [
>>                                                 inverse ifTrue: [ localIP
>> := localIP + distance ].
>>                                                 ^ self fetchNextBytecode
>> ] ].
>>                          inverse ifFalse: [localIP := localIP + distance].
>>                          ^ self fetchNextBytecode]
>>                 ifFalse:
>>                         [tosClassTag ~= (objectMemory
>> rawClassTagForClass: literal) ifTrue:
>>                                 [inverse ifFalse: [localIP := localIP +
>> distance].
>>                                 ^ self fetchNextBytecode]].
>>         inverse ifTrue: [localIP := localIP + distance].
>>         self fetchNextBytecode!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extJumpIfTrue (in category 'jump
>> bytecodes') -----
>>   extJumpIfTrue
>>         "243            11110011        i i i i i i i i Pop and Jump 0n
>> True i i i i i i i i (+ Extend B * 256, where Extend B >= 0)"
>>         | byte offset |
>>         byte := self fetchByte.
>>         offset := byte + (extB << 8).
>> +       numExtB := extB := extA := 0.
>> -       extB := extA := 0.
>>         self jumplfTrueBy: offset!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extNopBytecode (in category
>> 'miscellaneous bytecodes') -----
>>   extNopBytecode
>>         "SistaV1                94              01011111
>> Nop"
>>         "NewspeakV4: 221                11011101                Nop"
>>         self fetchNextBytecode.
>> +       numExtB := extA := extB := 0!
>> -       extA := extB := 0!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extPushCharacterBytecode (in category
>> 'stack bytecodes') -----
>>   extPushCharacterBytecode
>>         "SistaV1:       *       233             11101001        iiiiiiii
>>               Push Character #iiiiiiii (+ Extend B * 256)"
>>         | value |
>>         value := self fetchByte + (extB << 8).
>>         self fetchNextBytecode.
>>         self internalPush: (objectMemory characterObjectOf: value).
>> +       numExtB := extB := 0!
>> -       extB := 0!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extPushClosureBytecode (in category
>> 'stack bytecodes') -----
>>   extPushClosureBytecode
>>         "253            11111101 eei i i kkk    jjjjjjjj
>> Push Closure Num Copied iii (+ Ext A // 16 * 8) Num Args kkk (+ Ext A \\ 16
>> * 8) BlockSize jjjjjjjj (+ Ext B * 256). ee = num extensions.
>>          The compiler has pushed the values to be copied, if any.  Find
>> numArgs and numCopied in the byte following.
>>          Create a Closure with space for the copiedValues and pop
>> numCopied values off the stack into the closure.
>>          Set numArgs as specified, and set startpc to the pc following
>> the block size and jump over that code."
>>         | byte numArgs numCopied blockSize |
>>         byte := self fetchByte.
>>         numArgs := (byte bitAnd: 7) + (extA \\ 16 * 8).
>>         numCopied := ((byte >> 3) bitAnd: 7) + (extA // 16 * 8).
>>         extA := 0.
>>         blockSize := self fetchByte + (extB << 8).
>> +       numExtB := extB := 0.
>> -       extB := 0.
>>         self pushClosureNumArgs: numArgs copiedValues: numCopied
>> blockSize: blockSize!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extPushIntegerBytecode (in category
>> 'stack bytecodes') -----
>>   extPushIntegerBytecode
>>         "229            11100101        i i i i i i i i Push Integer
>> #iiiiiiii (+ Extend B * 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0,
>> a=0, s=1)"
>>         | value |
>>         value := self fetchByte + (extB << 8).
>>         self fetchNextBytecode.
>>         extB := 0.
>> +       numExtB := 0.
>>         self internalPush: (objectMemory integerObjectOf: value)!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extPushPseudoVariable (in category
>> 'stack bytecodes') -----
>>   extPushPseudoVariable
>>         "SistaV1:       *       82                      01010010
>>               Push thisContext, (then e.g. Extend B 1 = push thisProcess)"
>>         | theThingToPush |
>>         extB
>>                 caseOf: {
>>                         [0]     ->      [theThingToPush := self
>> ensureFrameIsMarried: localFP SP: localSP].
>>                         [1]     ->      [theThingToPush := self
>> activeProcess] }
>>                 otherwise:
>>                         [self respondToUnknownBytecode].
>>         self fetchNextBytecode.
>>         self internalPush: theThingToPush.
>> +       extB := 0.
>> +       numExtB := 0.!
>> -       extB := 0!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extPushPseudoVariableOrOuterBytecode
>> (in category 'stack bytecodes') -----
>>   extPushPseudoVariableOrOuterBytecode
>>         "77                     01001101                Push false [*
>> 1:true, 2:nil, 3:thisContext, ..., -N: pushExplicitOuter: N, N = Extend B]"
>>         | thing |
>>         self fetchNextBytecode.
>>         thing := extB
>>                                 caseOf: {
>>                                         [0]     ->      [^self
>> internalPush: objectMemory falseObject].
>>                                         [1]     ->      [objectMemory
>> trueObject].
>>                                         [2]     ->      [objectMemory
>> nilObject].
>>                                         [3]     ->      [| context |
>>                                                          context := self
>> ensureFrameIsMarried: localFP SP: localSP.
>>                                                          context]
>>                                 }
>>                                 otherwise:
>>                                         [extB < 0
>>                                                 ifTrue:
>>                                                         [self
>>
>> enclosingObjectAt: 0 - extB
>>
>> withObject: self receiver
>>
>> withMixin: (self methodClassOf: method)]
>>                                                 ifFalse:
>>                                                         [self error:
>> 'undefined extension for extPushPseudoVariableOrOuter'.
>>                                                          objectMemory
>> nilObject]].
>>         extB := 0.
>> +       numExtB := 0.
>>         self internalPush: thing!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extPushRemoteTempOrInstVarLongBytecode
>> (in category 'stack bytecodes') -----
>>   extPushRemoteTempOrInstVarLongBytecode
>>         | slotIndex tempIndex object |
>>         slotIndex := self fetchByte.
>>         tempIndex := self fetchByte.
>>         self fetchNextBytecode.
>>         (tempIndex noMask: self remoteIsInstVarAccess)
>>                 ifTrue: [self pushRemoteTemp: slotIndex inVectorAt:
>> tempIndex]
>>                 ifFalse:
>>                         [ slotIndex := slotIndex + (extA << 8).
>>                         tempIndex := tempIndex - self
>> remoteIsInstVarAccess.
>> +                       numExtB := extA := extB := 0.
>> -                       extA := extB := 0.
>>                         object := self temporary: tempIndex in: localFP.
>>                         self pushMaybeContext: object receiverVariable:
>> slotIndex ]!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSendAbsentDynamicSuperBytecode (in
>> category 'send bytecodes') -----
>>   extSendAbsentDynamicSuperBytecode
>>         "241            11110001        i i i i i j j j Send To Dynamic
>> Superclass Literal Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B *
>> 8) Arguments"
>>         | byte |
>>         byte := self fetchByte.
>>         messageSelector := self literal: (byte >> 3) + (extA << 5).
>>         extA := 0.
>>         argumentCount := (byte bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         self commonSendDynamicSuper!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSendAbsentImplicitBytecode (in
>> category 'send bytecodes') -----
>>   extSendAbsentImplicitBytecode
>>         "240            11110000        i i i i i j j j Send To Absent
>> Implicit Receiver Literal Selector #iiiii (+ Extend A * 32) with jjj (+
>> Extend B * 8) Arguments"
>>         | byte |
>>         byte := self fetchByte.
>>         messageSelector := self literal: (byte >> 3) + (extA << 5).
>>         extA := 0.
>>         argumentCount := (byte bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         self commonSendImplicitReceiver.!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSendAbsentOuterBytecode (in
>> category 'send bytecodes') -----
>>   extSendAbsentOuterBytecode
>>         "254              11111110      i i i i i j j j kkkkkkkk Send To
>> Enclosing Object at Depth kkkkkkkk Literal Selector #iiiii (+ Extend A *
>> 32) with jjj (+ Extend B * 8) Arguments"
>>         | byte depth |
>>         byte := self fetchByte.
>>         messageSelector := self literal: (byte >> 3) + (extA << 5).
>>         extA := 0.
>>         argumentCount := (byte bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         depth := self fetchByte.
>>         self commonSendOuter: depth!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSendAbsentSelfBytecode (in category
>> 'send bytecodes') -----
>>   extSendAbsentSelfBytecode
>>         "245             11110101       i i i i i j j j Send To Self
>> Literal Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8)
>> Arguments"
>>         | byte |
>>         byte := self fetchByte.
>>         messageSelector := self literal: (byte >> 3) + (extA << 5).
>>         extA := 0.
>>         argumentCount := (byte bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         self commonSendOuter: 0!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSendBytecode (in category 'send
>> bytecodes') -----
>>   extSendBytecode
>>         "238            11101110        i i i i i j j j Send Literal
>> Selector #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments"
>>         | byte rcvr |
>>         byte := self fetchByte.
>>         messageSelector := self literal: (byte >> 3) + (extA << 5).
>>         extA := 0.
>>         argumentCount := (byte bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         rcvr := self internalStackValue: argumentCount.
>>         lkupClassTag := objectMemory fetchClassTagOf: rcvr.
>>         self commonSendOrdinary!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSendSuperBytecode (in category
>> 'send bytecodes') -----
>>   extSendSuperBytecode
>>         "239            11101111        i i i i i j j j
>>                 ExtendB < 64
>>                         ifTrue: [Send To Superclass Literal Selector
>> #iiiii (+ Extend A * 32) with jjj (+ Extend B * 8) Arguments]
>>                         ifFalse: [Send To Superclass of Stacked Class
>> Literal Selector #iiiii (+ Extend A * 32) with jjj (+ (Extend B bitAnd: 63)
>> * 8) Arguments]"
>>         | byte |
>>         byte := self fetchByte.
>>         messageSelector := self literal: (byte >> 3) + (extA << 5).
>>         extA := 0.
>>         BytecodeSetHasDirectedSuperSend ifTrue:
>>                 [extB >= 64 ifTrue:
>>                         [argumentCount := (byte bitAnd: 7) + (extB - 64
>> << 3).
>>                          extB := 0.
>>                          ^self directedSuperclassSend]].
>>         argumentCount := (byte bitAnd: 7) + (extB << 3).
>>         extB := 0.
>> +       numExtB := 0.
>>         self superclassSend!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSistaStoreAndPopLiteralVariableBytecode
>> (in category 'stack bytecodes') -----
>>   extSistaStoreAndPopLiteralVariableBytecode
>>         "236            11101100        i i i i i i i i Pop and Store
>> Literal Variable #iiiiiiii (+ Extend A * 256)
>>         (3) ExtB lowest bit implies no store check is needed, ExtB next
>> bit implies the object may be a context, other bits in the extension are
>> unused."
>>         | variableIndex value |
>>         variableIndex := self fetchByte + (extA << 8).
>>         value := self internalStackTop.
>>         self internalPop: 1.
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0..
>>         self storeLiteralVariable: variableIndex withValue: value.
>>         self fetchNextBytecode.!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSistaStor
>> eAndPopReceiverVariableBytecode (in category 'stack bytecodes') -----
>>   extSistaStoreAndPopReceiverVariableBytecode
>>         "235            11101011        i i i i i i i i Pop and Store
>> Receiver Variable #iiiiiii (+ Extend A * 256)
>>         (3) ExtB lowest bit implies no store check is needed, ExtB next
>> bit implies the object may be a context, other bits in the extension are
>> unused."
>>         | variableIndex value |
>>         variableIndex := self fetchByte + (extA << 8).
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0.
>>         value := self internalStackTop.
>>         self internalPop: 1.
>>         self storeMaybeContextReceiverVariable: variableIndex withValue:
>> value.
>>         self fetchNextBytecode.!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSistaStoreLiteralVariableBytecode
>> (in category 'stack bytecodes') -----
>>   extSistaStoreLiteralVariableBytecode
>>         "233            11101001        i i i i i i i i Store Literal
>> Variable #iiiiiiii (+ Extend A * 256)
>>         (3) ExtB lowest bit implies no store check is needed, ExtB next
>> bit implies the object may be a context, other bits in the extension are
>> unused."
>>         | variableIndex |
>>         variableIndex := self fetchByte + (extA << 8).
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0.
>>         self storeLiteralVariable: variableIndex withValue: self
>> internalStackTop.
>>         self fetchNextBytecode.!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extSistaStoreReceiverVariableBytecode
>> (in category 'stack bytecodes') -----
>>   extSistaStoreReceiverVariableBytecode
>>         "232            11101000        i i i i i i i i Store Receiver
>> Variable #iiiiiii (+ Extend A * 256)
>>         (3) ExtB lowest bit implies no store check is needed, ExtB next
>> bit implies the object may be a context, other bits in the extension are
>> unused."
>>         | variableIndex |
>>         variableIndex := self fetchByte + (extA << 8).
>> +       extA := numExtB := extB := 0.
>> -       extA := extB := 0.
>>         self storeMaybeContextReceiverVariable: variableIndex withValue:
>> self internalStackTop.
>>         self fetchNextBytecode.!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extStoreRemoteTempOrInstVarLongBytecode
>> (in category 'stack bytecodes') -----
>>   extStoreRemoteTempOrInstVarLongBytecode
>>         <inline: true>
>>         | slotIndex tempIndex object |
>>         slotIndex := self fetchByte.
>>         tempIndex := self fetchByte.
>>         self fetchNextBytecode.
>>         (tempIndex noMask: self remoteIsInstVarAccess)
>>                 ifTrue: [self storeRemoteTemp: slotIndex inVectorAt:
>> tempIndex]
>>                 ifFalse:
>>                         [ slotIndex := slotIndex + (extA << 8).
>>                         tempIndex := tempIndex - self
>> remoteIsInstVarAccess.
>> +                       extA := numExtB := extB := 0.
>> -                       extA := extB := 0.
>>                         object := self temporary: tempIndex in: localFP.
>>                         self storeMaybeContext: object receiverVariable:
>> slotIndex withValue: self internalStackTop ]!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>extUnconditionalJump (in category
>> 'jump bytecodes') -----
>>   extUnconditionalJump
>>         "242            11110010        i i i i i i i i Jump i i i i i i
>> i i (+ Extend B * 256, where bbbbbbbb = sddddddd, e.g. -32768 = i=0, a=0,
>> s=1)"
>>         | byte offset |
>>         byte := self fetchByte.
>>         offset := byte + (extB << 8).
>>         extB := 0.
>> +       numExtB := 0.
>>         localIP := localIP + offset.
>>         self ifBackwardsCheckForEvents: offset.
>>         self fetchNextBytecode!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>initExtensions (in category
>> 'simulation support') -----
>>   initExtensions
>>         <inline: true>
>> +       BytecodeSetHasExtensions ifTrue: [extA := numExtB := extB := 0]!
>> -       BytecodeSetHasExtensions ifTrue: [extA := extB := 0]!
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>lowcodePrimitivePerformCallStructure
>> (in category 'inline primitive generated code') -----
>>   lowcodePrimitivePerformCallStructure
>>         <option: #LowcodeVM>    "Lowcode instruction generator"
>>         | resultPointer result function structureSize |
>>         <var: #resultPointer type: #'char*' >
>>         <var: #result type: #'char*' >
>>         function := extA.
>>         structureSize := extB.
>>         result := self internalPopStackPointer.
>>
>>         self internalPushShadowCallStackPointer: result.
>>         resultPointer := self lowcodeCalloutPointerResult: (self cCoerce:
>> function to: #'char*').
>>
>>         self internalPushPointer: resultPointer.
>>         extA := 0.
>>         extB := 0.
>> +       numExtB := 0.
>> -
>>   !
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>lowcodePrimitivePointerAddConstantOffset
>> (in category 'inline primitive generated code') -----
>>   lowcodePrimitivePointerAddConstantOffset
>>         <option: #LowcodeVM>    "Lowcode instruction generator"
>>         | base offset result |
>>         <var: #base type: #'char*' >
>>         <var: #result type: #'char*' >
>>         offset := extB.
>>         base := self internalPopStackPointer.
>>
>>         result := base + offset.
>>
>>         self internalPushPointer: result.
>>         extB := 0.
>> +       numExtB := 0.
>>
>>   !
>>
>> Item was changed:
>>   ----- Method: StackInterpreter>>unaryInlinePrimitive: (in category
>> 'miscellaneous bytecodes') -----
>>   unaryInlinePrimitive: primIndex
>>         "SistaV1:       248             11111000        iiiiiiii
>>       mjjjjjjj                Call Primitive #iiiiiiii + (jjjjjjj * 256)
>> m=1 means inlined primitive, no hard return after execution."
>>         <option: #SistaVM>
>>         | result |
>>         primIndex caseOf: {
>>                 "1000   unchecked class"
>>                 [0]     ->      [result := objectMemory fetchClassOf:
>> self internalStackTop.
>>                                  self internalStackTopPut: result].
>>                 "1001   unchecked pointer numSlots"
>>                 [1]     ->      [result := objectMemory numSlotsOf: self
>> internalStackTop.
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)].
>>                 "1002   unchecked pointer basicSize"
>>                 [2]     ->      [result := (objectMemory numSlotsOf: self
>> internalStackTop)
>>                                                 - (objectMemory
>> fixedFieldsOfClass: (objectMemory fetchClassOfNonImm: self
>> internalStackTop)).
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)].
>>                 "1003   unchecked byte8Type format numBytes (includes
>> CompiledMethod)"
>>                 [3]     ->      [result := objectMemory numBytesOf: self
>> internalStackTop.
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)].
>>                 "1004   unchecked short16Type format numShorts"
>>                 [4]     ->      [result := objectMemory num16BitUnitsOf:
>> self internalStackTop.
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)].
>>                 "1005   unchecked word32Type format numWords"
>>                 [5]     ->      [result := objectMemory num32BitUnitsOf:
>> self internalStackTop.
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)].
>>                 "1006   unchecked doubleWord64Type format numDoubleWords"
>>                 [6]     ->      [result := objectMemory num64BitUnitsOf:
>> self internalStackTop.
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)].
>>
>>                 "1011   unchecked fixed pointer basicNew"
>>                 [11] -> [| classObj numSlots |
>>                                  classObj := self internalStackTop.
>>                                  numSlots := objectMemory instanceSizeOf:
>> classObj.
>>                                  result := objectMemory
>> eeInstantiateSmallClass: classObj numSlots: numSlots.
>>                                  (extB noMask: 1) ifTrue:
>>                                         [0 to: numSlots - 1 do:
>>                                                 [:i| objectMemory
>> storePointerUnchecked: i ofObject: result withValue: objectMemory
>> nilObject]].
>>                                  extB := 0.
>> +                               numExtB := 0.
>>                                  self internalStackTopPut: result].
>>                 "1020   identityHash"
>>                 [20] -> [result := objectMemory hashBitsOf: self
>> internalStackTop.
>>                                  self internalStackTopPut: (objectMemory
>> integerObjectOf: result)]
>>                 "1021           identityHash (SmallInteger)"
>>                 "1022           identityHash (Character)"
>>                 "1023           identityHash (SmallFloat64)"
>>                 "1024           identityHash (Behavior)"
>>                  }
>>         otherwise:
>>                 [localIP := localIP - 3.
>>                  self respondToUnknownBytecode]!
>>
>> Item was changed:
>>   ----- Method: StackToRegisterMappingCogit>>g
>> enExtJumpIfNotInstanceOfBehaviorsOrPopBytecode (in category 'bytecode
>> generators') -----
>>   genExtJumpIfNotInstanceOfBehaviorsOrPopBytecode
>>         "SistaV1: *     254             11111110        kkkkkkkk
>> jjjjjjjj                branch If Not Instance Of Behavior/Array Of
>> Behavior kkkkkkkk (+ Extend A * 256, where Extend A >= 0) distance jjjjjjjj
>> (+ Extend B * 256, where Extend B >= 0)"
>>
>>         | reg literal distance targetFixUp |
>>
>>         "We loose the information of in which register is stack top
>>         when jitting the branch target so we need to flush everything.
>>         We could use a fixed register here...."
>>         reg := self allocateRegForStackEntryAt: 0.
>>         self ssTop popToReg: reg.
>>         self ssFlushTo: simStackPtr. "flushed but the value is still in
>> reg"
>>
>>         literal := self getLiteral: (extA * 256 + byte1).
>>         extA := 0.
>>         distance := extB * 256 + byte2.
>>         extB := 0.
>> +       numExtB := 0.
>>
>>         targetFixUp := self cCoerceSimple: (self ensureFixupAt:
>> bytecodePC + 3 + distance - initialPC) to: #'AbstractInstruction *'.
>>
>>         (objectMemory isArrayNonImm: literal)
>>                 ifTrue: [objectRepresentation branchIf: reg
>> notInstanceOfBehaviors: literal target: targetFixUp]
>>                 ifFalse: [objectRepresentation branchIf: reg
>> notInstanceOfBehavior: literal target: targetFixUp].
>>
>>         self genPopStackBytecode.
>>
>>         ^0!
>>
>> Item was changed:
>>   ----- Method: StackToRegisterMappingCogit>>genExtPushClosureBytecode
>> (in category 'bytecode generators') -----
>>   genExtPushClosureBytecode
>>         "Block compilation.  At this point in the method create the
>> block.  Note its start
>>          and defer generating code for it until after the method and any
>> other preceding
>>          blocks.  The block's actual code will be compil
>
>
> ...
>
> [Message clipped]




-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20170108/e7c5fd68/attachment-0001.html>


More information about the Vm-dev mailing list