diff --git a/smalltalksrc/Melchor/VMBasicConstants.class.st b/smalltalksrc/Melchor/VMBasicConstants.class.st index 8778dccda04..1bdbe46674a 100644 --- a/smalltalksrc/Melchor/VMBasicConstants.class.st +++ b/smalltalksrc/Melchor/VMBasicConstants.class.st @@ -12,7 +12,6 @@ Class { #superclass : 'SharedPool', #classVars : [ 'BaseHeaderSize', - 'BytecodeSetHasExtensions', 'BytesPerOop', 'BytesPerWord', 'COGVM', diff --git a/smalltalksrc/Melchor/VMClass.class.st b/smalltalksrc/Melchor/VMClass.class.st index 54a39b499e1..83991aad32e 100644 --- a/smalltalksrc/Melchor/VMClass.class.st +++ b/smalltalksrc/Melchor/VMClass.class.st @@ -401,13 +401,6 @@ VMClass class >> writeVMHeaderTo: aStream bytesPerWord: bytesPerWord generator: aStream newLine ] -{ #category : 'translation support' } -VMClass >> addressOf: anObject [ - - "Translates into &anObject in C." - ^anObject -] - { #category : 'translation support' } VMClass >> addressOf: anObject put: aBlock [ diff --git a/smalltalksrc/Slang-Tests/SlangBasicTranslationTest.class.st b/smalltalksrc/Slang-Tests/SlangBasicTranslationTest.class.st index 8ee0c03cb14..54149c10c19 100644 --- a/smalltalksrc/Slang-Tests/SlangBasicTranslationTest.class.st +++ b/smalltalksrc/Slang-Tests/SlangBasicTranslationTest.class.st @@ -6378,6 +6378,25 @@ SlangBasicTranslationTest >> testSendWordSize [ self assert: translation equals: 'BytesPerWord' ] +{ #category : 'tests-structs' } +SlangBasicTranslationTest >> testStructCastToPointer [ + + | translation tMethod | + tMethod := self getTMethodFrom: #methodAccessStructPointer. + translation := self translate: tMethod. + self + assert: translation + equals: '/* SlangBasicTranslationTestClass>>#methodAccessStructPointer */ +static Struct * +methodAccessStructPointer(void) +{ + Struct _t; + + return somethingWithStructPointer(&_t); +} +' +] + { #category : 'tests-builtins' } SlangBasicTranslationTest >> testStructFieldIsRenamedWithReservedWord [ "Tests if the struct field is renamed when it's a reserved word" diff --git a/smalltalksrc/Slang-Tests/SlangBasicTranslationTestClass.class.st b/smalltalksrc/Slang-Tests/SlangBasicTranslationTestClass.class.st index bafb4083203..c5824dc09e4 100644 --- a/smalltalksrc/Slang-Tests/SlangBasicTranslationTestClass.class.st +++ b/smalltalksrc/Slang-Tests/SlangBasicTranslationTestClass.class.st @@ -50,6 +50,17 @@ SlangBasicTranslationTestClass >> initializationOptions [ ^ nil ] +{ #category : 'inline' } +SlangBasicTranslationTestClass >> methodAccessStructPointer [ + + | t | + + + "This should automatically extract the pointer from t + somethingWithStructPointer(&t)" + ^ self somethingWithStructPointer: (self addressOf: t) +] + { #category : 'inline' } SlangBasicTranslationTestClass >> methodCallingCFunction [ @@ -373,6 +384,13 @@ SlangBasicTranslationTestClass >> methodWithoutReturn [ ] +{ #category : 'inline' } +SlangBasicTranslationTestClass >> somethingWithStructPointer: t [ + + + ^ t +] + { #category : 'inline-comment' } SlangBasicTranslationTestClass >> switchInReturn [ diff --git a/smalltalksrc/Slang/CCodeGenerator.class.st b/smalltalksrc/Slang/CCodeGenerator.class.st index a78b570d359..a89b7175199 100644 --- a/smalltalksrc/Slang/CCodeGenerator.class.st +++ b/smalltalksrc/Slang/CCodeGenerator.class.st @@ -5114,7 +5114,6 @@ CCodeGenerator >> typeForDereference: sendNode in: aTMethod [ { #category : 'C code generator' } CCodeGenerator >> typeOfVariable: varName [ "" - self assert: varName isString. scopeStack reverseDo: [ :scope | (scope declarations includesKey: varName) ifTrue: [ diff --git a/smalltalksrc/Slang/SlangClass.class.st b/smalltalksrc/Slang/SlangClass.class.st index f131f3d396d..8e84582e72a 100644 --- a/smalltalksrc/Slang/SlangClass.class.st +++ b/smalltalksrc/Slang/SlangClass.class.st @@ -77,6 +77,13 @@ SlangClass class >> typeForSelf [ ^nil ] +{ #category : 'translation support' } +SlangClass >> addressOf: anObject [ + + "Translates into &anObject in C." + ^anObject +] + { #category : 'translation support' } SlangClass >> cCall: function [ "Support for Smalltalk-to-C translation. diff --git a/smalltalksrc/VMMaker/CoInterpreter.class.st b/smalltalksrc/VMMaker/CoInterpreter.class.st index b8b62297c34..29144e74865 100644 --- a/smalltalksrc/VMMaker/CoInterpreter.class.st +++ b/smalltalksrc/VMMaker/CoInterpreter.class.st @@ -101,8 +101,6 @@ Class { 'MinBackwardJumpCountForCompile', 'PrimTraceLogSize', 'RumpCStackSize', - 'TraceBlockActivation', - 'TraceBlockCreation', 'TraceBufferSize', 'TraceCodeCompaction', 'TraceContextSwitch', @@ -113,9 +111,7 @@ Class { 'TracePrimitiveFailure', 'TracePrimitiveRetry', 'TraceSources', - 'TraceStackOverflow', - 'TraceVMCallback', - 'TraceVMCallbackReturn' + 'TraceStackOverflow' ], #pools : [ 'CogMethodConstants', @@ -285,13 +281,9 @@ CoInterpreter class >> initializeMiscConstants [ PrimTraceLogSize := 256. "Room for 256 selectors. Must be 256 because we use a byte to hold the index" TraceBufferSize := 256 * 3. "Room for 256 events" TraceContextSwitch := self objectMemoryClass basicNew integerObjectOf: 1. - TraceBlockActivation := self objectMemoryClass basicNew integerObjectOf: 2. - TraceBlockCreation := self objectMemoryClass basicNew integerObjectOf: 3. TraceIncrementalGC := self objectMemoryClass basicNew integerObjectOf: 4. TraceFullGC := self objectMemoryClass basicNew integerObjectOf: 5. TraceCodeCompaction := self objectMemoryClass basicNew integerObjectOf: 6. - TraceVMCallback := self objectMemoryClass basicNew integerObjectOf: 11. - TraceVMCallbackReturn := self objectMemoryClass basicNew integerObjectOf: 12. TraceStackOverflow := self objectMemoryClass basicNew integerObjectOf: 13. TracePrimitiveFailure := self objectMemoryClass basicNew integerObjectOf: 14. TracePrimitiveRetry := self objectMemoryClass basicNew integerObjectOf: 15. @@ -315,7 +307,6 @@ CoInterpreter class >> initializePrimitiveTable [ [:pidx| self assert: (PrimitiveTable at: pidx + 1) = #primitiveFail]. self assert: (PrimitiveTable at: 215 + 1) = #primitiveFlushCacheByMethod. PrimitiveTable - at: 253 + 1 put: #primitiveCollectCogCodeConstituents; at: 215 + 1 put: #primitiveVoidVMStateForMethod; at: 216 + 1 put: #primitiveMethodXray; at: 217 + 1 put: #primitiveMethodProfilingData @@ -1100,8 +1091,6 @@ CoInterpreter >> ceCheckAndMaybeRetryPrimitive: primIndex [ CoInterpreter >> ceCheckForInterrupts [ | switched | - self cCode: [] inSmalltalk: - [self maybeCheckStackDepth: 0 sp: stackPointer pc: instructionPointer]. switched := self checkForEventsMayContextSwitch: true. self returnToExecutive: false postContextSwitch: switched ] @@ -1440,7 +1429,6 @@ CoInterpreter >> ceSend: maybeForwardedSelector above: methodClass to: receiver - | classTag classObj | self assert: (objectMemory addressCouldBeOop: receiver). @@ -1467,7 +1455,6 @@ CoInterpreter >> ceSend: selector aboveClassBinding: methodClassBinding to: rcvr args head sp -> sender return pc" - self ceSend: selector above: (self fetchPointer: ValueIndex ofObject: (objectMemory followMaybeForwarded: methodClassBinding)) @@ -1726,48 +1713,6 @@ CoInterpreter >> ceStackOverflow: contextSwitchIfNotNil [ ] -{ #category : 'debug support' } -CoInterpreter >> ceTraceBlockActivation [ - - cogit recordBlockTrace ifTrue: - [self recordTrace: TraceBlockActivation - thing: (self mframeHomeMethod: framePointer) methodObject - source: TraceIsFromMachineCode. - cogit printOnTrace ifTrue: - [self printActivationNameFor: (self mframeHomeMethod: framePointer) methodObject - receiver: (self frameReceiver: framePointer) - isBlock: true - firstTemporary: nil. - self cr]] -] - -{ #category : 'debug support' } -CoInterpreter >> ceTraceLinkedSend: theReceiver [ - | cogMethod | - - - cogMethod := self cCoerceSimple: (self stackTop - cogit traceLinkedSendOffset) - to: #'CogMethod *'. - self cCode: [] inSmalltalk: - [cogit checkStackDepthOnSend ifTrue: - [self maybeCheckStackDepth: (cogMethod cmNumArgs > cogit numRegArgs - ifTrue: [cogMethod cmNumArgs + 1] - ifFalse: [0]) - sp: stackPointer + objectMemory wordSize - pc: (self stackValue: 1)]]. - "cogit recordSendTrace ifTrue: is implicit; wouldn't compile the call otherwise." - self recordTrace: (objectMemory fetchClassOf: theReceiver) - thing: cogMethod selector - source: TraceIsFromMachineCode. - cogit printOnTrace ifTrue: - [self printActivationNameFor: cogMethod methodObject - receiver: theReceiver - isBlock: false - firstTemporary: (self cCode: [nil] inSmalltalk: [0]); - cr]. - self sendBreakpoint: cogMethod selector receiver: theReceiver -] - { #category : 'trampolines' } CoInterpreter >> ceTraceStoreOf: aValue into: anObject [ @@ -2145,18 +2090,6 @@ CoInterpreter >> divorceSomeMachineCodeFramesWithMethod: cogMethod [ ^ divorcedSome ] -{ #category : 'send bytecodes' } -CoInterpreter >> doRecordSendTrace [ - - - cogit recordSendTrace ifTrue: [ - self - recordTrace: (objectMemory classForClassTag: lkupClassTag) - thing: messageSelector - source: TraceIsFromInterpreter. - super doRecordSendTrace ] -] - { #category : 'debug support' } CoInterpreter >> dumpPrimTraceLog [ "The prim trace log is a circular buffer of entries. If there is @@ -3604,16 +3537,6 @@ CoInterpreter >> maybeReturnToMachineCodeFrame [ instructionPointer := self pointerForOop: (self iframeSavedIP: framePointer) ] ] -{ #category : 'stack bytecodes' } -CoInterpreter >> maybeTraceBlockCreation: newClosure [ - - cogit recordSendTrace ifTrue: [ - self - recordTrace: TraceBlockCreation - thing: newClosure - source: TraceIsFromInterpreter ] -] - { #category : 'debug support' } CoInterpreter >> maybeTraceStackOverflow [ cogit recordOverflowTrace ifTrue: @@ -4329,20 +4252,12 @@ CoInterpreter >> printLogEntryAt: i [ [self print: 'stack overflow']. intOrClass = TraceContextSwitch ifTrue: [self print: 'context switch from '; printHex: selectorMethodOrProcess]. - intOrClass = TraceBlockActivation ifTrue: - [self print: ' [] in '; printHex: selectorMethodOrProcess]. - intOrClass = TraceBlockCreation ifTrue: - [self print: 'create [] '; printHex: selectorMethodOrProcess]. intOrClass = TraceIncrementalGC ifTrue: [self print: 'incrementalGC']. intOrClass = TraceFullGC ifTrue: [self print: 'fullGC']. intOrClass = TraceCodeCompaction ifTrue: - [self print: 'compactCode']. - intOrClass = TraceVMCallback ifTrue: - [self print: 'callback']. - intOrClass = TraceVMCallbackReturn ifTrue: - [self print: 'return from callback']] + [self print: 'compactCode'] ] ifFalse: [self space; printNameOfClass: intOrClass count: 5; print: '>>'; printStringOf: selectorMethodOrProcess]. source > TraceIsFromInterpreter ifTrue: @@ -4447,12 +4362,6 @@ CoInterpreter >> printPrimLogEntryAt: i [ ifFalse: [objectMemory safePrintStringOf: intOrSelector]] ] -{ #category : 'debug printing' } -CoInterpreter >> printSends [ - - ^cogit printOnTrace -] - { #category : 'cog jit support' } CoInterpreter >> quickPrimitiveConstantFor: aQuickPrimitiveIndex [ @@ -4692,8 +4601,6 @@ CoInterpreter >> returnToMachineCodeFrame [ line: #__LINE__. self stackTopPut: instructionPointer. self push: localReturnValue. - self cCode: '' inSmalltalk: [ - self maybeCheckStackDepth: 1 sp: stackPointer pc: instructionPointer ]. self callEnilopmart: #ceEnterCogCodePopReceiverReg. self unreachable ] diff --git a/smalltalksrc/VMMaker/CoInterpreterPrimitives.class.st b/smalltalksrc/VMMaker/CoInterpreterPrimitives.class.st index bf525949417..331ca647f41 100644 --- a/smalltalksrc/VMMaker/CoInterpreterPrimitives.class.st +++ b/smalltalksrc/VMMaker/CoInterpreterPrimitives.class.st @@ -60,27 +60,6 @@ CoInterpreterPrimitives >> primitiveAllMethodsCompiledToMachineCode [ self pop: 1 thenPush: arrayObj ] -{ #category : 'process primitives' } -CoInterpreterPrimitives >> primitiveCollectCogCodeConstituents [ - "Answer the contents of the code zone as an array of pair-wise element, address in ascending - address order. Answer a string for a runtime routine or abstract label (beginning, end, etc), - a CompiledMethod for a CMMethod, or a selector (presumably a Symbol) for a PIC. - If there is an argument and it is true, then collect inner information about the CogMethod." - | constituents withDetails | - argumentCount = 0 - ifTrue: [withDetails := false] - ifFalse: - [withDetails := self stackTop. - (withDetails = objectMemory trueObject - or: [withDetails = objectMemory falseObject]) ifFalse: - [^self primitiveFailFor: PrimErrBadArgument]. - withDetails := withDetails = objectMemory trueObject]. - constituents := cogit cogCodeConstituents: withDetails. - constituents ifNil: - [^self primitiveFailFor: PrimErrNoMemory]. - self pop: argumentCount + 1 thenPush: constituents -] - { #category : 'indexing primitives' } CoInterpreterPrimitives >> primitiveContextXray [ "Lift the veil from a context and answer an integer describing its interior state. diff --git a/smalltalksrc/VMMaker/CogBytecodeFixup.class.st b/smalltalksrc/VMMaker/CogBytecodeFixup.class.st index dee41bb7779..0898bc50f0c 100644 --- a/smalltalksrc/VMMaker/CogBytecodeFixup.class.st +++ b/smalltalksrc/VMMaker/CogBytecodeFixup.class.st @@ -62,8 +62,6 @@ CogBytecodeFixup class >> instVarNamesAndTypesForTranslationDo: aBinaryBlock [ ['mergeSimStack'] -> [#'SimStackEntry *']. ['instructionIndex'] -> [#'unsigned short']. ['simStackPtr'] -> [#'unsigned char']. - ['simNativeStackPtr'] -> [#'short']. - ['simNativeStackSize'] -> [#'unsigned short']. ['isTargetOfBackwardBranch'] -> [#char] }])] ] diff --git a/smalltalksrc/VMMaker/CogCompileTimeStackState.class.st b/smalltalksrc/VMMaker/CogCompileTimeStackState.class.st new file mode 100644 index 00000000000..bc86deee86e --- /dev/null +++ b/smalltalksrc/VMMaker/CogCompileTimeStackState.class.st @@ -0,0 +1,136 @@ +Class { + #name : 'CogCompileTimeStackState', + #superclass : 'VMStructType', + #instVars : [ + 'simStack', + 'simStackPtr', + 'simSpillBase' + ], + #category : 'VMMaker-JIT', + #package : 'VMMaker', + #tag : 'JIT' +} + +{ #category : 'translation' } +CogCompileTimeStackState class >> instVarNamesAndTypesForTranslationDo: aBinaryBlock [ + "Enumerate aBinaryBlock with the names and C type strings for the inst vars to include in a BytecodeFixup struct." + + "self withAllSubclasses collect: [:ea| ea typedef]" + + self filteredInstVarNames do: [ :ivn | + aBinaryBlock value: ivn value: (ivn first ~= $# ifTrue: [ + ivn caseOf: { + ([ 'simStack' ] -> [ {'SimStackEntry' .'[' , StackToRegisterMappingCogit simStackSlots asString , ']'} ]). + ([ 'simStackPtr' ] -> [ #'unsigned char' ]). + ([ 'simSpillBase' ] -> [ #'unsigned char' ]) } ]) ] +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> printSimStack: aSimStack toDepth: limit spillBase: spillBase on: aStream [ + + + aStream newLine. + limit < 0 ifTrue: [ + ^ aStream + nextPutAll: 'simStackEmpty'; + cr; + flush ]. + aSimStack ifNil: [ + ^ aStream + nextPutAll: 'nil simStack'; + cr; + flush ]. + 0 to: limit do: [ :i | + aStream print: i. + i = simStackPtr ifTrue: [ aStream nextPutAll: '<-' ]. + i = spillBase ifTrue: [ aStream nextPutAll: '(sb)' ]. + aStream tab: (i = spillBase + ifTrue: [ 1 ] + ifFalse: [ 2 ]). + aStream + cr; + flush ]. + simSpillBase > limit ifTrue: [ + aStream + nextPutAll: '(sb: '; + print: simSpillBase; + nextPut: $); + cr; + flush ] +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simSpillBase [ + + ^ simSpillBase +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simSpillBase: anObject [ + + simSpillBase := anObject +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStack [ + + ^ simStack +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStack: anObject [ + + simStack := anObject +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStackAt: index [ + + ^self addressOf: (simStack at: index) +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStackAt: index put: simStackEntry [ + + + simStack at: index put: simStackEntry +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStackDescriptorAt: index [ + + + ^ simStack at: index +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStackPrintString [ + + ^String streamContents: [:s| self printSimStack: simStack toDepth: simStackPtr spillBase: simSpillBase on: s] +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStackPtr [ + + ^ simStackPtr +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> simStackPtr: anObject [ + + ^ simStackPtr := anObject +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> ssTop [ + + ^self simStackAt: simStackPtr +] + +{ #category : 'accessing' } +CogCompileTimeStackState >> ssTopDescriptor [ + + + + ^ self simStackDescriptorAt: simStackPtr +] diff --git a/smalltalksrc/VMMaker/CogObjectRepresentationForSpur.class.st b/smalltalksrc/VMMaker/CogObjectRepresentationForSpur.class.st index 2346db98265..7edd77f3237 100644 --- a/smalltalksrc/VMMaker/CogObjectRepresentationForSpur.class.st +++ b/smalltalksrc/VMMaker/CogObjectRepresentationForSpur.class.st @@ -2670,7 +2670,6 @@ CogObjectRepresentationForSpur >> genStoreHeader: header intoNewInstance: rcvrRe { #category : 'compile abstract instructions' } CogObjectRepresentationForSpur >> genStoreSourceReg: sourceReg slotIndex: index destReg: destReg scratchReg: scratchReg inFrame: inFrame needsStoreCheck: needsStoreCheck [ - cogit genTraceStores. "do the store" cogit MoveR: sourceReg Mw: index * objectMemory wordSize + objectMemory baseHeaderSize @@ -2837,8 +2836,6 @@ CogObjectRepresentationForSpur >> genStoreWithImmutabilityAndStoreCheckSourceReg immutableJump := self genJumpImmutable: destReg scratchReg: scratchReg. - cogit genTraceStores. - "do the store" cogit MoveR: sourceReg Mw: index * objectMemory wordSize + objectMemory baseHeaderSize @@ -2896,8 +2893,6 @@ CogObjectRepresentationForSpur >> genStoreWithImmutabilityButNoStoreCheckSourceR immutabilityFailure := cogit Jump: 0. mutableJump jmpTarget: cogit Label. - cogit genTraceStores. - "do the store" cogit MoveR: sourceReg Mw: index * objectMemory wordSize + objectMemory baseHeaderSize diff --git a/smalltalksrc/VMMaker/CogRASSBytecodeFixup.class.st b/smalltalksrc/VMMaker/CogRASSBytecodeFixup.class.st deleted file mode 100644 index c8d53bd2a0a..00000000000 --- a/smalltalksrc/VMMaker/CogRASSBytecodeFixup.class.st +++ /dev/null @@ -1,93 +0,0 @@ -" -A CogRASSBytecodeFixup extends CogSSBytecodeFixup with state to merge the stack at control-flow joins, preserving register contents. By holding onto the entire stack state a CogRASSBytecodeFixup allows RegisterAllocatingCogit to merge individual stack entries, instead of merely spilling to the same height. - -Instance Variables - cogit: - mergeSimStack: - -cogit - - the JIT compiler - -mergeSimStack - - the state of the stack at the jump to this fixup -" -Class { - #name : 'CogRASSBytecodeFixup', - #superclass : 'CogSSBytecodeFixup', - #instVars : [ - 'cogit', - 'mergeSimStack' - ], - #category : 'VMMaker-JIT', - #package : 'VMMaker', - #tag : 'JIT' -} - -{ #category : 'translation' } -CogRASSBytecodeFixup class >> filteredInstVarNames [ - "Override to group char and short vars together for compactness. - self typedef" - | vars | - vars := super filteredInstVarNames asOrderedCollection. - vars - remove: 'mergeSimStack'; - add: 'mergeSimStack' afterIndex: (vars indexOf: 'targetInstruction'). - ^vars -] - -{ #category : 'instance creation' } -CogRASSBytecodeFixup class >> for: aCogit [ - ^self new cogit: aCogit -] - -{ #category : 'initialize-release' } -CogRASSBytecodeFixup >> cogit: aCogit [ - cogit := aCogit. - ^self -] - -{ #category : 'debug printing' } -CogRASSBytecodeFixup >> hasMergeSimStack [ - ^self needsFixup and: [mergeSimStack notNil] -] - -{ #category : 'accessing' } -CogRASSBytecodeFixup >> mergeSimStack [ - - ^mergeSimStack -] - -{ #category : 'accessing' } -CogRASSBytecodeFixup >> mergeSimStack: anObject [ - - ^mergeSimStack := anObject -] - -{ #category : 'debug printing' } -CogRASSBytecodeFixup >> printStateOn: aStream [ - - (targetInstruction isNil and: [simStackPtr isNil]) ifTrue: - [^self]. - super printStateOn: aStream. - mergeSimStack ifNotNil: - [aStream skip: -1; space; nextPut: $(. - cogit printSimStack: mergeSimStack toDepth: simStackPtr spillBase: -1 on: aStream. - aStream nextPut: $); nextPut: $)] -] - -{ #category : 'accessing' } -CogRASSBytecodeFixup >> reinitialize [ - - super reinitialize. - mergeSimStack := nil -] - -{ #category : 'debug printing' } -CogRASSBytecodeFixup >> simStackPrintString [ - - ^String streamContents: - [:s| - self notAFixup - ifTrue: [s nextPutAll: 'notAFixup'] - ifFalse: [cogit printSimStack: mergeSimStack toDepth: simStackPtr spillBase: -1 on: s]] -] diff --git a/smalltalksrc/VMMaker/CogSSBytecodeFixup.class.st b/smalltalksrc/VMMaker/CogSSBytecodeFixup.class.st index 23c8253883d..1250ecaaeb2 100644 --- a/smalltalksrc/VMMaker/CogSSBytecodeFixup.class.st +++ b/smalltalksrc/VMMaker/CogSSBytecodeFixup.class.st @@ -16,9 +16,7 @@ Class { #superclass : 'CogBytecodeFixup', #instVars : [ 'simStackPtr', - 'isTargetOfBackwardBranch', - 'simNativeStackPtr', - 'simNativeStackSize' + 'isTargetOfBackwardBranch' ], #classVars : [ 'NeedsMergeFixupFlag', @@ -184,20 +182,6 @@ CogSSBytecodeFixup >> setIsBackwardBranchFixup [ isTargetOfBackwardBranch := true ] -{ #category : 'accessing' } -CogSSBytecodeFixup >> simNativeStackSize [ - "Answer the value of simStackPtr" - - ^ simNativeStackSize -] - -{ #category : 'accessing' } -CogSSBytecodeFixup >> simNativeStackSize: anObject [ - "Set the value of simStackPtr" - - ^simNativeStackSize := anObject -] - { #category : 'accessing' } CogSSBytecodeFixup >> simStackPtr [ "Answer the value of simStackPtr" diff --git a/smalltalksrc/VMMaker/CogSSOptStatus.class.st b/smalltalksrc/VMMaker/CogSSOptStatus.class.st deleted file mode 100644 index 0dc0111f0e7..00000000000 --- a/smalltalksrc/VMMaker/CogSSOptStatus.class.st +++ /dev/null @@ -1,67 +0,0 @@ -Class { - #name : 'CogSSOptStatus', - #superclass : 'VMStructType', - #instVars : [ - 'isReceiverResultRegLive', - 'ssEntry' - ], - #category : 'VMMaker-JIT', - #package : 'VMMaker', - #tag : 'JIT' -} - -{ #category : 'translation' } -CogSSOptStatus class >> instVarNamesAndTypesForTranslationDo: aBinaryBlock [ - "enumerate aBinaryBlock with the names and C type strings for the inst vars to include in a CogSSOptStatus struct." - - self instVarNames do: - [:ivn| - aBinaryBlock - value: ivn - value: (ivn = 'ssEntry' - ifTrue: [#'CogSimStackEntry *'] - ifFalse: [#sqInt])] -] - -{ #category : 'accessing' } -CogSSOptStatus >> isReceiverResultRegLive [ - "Answer the value of isReceiverResultRegLive" - - ^ isReceiverResultRegLive -] - -{ #category : 'accessing' } -CogSSOptStatus >> isReceiverResultRegLive: anObject [ - "Set the value of isReceiverResultRegLive" - - ^isReceiverResultRegLive := anObject -] - -{ #category : 'printing' } -CogSSOptStatus >> printStateOn: aStream [ - - (isReceiverResultRegLive notNil - or: [ssEntry notNil]) ifTrue: - [aStream - nextPut: $(; - print: isReceiverResultRegLive; - space. - ssEntry - ifNil: [aStream nextPutAll: 'ssEntry is nil'] - ifNotNil: [ssEntry printStateOn: aStream]. - aStream nextPut: $)] -] - -{ #category : 'accessing' } -CogSSOptStatus >> ssEntry [ - "Answer the value of ssEntry" - - ^ ssEntry -] - -{ #category : 'accessing' } -CogSSOptStatus >> ssEntry: anObject [ - "Set the value of ssEntry" - - ^ssEntry := anObject -] diff --git a/smalltalksrc/VMMaker/CogSimStackEntry.class.st b/smalltalksrc/VMMaker/CogSimStackEntry.class.st index 25df8a11be1..6bf407acf09 100644 --- a/smalltalksrc/VMMaker/CogSimStackEntry.class.st +++ b/smalltalksrc/VMMaker/CogSimStackEntry.class.st @@ -167,7 +167,6 @@ CogSimStackEntry >> ensureSpilledAt: baseOffset from: baseRegister [ [self assert: ((offset = baseOffset and: [registerr = baseRegister]) or: [cogit violatesEnsureSpilledSpillAssert]). ^self]]. self assert: type ~= SSSpill. - cogit traceSpill: self. type = SSConstant ifTrue: [inst := cogit genPushConstant: constant] diff --git a/smalltalksrc/VMMaker/CogStackToRegisterCompilationState.class.st b/smalltalksrc/VMMaker/CogStackToRegisterCompilationState.class.st new file mode 100644 index 00000000000..57359b1eec9 --- /dev/null +++ b/smalltalksrc/VMMaker/CogStackToRegisterCompilationState.class.st @@ -0,0 +1,111 @@ +Class { + #name : 'CogStackToRegisterCompilationState', + #superclass : 'VMStructType', + #instVars : [ + 'deadCode', + 'methodOrBlockNumTemps', + 'prevBCDescriptor', + 'regArgsHaveBeenPushed', + 'useTwoPaths', + 'simStackStateField' + ], + #category : 'VMMaker-JIT', + #package : 'VMMaker', + #tag : 'JIT' +} + +{ #category : 'translation' } +CogStackToRegisterCompilationState class >> instVarNamesAndTypesForTranslationDo: aBinaryBlock [ + "Enumerate aBinaryBlock with the names and C type strings for the inst vars to include in a BytecodeFixup struct." + + "self withAllSubclasses collect: [:ea| self typedef]" + + self filteredInstVarNames do: [ :ivn | + aBinaryBlock value: ivn value: (ivn first ~= $# ifTrue: [ + ivn caseOf: { + ([ 'deadCode' ] -> [ #sqInt ]). + ([ 'methodOrBlockNumTemps' ] -> [ #sqInt ]). + ([ 'prevBCDescriptor' ] -> [ #'BytecodeDescriptor *' ]). + ([ 'regArgsHaveBeenPushed' ] -> [ #sqInt ]). + ([ 'simStackStateField' ] -> [ #CogCompileTimeStackState ]). + ([ 'useTwoPaths' ] -> [ #sqInt ]) } ]) ] +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> deadCode [ + + ^ deadCode +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> deadCode: anObject [ + + deadCode := anObject +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> methodOrBlockNumTemps [ + + ^ methodOrBlockNumTemps +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> methodOrBlockNumTemps: anObject [ + + methodOrBlockNumTemps := anObject +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> prevBCDescriptor [ + + ^ prevBCDescriptor +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> prevBCDescriptor: anObject [ + + prevBCDescriptor := anObject +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> regArgsHaveBeenPushed [ + + ^ regArgsHaveBeenPushed +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> regArgsHaveBeenPushed: anObject [ + + regArgsHaveBeenPushed := anObject +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> simStackState [ + + + ^ self addressOf: self simStackStateField +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> simStackStateField [ + + ^ simStackStateField +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> simStackStateField: anObject [ + + simStackStateField := anObject +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> useTwoPaths [ + + ^ useTwoPaths +] + +{ #category : 'accessing' } +CogStackToRegisterCompilationState >> useTwoPaths: anObject [ + + useTwoPaths := anObject +] diff --git a/smalltalksrc/VMMaker/CogVMSimulator.class.st b/smalltalksrc/VMMaker/CogVMSimulator.class.st index f5ba6d5d780..e1d1816f845 100644 --- a/smalltalksrc/VMMaker/CogVMSimulator.class.st +++ b/smalltalksrc/VMMaker/CogVMSimulator.class.st @@ -457,16 +457,6 @@ CogVMSimulator >> cr [ traceOn ifTrue: [ transcript cr; flush ]. ] -{ #category : 'debug support' } -CogVMSimulator >> debugStackPointersFor: aMethod [ - ^CArrayAccessor on: - (StackDepthFinder on: (VMCompiledMethodProxy new - for: aMethod - coInterpreter: self - objectMemory: objectMemory)) - stackPointers -] - { #category : 'initialization' } CogVMSimulator >> desiredCogCodeSize: anInteger [ desiredCogCodeSize := anInteger @@ -1086,42 +1076,6 @@ CogVMSimulator >> mappedPluginEntries [ ^mappedPluginEntries ] -{ #category : 'debug support' } -CogVMSimulator >> maybeCheckStackDepth: delta sp: sp pc: mcpc [ - - | asp bcpc startbcpc cogMethod csp debugStackPointers | - debugStackDepthDictionary ifNil: [ ^ self ]. - (self isMachineCodeFrame: framePointer) ifFalse: [ ^ self ]. - cogMethod := self mframeCogMethod: framePointer. - debugStackPointers := debugStackDepthDictionary - at: cogMethod methodObject - ifAbsentPut: [ - self debugStackPointersFor: - cogMethod methodObject ]. - startbcpc := self startPCOfMethod: cogMethod methodObject. - bcpc := cogit bytecodePCFor: mcpc startBcpc: startbcpc in: cogMethod. - self assert: bcpc ~= 0. - (cogMethod cmIsFullBlock and: [ cogit isNonLocalReturnPC: mcpc ]) - ifTrue: [ - | lastbcpc | - "Method returns within a block (within an unwind-protect) must check the stack depth at the - return, not the bytecode following, but the pc mapping maps to the bytecode following the - return. lastBytecodePCForBlockAt:in: catches method returns at the end of a block, modifying - the bcpc to that of the return. isNonLocalReturnPC: catches method returns not at the end. - Assumes method return bytecodes are 1 bytecode long;a dodgy assumption, but good enough." - lastbcpc := cogit endPCOf: cogMethod methodObject. - bcpc > lastbcpc ifTrue: [ bcpc := lastbcpc ] ]. - asp := self - stackPointerIndexForFrame: framePointer - WithSP: sp + objectMemory wordSize. - csp := debugStackPointers at: bcpc ifAbsent: [ -1 ]. - "Compensate for some edge cases" - asp - delta = csp ifTrue: [ "Compensate for the implicit context receiver push in a trap bytecode with the absence of a contnuation. - Assumes trap bytecodes are 1 byte bytecodes." - (SistaVM and: [ cogit isTrapAt: mcpc ]) ifTrue: [ csp := csp + 1 ] ]. - self assert: asp - delta + 1 = csp -] - { #category : 'primitive support' } CogVMSimulator >> maybeMapPrimitiveFunctionPointerBackToSomethingEvaluable [ "In the real VM primitiveFunctionPointer is either an index (for quick primitives) diff --git a/smalltalksrc/VMMaker/Cogit.class.st b/smalltalksrc/VMMaker/Cogit.class.st index f6e70810e6d..106ac53f56d 100644 --- a/smalltalksrc/VMMaker/Cogit.class.st +++ b/smalltalksrc/VMMaker/Cogit.class.st @@ -121,19 +121,11 @@ Class { 'methodZoneBase', 'codeBase', 'minValidCallAddress', - 'lastNInstructions', 'simulatedAddresses', 'simulatedTrampolines', 'simulatedVariableGetters', 'simulatedVariableSetters', - 'printRegisters', - 'printInstructions', - 'compilationTrace', - 'clickConfirm', - 'singleStep', - 'guardPageSize', 'traceFlags', - 'traceStores', 'methodObj', 'enumeratingCogMethod', 'methodHeader', @@ -198,9 +190,6 @@ Class { 'ceEnclosingObjectTrampoline', 'ceFlushICache', 'ceCheckFeaturesFunction', - 'ceTraceLinkedSendTrampoline', - 'ceTraceBlockActivationTrampoline', - 'ceTraceStoreTrampoline', 'ceGetFP', 'ceGetSP', 'ceCaptureCStackPointers', @@ -218,9 +207,6 @@ Class { 'objectReferencesInRuntime', 'runtimeObjectRefIndex', 'cFramePointerInUse', - 'debugPrimCallStackOffset', - 'ceTryLockVMOwner', - 'ceUnlockVMOwner', 'extA', 'extB', 'numExtB', @@ -231,8 +217,6 @@ Class { 'CFramePointer', 'ceMallocTrampoline', 'ceFreeTrampoline', - 'disassemblingMethod', - 'cogConstituentIndex', 'directedSendUsesBinding', 'simulateFPInUse', 'statCompileFullBlockCount', @@ -426,12 +410,10 @@ Cogit class >> declareCVarsIn: aCCodeGenerator [ #( 'coInterpreter' 'objectMemory' 'methodZone' 'objectRepresentation' 'cogMethodSurrogateClass' - 'processor' 'lastNInstructions' 'simulatedAddresses' + 'processor' 'simulatedAddresses' 'simulatedTrampolines' 'simulatedVariableGetters' - 'simulatedVariableSetters' 'printRegisters' 'printInstructions' - 'clickConfirm' 'singleStep' ) do: [ - :simulationVariableNotNeededForRealVM | - aCCodeGenerator removeVariable: simulationVariableNotNeededForRealVM ]. + 'simulatedVariableSetters' ) do: [ :simulationVariableNotNeededForRealVM | + aCCodeGenerator removeVariable: simulationVariableNotNeededForRealVM ]. aCCodeGenerator addHeaderFile: ''; @@ -505,13 +487,12 @@ Cogit class >> declareCVarsIn: aCCodeGenerator [ declareC: 'sqInt ordinarySendTrampolines[NumSendTrampolines]'; var: #superSendTrampolines declareC: 'sqInt superSendTrampolines[NumSendTrampolines]'. - BytecodeSetHasDirectedSuperSend ifTrue: [ - aCCodeGenerator - var: #directedSuperSendTrampolines - declareC: 'sqInt directedSuperSendTrampolines[NumSendTrampolines]'; - var: #directedSuperBindingSendTrampolines - declareC: - 'sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]' ]. + aCCodeGenerator + var: #directedSuperSendTrampolines + declareC: 'sqInt directedSuperSendTrampolines[NumSendTrampolines]'; + var: #directedSuperBindingSendTrampolines + declareC: + 'sqInt directedSuperBindingSendTrampolines[NumSendTrampolines]'. aCCodeGenerator var: #trampolineAddresses declareC: 'static char *trampolineAddresses[NumTrampolines*2]'; @@ -654,11 +635,6 @@ Cogit class >> generatorTableFrom: anArray [ ^generatorTable ] -{ #category : 'accessing' } -Cogit class >> guardPageSize [ - ^1024 -] - { #category : 'translation' } Cogit class >> implicitReturnTypeFor: aSelector [ "Answer the return type for methods that don't have an explicit return." @@ -722,9 +698,8 @@ Cogit class >> initializeAnnotationConstants [ IsSendCall := 7. "These are formed by combining IsSendCall and IsAnnotationExtension annotations." IsSuperSend := 8. - - IsDirectedSuperSend := BytecodeSetHasDirectedSuperSend ifTrue: [9]. - IsDirectedSuperBindingSend := BytecodeSetHasDirectedSuperSend ifTrue: [10]. + IsDirectedSuperSend := 9. + IsDirectedSuperBindingSend := 10. DisplacementMask := (1 << AnnotationShift) - 1. DisplacementX2N := IsDisplacementX2N << AnnotationShift. @@ -767,7 +742,6 @@ Cogit class >> initializeBytecodeTable [ "StackToRegisterMappingCogit initializeBytecodeTableWith: Dictionary new" | initializer | - BytecodeSetHasDirectedSuperSend := BytecodeSetHasExtensions := false. initializer := InitializationOptions at: #bytecodeTableInitializer ifAbsent: [ #initializeBytecodeTableForSistaV1 ]. @@ -841,7 +815,7 @@ Cogit class >> initializeMiscConstants [ Cogit class >> initializeNumTrampolines [ NumTrampolines := self numTrampolines + self objectRepresentationClass numTrampolines - + (BytecodeSetHasDirectedSuperSend ifTrue: [NumSendTrampolines * 2] ifFalse: [0]) + + (NumSendTrampolines * 2) ] { #category : 'class initialization' } @@ -1196,18 +1170,17 @@ Cogit class >> mustBeGlobalAndExport: var [ only used outside of Cogit by the object representation). Include CFramePointer CStackPointer as a hack to get them declared at all." - ^#( 'ceBaseFrameReturnTrampoline' #ceCaptureCStackPointers 'ceCheckForInterruptTrampoline' - ceEnterCogCodePopReceiverReg realCEEnterCogCodePopReceiverReg - ceCallCogCodePopReceiverReg realCECallCogCodePopReceiverReg - ceCallCogCodePopReceiverAndClassRegs realCECallCogCodePopReceiverAndClassRegs - 'ceReturnToInterpreterTrampoline' 'ceCannotResumeTrampoline' - ceTryLockVMOwner ceUnlockVMOwner - 'cmEntryOffset' 'cmNoCheckEntryOffset' 'cmDynSuperEntryOffset' 'cmSelfSendEntryOffset' - 'missOffset' 'cbEntryOffset' 'cbNoSwitchEntryOffset' 'blockNoContextSwitchOffset' - CFramePointer CStackPointer 'cFramePointerInUse' ceGetFP ceGetSP - traceFlags 'traceStores' debugPrimCallStackOffset) - includes: var - + ^ #( 'ceBaseFrameReturnTrampoline' #ceCaptureCStackPointers + 'ceCheckForInterruptTrampoline' ceEnterCogCodePopReceiverReg + realCEEnterCogCodePopReceiverReg + ceCallCogCodePopReceiverReg realCECallCogCodePopReceiverReg + ceCallCogCodePopReceiverAndClassRegs + realCECallCogCodePopReceiverAndClassRegs + 'ceReturnToInterpreterTrampoline' + 'ceCannotResumeTrampoline' 'cmEntryOffset' 'cmNoCheckEntryOffset' + 'missOffset' 'cbEntryOffset' 'cbNoSwitchEntryOffset' + CFramePointer CStackPointer 'cFramePointerInUse' + ceGetFP ceGetSP traceFlags ) includes: var ] { #category : 'translation' } @@ -1356,7 +1329,7 @@ Cogit class >> runtime [ { #category : 'translation' } Cogit class >> shouldGenerateTypedefFor: aStructClass [ "Hack to work-around mutliple definitions. Sometimes a type has been defined in an include." - ^({ CogMethod. SistaCogMethod } includes: aStructClass) not + ^ CogMethod ~= aStructClass ] { #category : 'translation' } @@ -3199,12 +3172,12 @@ Cogit >> annotationForMcpc: mcpc in: cogHomeMethod [ { #category : 'in-line cacheing' } Cogit >> annotationIsForUncheckedEntryPoint: annotation [ + - ^annotation = IsSuperSend - or: [BytecodeSetHasDirectedSuperSend - and: [annotation - between: IsDirectedSuperSend - and: IsDirectedSuperBindingSend]] + ^ annotation = IsSuperSend or: [ + annotation + between: IsDirectedSuperSend + and: IsDirectedSuperBindingSend ] ] { #category : 'simulation only' } @@ -3389,13 +3362,6 @@ Cogit >> blockDispatchTargetsFor: cogMethod perform: binaryFunction arg: arg [ ^0 ] -{ #category : 'debugging' } -Cogit >> breakOnImplicitReceiver [ - - - ^(traceFlags bitAnd: 64) ~= 0 -] - { #category : 'accessing' } Cogit >> byte1: anInteger [ @@ -4166,12 +4132,6 @@ Cogit >> checkMaybeObjRefInPIC: maybeObject [ ^objectRepresentation checkValidObjectReference: maybeObject ] -{ #category : 'debugging' } -Cogit >> checkStackDepthOnSend [ - - ^(traceFlags bitAnd: 128) ~= 0 -] - { #category : 'garbage collection' } Cogit >> checkValidObjectReferencesInPIC: aPIC [ @@ -4266,9 +4226,6 @@ Cogit >> cog: aMethodObj selector: aSelectorOop [ | selector cogMethod startTime | - (self exclude: aMethodObj selector: aSelectorOop) ifTrue: - [^nil]. - startTime := coInterpreter ioUTCMicrosecondsNow. self deny: (coInterpreter methodHasCogMethod: aMethodObj). @@ -4307,115 +4264,6 @@ Cogit >> cogCodeBase: anInteger [ ] -{ #category : 'profiling primitives' } -Cogit >> cogCodeConstituents: withDetails [ - - "Answer the contents of the code zone as an array of pair-wise element, address in ascending address order. - Answer a string for a runtime routine or abstract label (beginning, end, etc), a CompiledMethod for a CMMethod, - or a selector (presumably a Symbol) for a PIC. - If withDetails is true - - answer machine-code to bytecode pc mapping information for methods - - answer class, target pair information for closed PIC - N.B. Since the class tag for the first case of a closed PIC is stored at the send site, it must be collected - by scanning methods (see collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method:). Since closed PICs - are never shared they always come after the method that references them, so we don't need an extra pass - to collect the first case class tags, which are (temporarily) assigned to each closed PIC's methodObject field. - But we do need to reset the methodObject fields to zero. This is done in createPICData:, unless memory - runs out, in which case it is done by cleanUpFailingCogCodeConstituents:." - - - - | count cogMethod constituents label value | - count := trampolineTableIndex / 2 + 3. "+ 3 for start, freeStart and end" - cogMethod := self cCoerceSimple: methodZoneBase to: #'CogMethod *'. - [ cogMethod < methodZone limitZony ] whileTrue: [ - cogMethod cmType ~= CMFree ifTrue: [ count := count + 1 ]. - cogMethod := methodZone methodAfter: cogMethod ]. - constituents := coInterpreter - instantiateClass: coInterpreter classArray - indexableSize: count * 2. - constituents ifNil: [ ^ constituents ]. - coInterpreter pushRemappableOop: constituents. - ((label := objectMemory stringForCString: 'CogCode') isNil or: [ - (value := self positiveMachineIntegerFor: codeBase) isNil ]) - ifTrue: [ - coInterpreter popRemappableOop. - ^ nil ]. - coInterpreter - storePointerUnchecked: 0 ofObject: constituents withValue: label; - storePointerUnchecked: 1 ofObject: constituents withValue: value. - 0 to: trampolineTableIndex - 1 by: 2 do: [ :i | - ((label := objectMemory stringForCString: - (trampolineAddresses at: i)) isNil or: [ - (value := self positiveMachineIntegerFor: - (trampolineAddresses at: i + 1) asUnsignedInteger) - isNil ]) ifTrue: [ - coInterpreter popRemappableOop. - ^ nil ]. - coInterpreter - storePointerUnchecked: 2 + i - ofObject: constituents - withValue: label; - storePointerUnchecked: 3 + i - ofObject: constituents - withValue: value ]. - count := trampolineTableIndex + 2. - cogMethod := self cCoerceSimple: methodZoneBase to: #'CogMethod *'. - [ cogMethod < methodZone limitZony ] whileTrue: [ - cogMethod cmType ~= CMFree ifTrue: [ - | profileData | - profileData := self - profileDataFor: cogMethod - withDetails: withDetails. - profileData ifNil: [ - ^ self cleanUpFailingCogCodeConstituents: cogMethod ]. - coInterpreter - storePointerUnchecked: count - ofObject: constituents - withValue: profileData. - value := withDetails - ifTrue: [ self collectCogMethodConstituent: cogMethod ] - ifFalse: [ - self positiveMachineIntegerFor: - cogMethod asUnsignedInteger ]. - value ifNil: [ ^ self cleanUpFailingCogCodeConstituents: cogMethod ]. - coInterpreter - storePointerUnchecked: count + 1 - ofObject: constituents - withValue: value. - count := count + 2 ]. - cogMethod := methodZone methodAfter: cogMethod ]. - ((label := objectMemory stringForCString: 'CCFree') isNil or: [ - (value := self positiveMachineIntegerFor: methodZone zoneFree) - isNil ]) ifTrue: [ - coInterpreter popRemappableOop. - ^ nil ]. - coInterpreter - storePointerUnchecked: count - ofObject: constituents - withValue: label; - storePointerUnchecked: count + 1 - ofObject: constituents - withValue: value. - ((label := objectMemory stringForCString: 'CCEnd') isNil or: [ - (value := self positiveMachineIntegerFor: methodZone zoneEnd) isNil ]) - ifTrue: [ - coInterpreter popRemappableOop. - ^ nil ]. - coInterpreter - storePointerUnchecked: count + 2 - ofObject: constituents - withValue: label; - storePointerUnchecked: count + 3 - ofObject: constituents - withValue: value. - constituents := coInterpreter popRemappableOop. - coInterpreter beRootIfOld: constituents. - "would like to assert this, but it requires the leak checked be run :-( - self assert: self allMachineCodeObjectReferencesValid." - ^ constituents -] - { #category : 'in-line cacheing' } Cogit >> cogExtendPIC: aPIC CaseNMethod: caseNMethod tag: caseNTag isMNUCase: isMNUCase [ "Extend the aPIC with the supplied case. If caseNMethod is cogged dispatch direct to @@ -4469,11 +4317,7 @@ Cogit >> cogFullBlockMethod: aMethodObj numCopied: numCopied [ - | cogMethod startTime ultimateLiteral | - - (self exclude: aMethodObj) ifTrue: - [^nil]. - + | cogMethod startTime ultimateLiteral | startTime := coInterpreter ioUTCMicrosecondsNow. objectRepresentation ensureNoForwardedLiteralsIn: aMethodObj. ultimateLiteral := coInterpreter ultimateLiteralOf: aMethodObj. @@ -4725,92 +4569,6 @@ Cogit >> cogitPostGCAction: gcMode [ methodZone kosherYoungReferrers ]) ] -{ #category : 'multi-threading' } -Cogit >> cogitTryLockVMOwner [ - - "ceTryLockVMOwner does an atomic swap of the lock with 1 and - then subtracts 1from lock's value. So if the result is 0 the lock was - already held. Anything else (in fact -1) implies we hold the lock." - - ^(self simulateLeafCallOf: ceTryLockVMOwner) ~= 0 -] - -{ #category : 'multi-threading' } -Cogit >> cogitUnlockVMOwner [ - - - ^self simulateLeafCallOf: ceUnlockVMOwner -] - -{ #category : 'profiling primitives' } -Cogit >> collectCogConstituentFor: descriptor Annotation: isBackwardBranchAndAnnotation Mcpc: mcpc Bcpc: bcpc Method: cogMethodArg [ - - - - - | address entryPoint | - descriptor ifNil: [^0]. - descriptor isMapped ifFalse: [^0]. - address := self positiveMachineIntegerFor: (self cCoerceSimple: mcpc to: #'usqIntptr_t'). - address ifNil: [^PrimErrNoMemory]. "This cannot trigger a GC but fails if not enough space in Eden," - "Assumes we write the values into topRemappableOop" - coInterpreter - storePointerUnchecked: cogConstituentIndex - ofObject: coInterpreter topRemappableOop - withValue: address. - coInterpreter - storePointerUnchecked: cogConstituentIndex + 1 - ofObject: coInterpreter topRemappableOop - withValue: (objectMemory integerObjectOf: bcpc). - cogConstituentIndex := cogConstituentIndex + 2. - - "Collect any first case classTags for closed PICs." - ((isBackwardBranchAndAnnotation noMask: 1) - and: [self isSendAnnotation: isBackwardBranchAndAnnotation >> 1]) ifTrue: - [entryPoint := backEnd callTargetFromReturnAddress: mcpc asInteger. - entryPoint > methodZoneBase ifTrue: "send is linked" - [self targetMethodAndSendTableFor: entryPoint annotation: isBackwardBranchAndAnnotation >> 1 into: - [:targetMethod :sendTable| - targetMethod cmType = CMPolymorphicIC ifTrue: - [targetMethod methodObject: (objectRepresentation classForInlineCacheTag: (backEnd inlineCacheTagAt: (self cCoerceSimple: mcpc to: #sqInt)))]]]]. - ^0 -] - -{ #category : 'profiling primitives' } -Cogit >> collectCogMethodConstituent: cogMethod [ - "Answer a description of the mapping between machine code pointers and bytecode pointers for the Cog Method. - First value is the address of the cog method. - Following values are pairs of machine code pc and bytecode pc" - - | cm nSlots errCode address data | - (cogMethod cmType = CMMethod) - ifFalse: [^self positiveMachineIntegerFor: cogMethod asUnsignedInteger ]. - cogMethod stackCheckOffset = 0 "isFrameless ?" - ifTrue: [^self positiveMachineIntegerFor: cogMethod asUnsignedInteger]. - cm := cogMethod methodObject. - nSlots := ((objectMemory byteSizeOf: cm) - (coInterpreter startPCOfMethod: cm)) * 2 + objectMemory minSlotsForShortening + 1."+1 for first address" - data := objectMemory instantiateClass: (objectMemory splObj: ClassArray) indexableSize: nSlots. - data ifNil: [^nil]. - coInterpreter pushRemappableOop: data. - "The iteration assumes the object is the top remappable oop" - address := (self positiveMachineIntegerFor: cogMethod asUnsignedInteger). - address ifNil: [coInterpreter popRemappableOop. ^nil]. - coInterpreter - storePointerUnchecked: 0 - ofObject: coInterpreter topRemappableOop - withValue: address. - cogConstituentIndex := 1. - errCode := self - mapFor: cogMethod - bcpc: (coInterpreter startPCOfMethod: cogMethod methodObject) - performUntil: #collectCogConstituentFor:Annotation:Mcpc:Bcpc:Method: - arg: cogMethod asVoidPointer. - errCode ~= 0 ifTrue: [coInterpreter popRemappableOop. ^nil]. - cogConstituentIndex < nSlots ifTrue: - [objectMemory shorten: coInterpreter topRemappableOop toIndexableSize: cogConstituentIndex]. - ^coInterpreter popRemappableOop. -] - { #category : 'disassembly' } Cogit >> collectMapEntry: annotation address: mcpc into: aDictionary [ @@ -4862,23 +4620,6 @@ Cogit >> compactPICsWithFreedTargets [ self assert: count = methodZone numMethods ] -{ #category : 'simulation only' } -Cogit >> compilationTrace [ - ^compilationTrace -] - -{ #category : 'simulation only' } -Cogit >> compilationTrace: anInteger [ - " 1 = method/block compilation - 2 = bytecode descriptor. - 4 = simStack & optStatus - 8 = spill - 16 = merge - 32 = fixup - 64 = map" - compilationTrace := anInteger -] - { #category : 'compile abstract instructions' } Cogit >> compileAbort [ "The start of a CogMethod has a call to a run-time abort routine that either @@ -5122,10 +4863,7 @@ Cogit >> compileEntry [ entry := objectRepresentation genGetInlineCacheClassTagFrom: ReceiverResultReg into: TempReg. self CmpR: ClassReg R: TempReg. self JumpNonZero: sendMiss. - noCheckEntry := self Label. - self compileSendTrace ifTrue: - [backEnd saveAndRestoreLinkRegAround: - [self CallRT: ceTraceLinkedSendTrampoline]] + noCheckEntry := self Label ] { #category : 'compile abstract instructions' } @@ -5282,13 +5020,6 @@ Cogit >> compilePolymorphicICPrototype [ ^0 ] -{ #category : 'debugging' } -Cogit >> compileSendTrace [ - "2 is trace sends; 256+2 is traceLinkedSends, so one can trace just unlinked sends using 2" - - ^traceFlags allMask: 256 + 2 -] - { #category : 'initialization' } Cogit >> compileTrampolineFor: aRoutine numArgs: numArgs arg: regOrConst0 arg: regOrConst1 arg: regOrConst2 arg: regOrConst3 regsToSave: regMask pushLinkReg: pushLinkReg floatResultReg: resultRegOrNone [ "Generate a trampoline with up to four arguments. Generate either a call or a jump to aRoutine @@ -5770,62 +5501,6 @@ Cogit >> estimateOfAbstractOpcodesPerBytecodes [ ^ 15 ] -{ #category : 'simulation only' } -Cogit >> exclude: aMethodObj [ - "For debugging, allow excluding methods based on selector or methodClass. Answer if the mehtod should be excluded." - - self cCode: [] inSmalltalk: "for debugging, allow excluding methods based on selector or methodClass" - [self class initializationOptions - at: #DoNotJIT - ifPresent: - [:excluded| - (excluded anySatisfy: [:exclude| aMethodObj = exclude]) ifTrue: - [coInterpreter transcript - newLine; nextPutAll: 'EXCLUDING '; - nextPutAll: aMethodObj; nextPutAll: ' (compiled block)'; - newLine; flush. - ^true]]. - (compilationTrace anyMask: 1) ifTrue: - [| methodClass | - methodClass := coInterpreter nameOfClass: (coInterpreter methodClassOf: aMethodObj). - coInterpreter transcript - newLine; - nextPutAll: 'compiling compiled block in '; - nextPutAll: methodClass; - newLine; flush]]. - ^false -] - -{ #category : 'simulation only' } -Cogit >> exclude: aMethodObj selector: aSelectorOop [ - "For debugging, allow excluding methods based on selector or methodClass. Answer if the mehtod should be excluded." - - self cCode: [] inSmalltalk: - [| methodClass selector | - self class initializationOptions - at: #DoNotJIT - ifPresent: - [:excluded| - methodClass := coInterpreter nameOfClass: (coInterpreter methodClassOf: aMethodObj). - selector := coInterpreter stringOf: aSelectorOop. - (excluded anySatisfy: [:exclude| selector = exclude or: [methodClass = exclude]]) ifTrue: - [coInterpreter transcript - newLine; nextPutAll: 'EXCLUDING '; - nextPutAll: methodClass; nextPutAll: '>>#'; nextPutAll: selector; - cr; flush. - ^true]]. - (compilationTrace anyMask: 1) ifTrue: - [methodClass := coInterpreter nameOfClass: (coInterpreter methodClassOf: aMethodObj). - selector := coInterpreter stringOf: aSelectorOop. - selector isEmpty ifTrue: - [selector := coInterpreter stringOf: (coInterpreter maybeSelectorOfMethod: aMethodObj)]. - coInterpreter transcript - newLine; nextPutAll: 'compiling '; - nextPutAll: methodClass; nextPutAll: '>>#'; nextPutAll: selector; - cr; flush]]. - ^false -] - { #category : 'in-line cacheing' } Cogit >> expectedPICPrototype: aPIC [ @@ -6711,13 +6386,7 @@ Cogit >> genInnerPICAbortTrampoline: name [ { #category : 'trampoline support' } Cogit >> genLoadCStackPointersForPrimCall [ - debugPrimCallStackOffset = 0 - ifTrue: - [self MoveAw: self cStackPointerAddress R: backEnd cStackPointer] - ifFalse: - [self MoveAw: self cStackPointerAddress R: TempReg. - self SubCq: debugPrimCallStackOffset R: TempReg. - self MoveR: TempReg R: backEnd cStackPointer]. + self MoveAw: self cStackPointerAddress R: backEnd cStackPointer. cFramePointerInUse ifTrue: [self MoveAw: self cFramePointerAddress R: FPReg]. ^0 @@ -7640,48 +7309,45 @@ Cogit >> generateRunTimeTrampolines [ { #category : 'initialization' } Cogit >> generateSendTrampolines [ - 0 to: NumSendTrampolines - 1 do: - [:numArgs| - ordinarySendTrampolines - at: numArgs - put: (self genTrampolineFor: #ceSend:super:to:numArgs: - called: (self trampolineName: 'ceSend' numArgs: numArgs) - arg: ClassReg - arg: (self trampolineArgConstant: false) - arg: ReceiverResultReg - arg: (self numArgsOrSendNumArgsReg: numArgs))]. + + 0 to: NumSendTrampolines - 1 do: [ :numArgs | + ordinarySendTrampolines at: numArgs put: (self + genTrampolineFor: #ceSend:super:to:numArgs: + called: (self trampolineName: 'ceSend' numArgs: numArgs) + arg: ClassReg + arg: (self trampolineArgConstant: false) + arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs)) ]. "Generate these in the middle so they are within [firstSend, lastSend]." - BytecodeSetHasDirectedSuperSend ifTrue: - [0 to: NumSendTrampolines - 1 do: - [:numArgs| - directedSuperSendTrampolines - at: numArgs - put: (self genTrampolineFor: #ceSend:above:to:numArgs: - called: (self trampolineName: 'ceDirectedSuperSend' numArgs: numArgs) - arg: ClassReg - arg: TempReg - arg: ReceiverResultReg - arg: (self numArgsOrSendNumArgsReg: numArgs)). - directedSuperBindingSendTrampolines - at: numArgs - put: (self genTrampolineFor: #ceSend:aboveClassBinding:to:numArgs: - called: (self trampolineName: 'ceDirectedSuperBindingSend' numArgs: numArgs) - arg: ClassReg - arg: TempReg - arg: ReceiverResultReg - arg: (self numArgsOrSendNumArgsReg: numArgs))]]. - - 0 to: NumSendTrampolines - 1 do: - [:numArgs| - superSendTrampolines - at: numArgs - put: (self genTrampolineFor: #ceSend:super:to:numArgs: - called: (self trampolineName: 'ceSuperSend' numArgs: numArgs) - arg: ClassReg - arg: (self trampolineArgConstant: true) - arg: ReceiverResultReg - arg: (self numArgsOrSendNumArgsReg: numArgs))]. + 0 to: NumSendTrampolines - 1 do: [ :numArgs | + directedSuperSendTrampolines at: numArgs put: (self + genTrampolineFor: #ceSend:above:to:numArgs: + called: + (self trampolineName: 'ceDirectedSuperSend' numArgs: numArgs) + arg: ClassReg + arg: TempReg + arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs)). + directedSuperBindingSendTrampolines at: numArgs put: (self + genTrampolineFor: #ceSend:aboveClassBinding:to:numArgs: + called: + (self + trampolineName: 'ceDirectedSuperBindingSend' + numArgs: numArgs) + arg: ClassReg + arg: TempReg + arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs)) ]. + + 0 to: NumSendTrampolines - 1 do: [ :numArgs | + superSendTrampolines at: numArgs put: (self + genTrampolineFor: #ceSend:super:to:numArgs: + called: (self trampolineName: 'ceSuperSend' numArgs: numArgs) + arg: ClassReg + arg: (self trampolineArgConstant: true) + arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs)) ]. firstSend := ordinarySendTrampolines at: 0. lastSend := superSendTrampolines at: NumSendTrampolines - 1 ] @@ -7724,9 +7390,7 @@ Cogit >> generateTrampolines [ self generateMissAbortTrampolines. objectRepresentation generateObjectRepresentationTrampolines. self generateRunTimeTrampolines. - SistaVM ifTrue: [self generateSistaRuntime]. self generateEnilopmarts. - self generateTracingTrampolines. self recordGeneratedRunTime: 'methodZoneBase' address: methodZoneBase] flushingCacheWith: [ self flushICacheFrom: methodZoneStart asUnsignedInteger to: methodZoneBase asUnsignedInteger ]. @@ -7824,13 +7488,6 @@ Cogit >> getPrimitiveIndex [ ^primitiveIndex ] -{ #category : 'accessing' } -Cogit >> guardPageSize: anInteger [ - - - guardPageSize := anInteger -] - { #category : 'translation support' } Cogit >> halt [ @@ -7880,88 +7537,95 @@ Cogit >> handleABICallOrJumpSimulationTrap: aProcessorSimulationTrap evaluable: { #category : 'simulation only' } Cogit >> handleCallOrJumpSimulationTrap: aProcessorSimulationTrap [ + | evaluable function memory result savedFramePointer savedStackPointer savedArgumentCount rpc | + evaluable := simulatedTrampolines at: + aProcessorSimulationTrap address. - evaluable := simulatedTrampolines at: aProcessorSimulationTrap address. - - (evaluable isBlock not and: [self isPrimitiveRunningInSmalltalkStack: evaluable selector]) - ifTrue: [ self assertCStackWellAligned ]. + (evaluable isBlock not and: [ + self isPrimitiveRunningInSmalltalkStack: evaluable selector ]) + ifTrue: [ self assertCStackWellAligned ]. function := evaluable isBlock - ifTrue: ['aBlock; probably some plugin primitive'] - ifFalse: - [evaluable receiver == backEnd ifTrue: - [^self handleABICallOrJumpSimulationTrap: aProcessorSimulationTrap evaluable: evaluable]. - evaluable selector]. - function ~~ #ceBaseFrameReturn: ifTrue: - [coInterpreter assertValidExternalStackPointers]. - (function beginsWith: 'ceShort') ifTrue: - [^self perform: function with: aProcessorSimulationTrap]. - + ifTrue: [ 'aBlock; probably some plugin primitive' ] + ifFalse: [ + evaluable receiver == backEnd ifTrue: [ + ^ self + handleABICallOrJumpSimulationTrap: + aProcessorSimulationTrap + evaluable: evaluable ]. + evaluable selector ]. + function ~~ #ceBaseFrameReturn: ifTrue: [ + coInterpreter assertValidExternalStackPointers ]. + (function beginsWith: 'ceShort') ifTrue: [ + ^ self perform: function with: aProcessorSimulationTrap ]. + aProcessorSimulationTrap type == #call - ifTrue: - [processor + ifTrue: [ + processor simulateCallOf: aProcessorSimulationTrap address nextpc: aProcessorSimulationTrap nextpc - memory: (memory := coInterpreter memory). - self recordInstruction: {'(simulated call of '. aProcessorSimulationTrap address. '/'. function. ')'}] - ifFalse: - [processor + memory: (memory := coInterpreter memory) ] + ifFalse: [ + processor simulateJumpCallOf: aProcessorSimulationTrap address - memory: nil. - self recordInstruction: {'(simulated jump to '. aProcessorSimulationTrap address. '/'. function. ')'}]. + memory: nil ]. savedFramePointer := coInterpreter framePointer. savedStackPointer := coInterpreter stackPointer. savedArgumentCount := coInterpreter argumentCount. - result := ["self halt: evaluable selector." - ((printRegisters or: [printInstructions]) and: [clickConfirm]) ifTrue: - [(self confirm: 'skip run-time call?') ifFalse: - [clickConfirm := false. self halt]]. - evaluable valueWithArguments: (processor - postCallArgumentsNumArgs: evaluable numArgs - in: nil)] - on: ReenterMachineCode - do: [:ex| ex return: ex returnValue]. - + result := [ + evaluable valueWithArguments: + (processor + postCallArgumentsNumArgs: evaluable numArgs + in: nil) ] + on: ReenterMachineCode + do: [ :ex | ex return: ex returnValue ]. + coInterpreter assertValidExternalStackPointers. "Verify the stack layout assumption compileInterpreterPrimitive: makes, provided we've not called something that has built a frame, such as closure value or evaluate method, or switched frames, such as primitiveSignal, primitiveWait, primitiveResume, primitiveSuspend et al." - (function beginsWith: 'primitive') ifTrue: - [coInterpreter checkForLastObjectOverwrite. - coInterpreter primFailCode = 0 - ifTrue: [(#( - primitiveFullClosureValue primitiveFullClosureValueWithArgs primitiveFullClosureValueNoContextSwitch - primitiveSignal primitiveWait primitiveResume primitiveSuspend primitiveYield - primitiveExecuteMethodArgsArray primitiveExecuteMethod - primitivePerform primitivePerformWithArgs primitivePerformInSuperclass - primitiveTerminateTo primitiveStoreStackp primitiveDoPrimitiveWithArgs) - includes: function) ifFalse: - ["This is a rare case (e.g. in Scorch where a married context's sender is set to nil on trapTrpped and hence the stack layout is altered." - (function == #primitiveSlotAtPut and: [objectMemory isContext: (coInterpreter frameReceiver: coInterpreter framePointer)]) ifFalse: - [self assert: savedFramePointer = coInterpreter framePointer. - self assert: savedStackPointer + (savedArgumentCount * objectMemory wordSize) - = coInterpreter stackPointer]]] - ifFalse: - [self assert: savedFramePointer = coInterpreter framePointer. - self assert: savedStackPointer = coInterpreter stackPointer]]. - result ~~ #continueNoReturn ifTrue: - [self recordInstruction: {'(simulated return to '. processor retpcIn: memory. ')'}. - rpc := processor retpcIn: memory. - self assert: (rpc >= codeBase and: [rpc < methodZone freeStart]). - processor - smashCallerSavedRegistersWithValuesFrom: 16r80000000 by: objectMemory wordSize in: memory; - simulateReturnIn: memory]. - self assert: (result isInteger "an oop result" - or: [result == coInterpreter - or: [result == objectMemory - or: [#(nil continue continueNoReturn) includes: result]]]). - processor cResultRegister: (result - ifNil: [0] - ifNotNil: [result isInteger - ifTrue: [result] - ifFalse: [16rF00BA222]]) + (function beginsWith: 'primitive') ifTrue: [ + coInterpreter checkForLastObjectOverwrite. + coInterpreter primFailCode = 0 + ifTrue: [ + (#( primitiveFullClosureValue primitiveFullClosureValueWithArgs + primitiveFullClosureValueNoContextSwitch + primitiveSignal primitiveWait primitiveResume primitiveSuspend + primitiveYield primitiveExecuteMethodArgsArray + primitiveExecuteMethod primitivePerform primitivePerformWithArgs + primitivePerformInSuperclass primitiveTerminateTo + primitiveStoreStackp primitiveDoPrimitiveWithArgs ) includes: + function) ifFalse: [ "This is a rare case (e.g. in Scorch where a married context's sender is set to nil on trapTrpped and hence the stack layout is altered." + (function == #primitiveSlotAtPut and: [ + objectMemory isContext: + (coInterpreter frameReceiver: coInterpreter framePointer) ]) + ifFalse: [ + self assert: savedFramePointer = coInterpreter framePointer. + self assert: + savedStackPointer + + (savedArgumentCount * objectMemory wordSize) + = coInterpreter stackPointer ] ] ] + ifFalse: [ + self assert: savedFramePointer = coInterpreter framePointer. + self assert: savedStackPointer = coInterpreter stackPointer ] ]. + result ~~ #continueNoReturn ifTrue: [ + rpc := processor retpcIn: memory. + self assert: (rpc >= codeBase and: [ rpc < methodZone freeStart ]). + processor + smashCallerSavedRegistersWithValuesFrom: 16r80000000 + by: objectMemory wordSize + in: memory; + simulateReturnIn: memory ]. + self assert: (result isInteger or: [ + result == coInterpreter or: [ + result == objectMemory or: [ + #( nil continue continueNoReturn ) includes: result ] ] ]). "an oop result" + processor cResultRegister: (result ifNil: [ 0 ] ifNotNil: [ + result isInteger + ifTrue: [ result ] + ifFalse: [ 16rF00BA222 ] ]) "coInterpreter cr. processor sp + 32 to: processor sp - 32 by: -4 do: @@ -8166,11 +7830,7 @@ Cogit >> initializeCodeZoneFrom: startAddress upTo: endAddress [ self enableCodeZoneWriteDuring: [ backEnd stopsFrom: startAddress to: endAddress - 1 ]. - self - simulationOnly: [ - startAddress = self class guardPageSize ifTrue: [ - backEnd stopsFrom: 0 to: endAddress - 1 ]. - self initializeProcessor ]. + self simulationOnly: [ self initializeProcessor ]. codeBase := methodZoneBase := startAddress. minValidCallAddress := (codeBase min: coInterpreter interpretAddress) min: coInterpreter primitiveFailAddress. @@ -8229,8 +7889,6 @@ Cogit >> initializePIC: aPIC atDelta: addrDelta numArgs: numArgs [ Cogit >> initializeProcessor [ "Initialize the simulation processor, arranging that its initial stack is somewhere on the rump C stack." - guardPageSize := self class guardPageSize. - lastNInstructions := OrderedCollection new. processor initializeStackFor: self. self initializeProcessorStack: coInterpreter rumpCStackAddress. self setCFramePointer: processor fp. @@ -8447,12 +8105,6 @@ Cogit >> labelForSimulationAccessor: blockOrMessageSendOrSelector [ ifFalse: [blockOrMessageSendOrSelector]]) ] -{ #category : 'accessing' } -Cogit >> lastNInstructions: aCollection [ - - lastNInstructions := aCollection -] - { #category : 'compile abstract instructions' } Cogit >> lastOpcode [ @@ -8627,31 +8279,6 @@ Cogit >> lookupAddress: address [ ^coInterpreter lookupAddress: address ] -{ #category : 'disassembly' } -Cogit >> lookupCHexString: aCHexString [ - - | pastLastZero shortened address | - (aCHexString beginsWith: '0x') ifFalse: - [^aCHexString]. - pastLastZero := aCHexString findFirst: [:c| c ~= $0 and: [c ~= $x]]. - shortened := pastLastZero = 0 - ifTrue: ['0x0'] - ifFalse: - [(aCHexString size >= 16 and: [pastLastZero >= 4]) - ifTrue: [aCHexString copyReplaceFrom: 3 to: pastLastZero - 1 with: ''] - ifFalse: [aCHexString]]. - address := Number readFrom: (ReadStream on: shortened from: 3 to: shortened size) base: 16. - (disassemblingMethod notNil - and: [address > disassemblingMethod - and: [address < (disassemblingMethod asInteger + disassemblingMethod blockSize)]]) ifTrue: - [shortened := '.+', (address - disassemblingMethod asInteger printStringBase: 16 length: 4 padded: true)]. - ^(self lookupAddress: (Number - readFrom: (ReadStream on: shortened from: 3 to: shortened size) - base: 16)) - ifNotNil: [:string| shortened, '=', string] - ifNil: [shortened] -] - { #category : 'disassembly' } Cogit >> lookupFrameOffset: anInteger [ @@ -9850,10 +9477,10 @@ Cogit >> offsetAndSendTableFor: entryPoint annotation: annotation into: binaryBl annotation = IsSendCall ifTrue: [offset := cmEntryOffset. sendTable := ordinarySendTrampolines] ifFalse: - [(BytecodeSetHasDirectedSuperSend and: [annotation = IsDirectedSuperSend]) ifTrue: + [(annotation = IsDirectedSuperSend) ifTrue: [offset := cmNoCheckEntryOffset. sendTable := directedSuperSendTrampolines] ifFalse: - [(BytecodeSetHasDirectedSuperSend and: [annotation = IsDirectedSuperBindingSend]) ifTrue: + [(annotation = IsDirectedSuperBindingSend) ifTrue: [offset := cmNoCheckEntryOffset. sendTable := directedSuperBindingSendTrampolines] ifFalse: [self assert: annotation = IsSuperSend. @@ -10245,19 +9872,6 @@ Cogit >> printCogMethodHeaderFor: address [ ifFalse: [self printMethodHeader: cogMethod on: coInterpreter transcript] ] -{ #category : 'disassembly' } -Cogit >> printInstructions [ - - ^printInstructions -] - -{ #category : 'disassembly' } -Cogit >> printInstructions: aBoolean [ - - printInstructions := aBoolean. - singleStep := singleStep or: [aBoolean] -] - { #category : 'disassembly' } Cogit >> printMethodHeader: cogMethod on: aStream [ @@ -10384,13 +9998,6 @@ Cogit >> printNum: n [ coInterpreter transcript printNum: n ] -{ #category : 'debugging' } -Cogit >> printOnTrace [ - - - ^(traceFlags bitAnd: 1) ~= 0 -] - { #category : 'method map' } Cogit >> printPCMapPairsFor: cogMethod [ " @@ -10424,8 +10031,7 @@ Cogit >> printPCMapPairsFor: cogMethod [ printChar: $ ; printNum: annotation; print: ' ('. - (BytecodeSetHasDirectedSuperSend and: [ - value between: IsDirectedSuperSend and: IsDirectedSuperBindingSend ]) + (value between: IsDirectedSuperSend and: IsDirectedSuperBindingSend) ifTrue: [ value caseOf: { ([ IsDirectedSuperSend ] @@ -10505,18 +10111,6 @@ Cogit >> printRegisterMapOn: aStream [ aStream cr; flush ] -{ #category : 'debugging' } -Cogit >> printRegisters [ - - ^printRegisters -] - -{ #category : 'debugging' } -Cogit >> printRegisters: aBoolean [ - - printRegisters := aBoolean -] - { #category : 'debugging' } Cogit >> printTrampolineTable [ @@ -10622,13 +10216,6 @@ Cogit >> receiverTags: anInteger [ receiverTags := anInteger ] -{ #category : 'debugging' } -Cogit >> recordBlockTrace [ - - - ^(traceFlags bitAnd: 4) ~= 0 -] - { #category : 'debugging' } Cogit >> recordEventTrace [ @@ -10645,17 +10232,6 @@ Cogit >> recordGeneratedRunTime: aString address: address [ trampolineTableIndex := trampolineTableIndex + 2 ] -{ #category : 'simulation only' } -Cogit >> recordInstruction: thing [ - - lastNInstructions addLast: thing. - [lastNInstructions size > 160"80"] whileTrue: - [lastNInstructions removeFirst. - lastNInstructions size * 2 > lastNInstructions capacity ifTrue: - [lastNInstructions makeRoomAtLast]]. - ^thing -] - { #category : 'debugging' } Cogit >> recordOverflowTrace [ @@ -10677,13 +10253,6 @@ Cogit >> recordPrimTraceFunc [ ^self recordPrimTrace ] -{ #category : 'simulation only' } -Cogit >> recordRegisters [ - - self recordInstruction: processor integerRegisterState - "self recordInstruction: processor registerState" -] - { #category : 'initialization' } Cogit >> recordRunTimeObjectReferences [ @@ -10701,13 +10270,6 @@ Cogit >> recordRunTimeObjectReferences [ runtimeObjectRefIndex := runtimeObjectRefIndex + 1]] ] -{ #category : 'debugging' } -Cogit >> recordSendTrace [ - - - ^(traceFlags bitAnd: 2) ~= 0 -] - { #category : 'register management' } Cogit >> registerMaskFor: reg [ @@ -10768,13 +10330,6 @@ Cogit >> registerMaskFor: reg1 and: reg2 and: reg3 and: reg4 and: reg5 and: reg6 ^((((((((1 << reg1 bitOr: 1 << reg2) bitOr: 1 << reg3) bitOr: 1 << reg4) bitOr: 1 << reg5) bitOr: 1 << reg6) bitOr: 1 << reg7) bitOr: 1 << reg8) bitOr: 1 << reg9) bitOr: 1 << reg10 ] -{ #category : 'disassembly' } -Cogit >> relativeBaseForDisassemblyInto: aBlock [ - - disassemblingMethod ifNotNil: - [aBlock value: disassemblingMethod asInteger value: '.'] -] - { #category : 'disassembly' } Cogit >> relativeLabelForPC: pc [ @@ -11195,15 +10750,12 @@ Cogit >> setInterpreter: aCoInterpreter [ simulatedTrampolines := Dictionary new. simulatedVariableGetters := Dictionary new. simulatedVariableSetters := Dictionary new. - traceStores := 0. traceFlags := (self class initializationOptions at: #recordPrimTrace ifAbsent: [ true ]) ifTrue: [ "record prim trace on by default (see Cogit class>>decareCVarsIn:)" 8 ] ifFalse: [ 0 ]. - debugPrimCallStackOffset := 0. - singleStep := printRegisters := printInstructions := clickConfirm := false. backEnd := CogCompilerClass for: self. methodLabel := CogCompilerClass for: self. (literalsManager := backEnd class literalsManagerClass new) cogit: @@ -11212,13 +10764,12 @@ Cogit >> setInterpreter: aCoInterpreter [ (Array new: NumSendTrampolines). superSendTrampolines := CArrayAccessor on: (Array new: NumSendTrampolines). - BytecodeSetHasDirectedSuperSend ifTrue: [ - directedSuperSendTrampolines := CArrayAccessor on: + directedSuperSendTrampolines := CArrayAccessor on: (Array new: NumSendTrampolines). directedSuperBindingSendTrampolines := CArrayAccessor on: (Array new: NumSendTrampolines). - directedSendUsesBinding := false ]. + directedSendUsesBinding := false. "debug metadata" objectReferencesInRuntime := CArrayAccessor on: (Array new: NumObjRefsInRuntime). @@ -11228,9 +10779,7 @@ Cogit >> setInterpreter: aCoInterpreter [ (Array new: NumTrampolines * 2). trampolineTableIndex := 0. - extA := numExtB := extB := 0. - - compilationTrace ifNil: [compilationTrace := self class initializationOptions at: #compilationTrace ifAbsent: [0]] + extA := numExtB := extB := 0 ] { #category : 'jit - api' } @@ -11312,25 +10861,14 @@ Cogit >> simulateCogCodeAt: address [ processor pc: address. [ - [ - singleStep - ifTrue: [ - processor - singleStepIn: coInterpreter memory - minimumAddress: guardPageSize - readOnlyBelow: methodZone zoneEnd ] - ifFalse: [ - processor - runInMemory: nil - minimumAddress: guardPageSize - readOnlyBelow: methodZone zoneEnd ]. - true ] whileTrue. + + processor run. + true ] whileTrue ] { #category : 'simulation only' } Cogit >> simulateEnilopmart: enilopmartAddress numArgs: n [ - "Enter Cog code, popping the class reg and receiver from the stack and then returning to the address beneath them. In the actual VM the enilopmart is a function pointer and so senders @@ -11339,11 +10877,10 @@ Cogit >> simulateEnilopmart: enilopmartAddress numArgs: n [ the interpreter) or return to the simulation (if we're in the run-time called from machine code. We should also smash the register state since, being an abnormal entry, no saved registers will be restored." + + self assert: (coInterpreter isOnRumpCStack: processor sp). - self assert: ((coInterpreter stackValue: n) between: guardPageSize and: methodZone freeStart - 1). "As a convenience for stack printing, nil localFP so we know we're in machine code." - (printInstructions or: [printRegisters]) ifTrue: - [coInterpreter printExternalHeadFrame]. processor smashRegistersWithValuesFrom: 16r80000000 by: objectMemory wordSize; simulateLeafCallOf: enilopmartAddress @@ -11371,24 +10908,18 @@ Cogit >> simulateLeafCallOf: someFunction [ answering the result returned by someFunction." | spOnEntry | - self recordRegisters. - spOnEntry := processor sp. processor simulateLeafCallOf: someFunction nextpc: 16rBADF00D0 memory: nil. - - singleStep - ifTrue: [ self notYetImplemented ]. processor runUntil: 16rBADF00D0. self assert: processor sp = spOnEntry. self assert: processor pc = 16rBADF00D0. - - self recordRegisters. + ^processor cResultRegister ] @@ -11496,18 +11027,6 @@ Cogit >> simulatedVariableAt: address put: value [ ^ simulatedVariableGetters at: address put: value ] -{ #category : 'debugging' } -Cogit >> singleStep [ - - ^singleStep -] - -{ #category : 'debugging' } -Cogit >> singleStep: aBoolean [ - - singleStep := aBoolean -] - { #category : 'debugging' } Cogit >> sizeOfTrampoline: address [ @@ -11609,14 +11128,6 @@ Cogit >> traceLinkedSendOffset [ ifFalse: [0]) ] -{ #category : 'debugging' } -Cogit >> traceStores: aBooleanOrInteger [ - - traceStores := aBooleanOrInteger isInteger - ifTrue: [aBooleanOrInteger] - ifFalse: [aBooleanOrInteger ifTrue: [1] ifFalse: [0]] -] - { #category : 'initialization' } Cogit >> trampolineArgConstant: booleanOrInteger [ "Encode true and false and 0 to N such that they can't be confused for register numbers (including NoReg) diff --git a/smalltalksrc/VMMaker/SimpleStackBasedCogit.class.st b/smalltalksrc/VMMaker/SimpleStackBasedCogit.class.st index ea02db0459c..c5013f80274 100644 --- a/smalltalksrc/VMMaker/SimpleStackBasedCogit.class.st +++ b/smalltalksrc/VMMaker/SimpleStackBasedCogit.class.st @@ -74,8 +74,6 @@ SimpleStackBasedCogit class >> declareCVarsIn: aCCodeGenerator [ SimpleStackBasedCogit class >> initializeBytecodeTableForSistaV1 [ "SimpleStackBasedCogit initializeBytecodeTableForSistaV1" - BytecodeSetHasDirectedSuperSend := true. - BytecodeSetHasExtensions := true. FirstSpecialSelector := 96. NumSpecialSelectors := 32. self flag: @@ -238,17 +236,16 @@ SimpleStackBasedCogit >> adjustArgumentsForPerform: numArgs [ { #category : 'bytecode generator support' } SimpleStackBasedCogit >> annotationForSendTable: sendTable [ "c.f. offsetAndSendTableFor:annotation:into:" + - sendTable == ordinarySendTrampolines ifTrue: - [^IsSendCall]. - BytecodeSetHasDirectedSuperSend ifTrue: - [sendTable == directedSuperSendTrampolines ifTrue: - [^IsDirectedSuperSend]. - sendTable == directedSuperBindingSendTrampolines ifTrue: - [^IsDirectedSuperBindingSend]]. + sendTable == ordinarySendTrampolines ifTrue: [ ^ IsSendCall ]. + sendTable == directedSuperSendTrampolines ifTrue: [ + ^ IsDirectedSuperSend ]. + sendTable == directedSuperBindingSendTrampolines ifTrue: [ + ^ IsDirectedSuperBindingSend ]. self assert: sendTable == superSendTrampolines. - ^IsSuperSend + ^ IsSuperSend ] { #category : 'simulation only' } @@ -269,27 +266,6 @@ SimpleStackBasedCogit >> cePICMissTrampoline: anAddress [ cePICMissTrampoline := anAddress ] -{ #category : 'simulation only' } -SimpleStackBasedCogit >> ceShortCutTraceBlockActivation: aProcessorSimulationTrap [ - self shortcutTrampoline: aProcessorSimulationTrap - to: [coInterpreter ceTraceBlockActivation] -] - -{ #category : 'simulation only' } -SimpleStackBasedCogit >> ceShortCutTraceLinkedSend: aProcessorSimulationTrap [ - self shortcutTrampoline: aProcessorSimulationTrap - to: [coInterpreter ceTraceLinkedSend: (processor registerAt: ReceiverResultReg)] -] - -{ #category : 'simulation only' } -SimpleStackBasedCogit >> ceShortCutTraceStore: aProcessorSimulationTrap [ - - self shortcutTrampoline: aProcessorSimulationTrap - to: [coInterpreter - ceTraceStoreOf: (processor registerAt: ClassReg) - into: (processor registerAt: ReceiverResultReg)] -] - { #category : 'accessing' } SimpleStackBasedCogit >> ceStoreContextInstVarTrampoline: anInteger [ @@ -2040,17 +2016,21 @@ SimpleStackBasedCogit >> genPushLiteralConstantBytecode [ ] { #category : 'bytecode generator support' } -SimpleStackBasedCogit >> genPushLiteralIndex: literalIndex [ "" +SimpleStackBasedCogit >> genPushLiteralIndex: literalIndex [ + "" + | literal | literal := self getLiteral: literalIndex. - BytecodeSetHasDirectedSuperSend ifTrue: - [self nextDescriptorExtensionsAndNextPCInto: - [:descriptor :exta :extb :followingPC| - (self isDirectedSuper: descriptor extA: exta extB: extb) ifTrue: - [tempOop := literal. - ^0]]]. - ^self genPushLiteral: literal + self nextDescriptorExtensionsAndNextPCInto: [ + :descriptor + :exta + :extb + :followingPC | + (self isDirectedSuper: descriptor extA: exta extB: extb) ifTrue: [ + tempOop := literal. + ^ 0 ] ]. + ^ self genPushLiteral: literal ] { #category : 'bytecode generators' } @@ -2061,20 +2041,23 @@ SimpleStackBasedCogit >> genPushLiteralVariable16CasesBytecode [ { #category : 'bytecode generator support' } SimpleStackBasedCogit >> genPushLiteralVariable: literalIndex [ + | association | association := self getLiteral: literalIndex. "If followed by a directed super send bytecode, avoid generating any code yet. The association will be passed to the directed send trampoline in a register and fully dereferenced only when first linked. It will be ignored in later sends." - BytecodeSetHasDirectedSuperSend ifTrue: - [self deny: directedSendUsesBinding. - self nextDescriptorExtensionsAndNextPCInto: - [:descriptor :exta :extb :followingPC| - (self isDirectedSuper: descriptor extA: exta extB: extb) ifTrue: - [tempOop := association. - directedSendUsesBinding := true. - ^0]]]. + self deny: directedSendUsesBinding. + self nextDescriptorExtensionsAndNextPCInto: [ + :descriptor + :exta + :extb + :followingPC | + (self isDirectedSuper: descriptor extA: exta extB: extb) ifTrue: [ + tempOop := association. + directedSendUsesBinding := true. + ^ 0 ] ]. "N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods." self genMoveConstant: association R: ClassReg. objectRepresentation @@ -2085,7 +2068,7 @@ SimpleStackBasedCogit >> genPushLiteralVariable: literalIndex [ sourceReg: ClassReg destReg: TempReg. self PushR: TempReg. - ^0 + ^ 0 ] { #category : 'bytecode generators' } @@ -2348,33 +2331,37 @@ SimpleStackBasedCogit >> genSend: selectorIndex numArgs: numArgs [ { #category : 'bytecode generator support' } SimpleStackBasedCogit >> genSend: selectorIndex numArgs: numArgs sendTable: sendTable [ + - - | annotation | self assert: needsFrame. annotation := self annotationForSendTable: sendTable. self assert: (numArgs between: 0 and: 255). "say" - self MoveMw: numArgs * objectMemory wordSize r: SPReg R: ReceiverResultReg. + self + MoveMw: numArgs * objectMemory wordSize + r: SPReg + R: ReceiverResultReg. "Deal with stale super sends; see SpurMemoryManager's class comment." - (self annotationIsForUncheckedEntryPoint: annotation) ifTrue: - [objectRepresentation genEnsureOopInRegNotForwarded: ReceiverResultReg scratchReg: TempReg]. + (self annotationIsForUncheckedEntryPoint: annotation) ifTrue: [ + objectRepresentation + genEnsureOopInRegNotForwarded: ReceiverResultReg + scratchReg: TempReg ]. "0 through (NumSendTrampolines - 2) numArgs sends have the arg count implciti in the trampoline. The last send trampoline (NumSendTrampolines - 1) passes numArgs in SendNumArgsReg." - numArgs >= (NumSendTrampolines - 1) ifTrue: - [self MoveCq: numArgs R: SendNumArgsReg]. - (BytecodeSetHasDirectedSuperSend - and: [annotation - between: IsDirectedSuperSend - and: IsDirectedSuperBindingSend]) ifTrue: - [self genMoveConstant: tempOop R: TempReg]. + numArgs >= (NumSendTrampolines - 1) ifTrue: [ + self MoveCq: numArgs R: SendNumArgsReg ]. + (annotation + between: IsDirectedSuperSend + and: IsDirectedSuperBindingSend) ifTrue: [ + self genMoveConstant: tempOop R: TempReg ]. self genLoadInlineCacheWithSelector: selectorIndex. - (self Call: (sendTable at: (numArgs min: NumSendTrampolines - 1))) annotation: annotation. + (self Call: (sendTable at: (numArgs min: NumSendTrampolines - 1))) + annotation: annotation. self PushR: ReceiverResultReg. - ^0 + ^ 0 ] { #category : 'bytecode generator support' } @@ -2742,21 +2729,6 @@ SimpleStackBasedCogit >> genSubConstant: constant R: reg [ ifFalse: [ self SubCq: constant R: reg ] ] -{ #category : 'initialization' } -SimpleStackBasedCogit >> genTraceStoreTrampoline [ - ceTraceStoreTrampoline := self genTrampolineFor: #ceTraceStoreOf:into: - called: 'ceTraceStoreTrampoline' - arg: ClassReg - arg: ReceiverResultReg - regsToSave: CallerSavedRegisterMask -] - -{ #category : 'bytecode generator support' } -SimpleStackBasedCogit >> genTraceStores [ - - traceStores > 0 ifTrue: [ self CallRT: ceTraceStoreTrampoline ]. -] - { #category : 'bytecode generators' } SimpleStackBasedCogit >> genUnconditionalTrapBytecode [ "SistaV1: * 217 Trap" @@ -2816,28 +2788,6 @@ SimpleStackBasedCogit >> generateMissAbortTrampolines [ arg: ClassReg ] -{ #category : 'initialization' } -SimpleStackBasedCogit >> generateTracingTrampolines [ - "Generate trampolines for tracing. In the simulator we can save a lot of time - and avoid noise instructions in the lastNInstructions log by short-cutting these - trampolines, but we need them in the real vm." - ceTraceLinkedSendTrampoline := - self genTrampolineFor: #ceTraceLinkedSend: - called: 'ceTraceLinkedSendTrampoline' - arg: ReceiverResultReg - regsToSave: CallerSavedRegisterMask. - ceTraceBlockActivationTrampoline := - self genTrampolineFor: #ceTraceBlockActivation - called: 'ceTraceBlockActivationTrampoline' - regsToSave: CallerSavedRegisterMask. - ceTraceStoreTrampoline := - self genTrampolineFor: #ceTraceStoreOf:into: - called: 'ceTraceStoreTrampoline' - arg: ClassReg - arg: ReceiverResultReg - regsToSave: CallerSavedRegisterMask. -] - { #category : 'register management' } SimpleStackBasedCogit >> isCallerSavedReg: reg [ diff --git a/smalltalksrc/VMMaker/SistaCogMethod.class.st b/smalltalksrc/VMMaker/SistaCogMethod.class.st deleted file mode 100644 index 0f5d1eb4a73..00000000000 --- a/smalltalksrc/VMMaker/SistaCogMethod.class.st +++ /dev/null @@ -1,51 +0,0 @@ -" -A SistaCogMethod is a CogMethod with a pointer to memory holding the Sista performance counters decremented in conditional branches. - -Instance Variables - counters: - -counters - - counters points to the first field of either a pinned object on the Spur heap or malloced memory. - -" -Class { - #name : 'SistaCogMethod', - #superclass : 'CogMethod', - #instVars : [ - 'counters' - ], - #category : 'VMMaker-JIT', - #package : 'VMMaker', - #tag : 'JIT' -} - -{ #category : 'class initialization' } -SistaCogMethod class >> initialize [ - "self initialize" - (Smalltalk classNamed: #CogSistaMethodSurrogate32) ifNotNil: - [:cms32| - self checkGenerateSurrogate: cms32 bytesPerWord: 4]. - (Smalltalk classNamed: #CogSistaMethodSurrogate64) ifNotNil: - [:cms64| - self checkGenerateSurrogate: cms64 bytesPerWord: 8] -] - -{ #category : 'translation' } -SistaCogMethod class >> structTypeName [ - "Provide the typedef name." - ^superclass structTypeName -] - -{ #category : 'accessing' } -SistaCogMethod >> counters [ - "Answer the value of counters" - - ^ counters -] - -{ #category : 'accessing' } -SistaCogMethod >> counters: anObject [ - "Set the value of counters" - - ^counters := anObject -] diff --git a/smalltalksrc/VMMaker/SmartSyntaxPluginSimulator.class.st b/smalltalksrc/VMMaker/SmartSyntaxPluginSimulator.class.st index 0a9133bedeb..a6505d8ff28 100644 --- a/smalltalksrc/VMMaker/SmartSyntaxPluginSimulator.class.st +++ b/smalltalksrc/VMMaker/SmartSyntaxPluginSimulator.class.st @@ -187,7 +187,6 @@ SmartSyntaxPluginSimulator >> doesNotUnderstand: aMessage [ signature := signatureMap at: aMessage selector ifAbsent: [^super doesNotUnderstand: aMessage]. - self log: [interpreterProxy coInterpreter printExternalHeadFrame; print: aMessage selector; cr]. "record the stack pointer to avoid cutting back the stack twice in plugins that mix smart syntax and traditional style." sp := interpreterProxy getStackPointer. selector := signature first. diff --git a/smalltalksrc/VMMaker/StackInterpreter.class.st b/smalltalksrc/VMMaker/StackInterpreter.class.st index a469461d02f..507bfa5da6f 100644 --- a/smalltalksrc/VMMaker/StackInterpreter.class.st +++ b/smalltalksrc/VMMaker/StackInterpreter.class.st @@ -538,10 +538,6 @@ If ffi is put as a separate header, slang will sort the header and put it outsid as: #'StackPage *' in: aCCodeGenerator. aCCodeGenerator removeVariable: 'stackPages'. "this is an implicit receiver in the translated code." - BytecodeSetHasExtensions == false ifTrue: [ - aCCodeGenerator - removeVariable: 'extA'; - removeVariable: 'extB' ]. aCCodeGenerator var: #methodCache declareC: 'sqIntptr_t methodCache[MethodCacheSize + 1 /* ' @@ -622,10 +618,6 @@ StackInterpreter class >> initializeAssociationIndex [ StackInterpreter class >> initializeBytecodeTable [ "StackInterpreter initializeBytecodeTable" - - VMBytecodeConstants falsifyBytecodeSetFlags: InitializationOptions. - BytecodeSetHasDirectedSuperSend := false. - ^ self initializeBytecodeTableForSistaV1 ] @@ -637,8 +629,6 @@ StackInterpreter class >> initializeBytecodeTableForSistaV1 [ BytecodeTable := Array new: 256. BytecodeEncoderClassName := #EncoderForSistaV1. - BytecodeSetHasDirectedSuperSend := true. - BytecodeSetHasExtensions := true. LongStoreBytecode := 245. self table: BytecodeTable from: #( "1 byte bytecodes" @@ -1665,7 +1655,7 @@ StackInterpreter class >> requiredMethodNames: options [ interpret loadInitialContext primitiveFail primitiveFailFor: primitiveFlushExternalPrimitives printAllStacks printCallStack printContext: - printExternalHeadFrame printFramesInPage: + printFramesInPage: printFrame: printHeadFrame printMemory printOop: printStackPages printStackPageList printStackPagesInUse printStackPageListInUse @@ -1756,27 +1746,6 @@ StackInterpreter >> ISA [ ifFalse: [#IA32]] ] -{ #category : 'debug support' } -StackInterpreter >> abstractDetailedSymbolicMethod: aMethod [ - - | ts prim | - (ts := self transcript) newLine. - (prim := self primitiveIndexOf: aMethod) > 0 ifTrue: - [ts nextPutAll: '. - (self isQuickPrimitiveIndex: prim) ifTrue: - [ts nextPutAll: ' quick method'; cr; flush. - ^self]. - ts cr]. - (RelativeDetailedInstructionPrinter - on: (VMCompiledMethodProxy new - for: aMethod - coInterpreter: self - objectMemory: objectMemory)) - indent: 0; - printInstructionsOn: ts. - ts flush -] - { #category : 'control primitives' } StackInterpreter >> activateNewFullClosure: blockClosure method: theMethod numArgs: numArgs mayContextSwitch: mayContextSwitch [ "Similar to activateNewMethod but for Closure and newMethod." @@ -4498,7 +4467,6 @@ StackInterpreter >> commonSendOrdinary [ "Note: This method is inlined into the interpreter dispatch loop." self sendBreakpoint: messageSelector receiver: (self stackValue: argumentCount). - self doRecordSendTrace. self findNewMethodOrdinary. self executeNewMethod: false. self fetchNextBytecode @@ -4817,8 +4785,6 @@ StackInterpreter >> directedSuperclassSend [ "Assume: messageSelector and argumentCount have been set, and that the receiver and arguments have been pushed onto the stack," "Note: This method is inlined into the interpreter dispatch loop." - "" - | class superclass | class := self popStack. (objectMemory isForwarded: class) ifTrue: @@ -5030,16 +4996,6 @@ StackInterpreter >> doPrimitiveMod: rcvr by: arg [ ^ integerResult ] -{ #category : 'send bytecodes' } -StackInterpreter >> doRecordSendTrace [ - - self printSends ifTrue: [ - self - printActivationNameForSelector: messageSelector - startClass: (objectMemory classForClassTag: lkupClassTag); - cr ] -] - { #category : 'process primitive support' } StackInterpreter >> doSignalSemaphoreWithIndex: index [ "Signal the external semaphore with the given index. Answer if a context switch @@ -5540,16 +5496,16 @@ StackInterpreter >> extSendSuperBytecode [ 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). + messageSelector := self literal: byte >> 3 + (extA << 5). extA := 0. - BytecodeSetHasDirectedSuperSend ifTrue: - [extB >= 64 ifTrue: - [argumentCount := (byte bitAnd: 7) + (extB - 64 << 3). - extB := 0. - numExtB := 0. - ^self directedSuperclassSend]]. + extB >= 64 ifTrue: [ + argumentCount := (byte bitAnd: 7) + (extB - 64 << 3). + extB := 0. + numExtB := 0. + ^ self directedSuperclassSend ]. argumentCount := (byte bitAnd: 7) + (extB << 3). extB := 0. numExtB := 0. @@ -7412,7 +7368,7 @@ StackInterpreter >> includesBehavior: aClass ThatOf: aSuperclass [ { #category : 'simulation support' } StackInterpreter >> initExtensions [ - BytecodeSetHasExtensions ifTrue: [extA := numExtB := extB := 0] + extA := numExtB := extB := 0 ] { #category : 'object memory support' } @@ -10989,12 +10945,6 @@ StackInterpreter >> primitiveObject: actualReceiver perform: selector withArgume argumentCount := arraySize. messageSelector := selector. self sendBreakpoint: messageSelector receiver: actualReceiver. - self printSends ifTrue: - [self printActivationNameForSelector: messageSelector - startClass: (lookupClassOrNil isNil - ifTrue: [objectMemory fetchClassOf: actualReceiver] - ifFalse: [lookupClassOrNil]); - cr]. self findNewMethodInClassTag: (lookupClassOrNil isNil ifTrue: [objectMemory fetchClassTagOf: actualReceiver] ifFalse: [objectMemory classTagForClass: lookupClassOrNil]). @@ -11450,12 +11400,6 @@ StackInterpreter >> printDecodeMethodHeaderOop: methodHeaderOop [ print: ' nTemps '; printNum: (self temporaryCountOfMethodHeader: methodHeaderOop) ] -{ #category : 'debug printing' } -StackInterpreter >> printExternalHeadFrame [ - - self printFrame: framePointer WithSP: stackPointer -] - { #category : 'debug printing' } StackInterpreter >> printFloat: f [ "For testing in Smalltalk, this method should be overridden in a subclass." @@ -12222,11 +12166,6 @@ StackInterpreter >> printProcsOnList: procList [ ^nil]] ] -{ #category : 'debug printing' } -StackInterpreter >> printSends [ - ^false -] - { #category : 'debug printing' } StackInterpreter >> printStackCallStack [ @@ -12659,7 +12598,6 @@ StackInterpreter >> pushFullClosureNumArgs: numArgs copiedValues: numCopiedArg c numArgs: numArgs numCopiedValues: numCopiedArg compiledBlock: compiledBlock. - self maybeTraceBlockCreation: newClosure. receiverIsOnStack ifFalse: [ startIndex := FullClosureFirstCopiedValueIndex. @@ -15176,30 +15114,6 @@ StackInterpreter >> superclassSend [ self commonSendOrdinary ] -{ #category : 'debug support' } -StackInterpreter >> symbolicMethod: aMethod [ - - self transcript - newLine; - nextPutAll: - ((String streamContents: - [:ts| | prim | - (prim := self primitiveIndexOf: aMethod) > 0 ifTrue: - [ts nextPutAll: '. - (self isQuickPrimitiveIndex: prim) ifTrue: - [ts nextPutAll: ' quick method'; cr; flush. - ^self]. - ts cr]. - (InstructionPrinter - on: (VMCompiledMethodProxy new - for: aMethod - coInterpreter: self - objectMemory: objectMemory)) - indent: 0; - printInstructionsOn: ts]) copyReplaceAll: 'a VMObjectProxy for ' with: ''); - flush -] - { #category : 'process primitive support' } StackInterpreter >> synchronousSignal: aSemaphore [ "Signal the given semaphore from within the interpreter. diff --git a/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st b/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st index 3e19d3e0a90..204da733d23 100644 --- a/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st +++ b/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st @@ -2477,11 +2477,6 @@ StackInterpreterPrimitives >> primitivePerform [ self pop: 1. lookupClassTag := objectMemory fetchClassTagOf: newReceiver. self sendBreakpoint: messageSelector receiver: newReceiver. - self printSends ifTrue: [ - self - printActivationNameForSelector: messageSelector - startClass: (objectMemory classForClassTag: lookupClassTag); - cr ]. self findNewMethodInClassTag: lookupClassTag. "Only test CompiledMethods for argument count - other objects will have to take their chances" diff --git a/smalltalksrc/VMMaker/StackInterpreterSimulator.class.st b/smalltalksrc/VMMaker/StackInterpreterSimulator.class.st index 30b99dca3b4..deb0653a5e7 100644 --- a/smalltalksrc/VMMaker/StackInterpreterSimulator.class.st +++ b/smalltalksrc/VMMaker/StackInterpreterSimulator.class.st @@ -479,47 +479,6 @@ StackInterpreterSimulator >> dumpMethodHeader: hdr [ ] ] -{ #category : 'compiled methods' } -StackInterpreterSimulator >> endPCOf: aMethod [ - "Determine the endPC of a method in the heap using interpretation that looks for returns and uses branches to skip intervening bytecodes." - | pc end farthestContinuation prim encoderClass inst is | - (prim := self primitiveIndexOf: aMethod) > 0 ifTrue: - [(self isQuickPrimitiveIndex: prim) ifTrue: - [^(self startPCOfMethod: aMethod) - 1]]. - encoderClass := self encoderClassForHeader: (objectMemory methodHeaderOf: aMethod). - is := (InstructionStream - on: (VMCompiledMethodProxy new - for: aMethod - coInterpreter: self - objectMemory: objectMemory)). - pc := farthestContinuation := self startPCOfMethod: aMethod. - end := objectMemory numBytesOf: aMethod. - is pc: pc + 1. - [pc <= end] whileTrue: - [inst := encoderClass interpretNextInstructionFor: MessageCatcher new in: is. - inst selector - caseOf: { - [#pushClosureCopyNumCopiedValues:numArgs:blockSize:] - -> [is pc: is pc + inst arguments last. - farthestContinuation := farthestContinuation max: pc]. - [#jump:] -> [farthestContinuation := farthestContinuation max: pc + inst arguments first]. - [#jump:if:] -> [farthestContinuation := farthestContinuation max: pc + inst arguments first]. - [#methodReturnConstant:] -> [pc >= farthestContinuation ifTrue: [end := pc]]. - [#methodReturnReceiver] -> [pc >= farthestContinuation ifTrue: [end := pc]]. - [#methodReturnTop] -> [pc >= farthestContinuation ifTrue: [end := pc]]. - "This is for CompiledBlock/FullBlockClosure. Since the response to pushClosure... above - skips over all block bytecoes, we will only see a blockReturnTop if it is at the top level, - and so it must be a blockReturnTop in a CompiledBlock for a FullBlockClosure." - [#blockReturnTop] -> [pc >= farthestContinuation ifTrue: [end := pc]]. - [#branchIfInstanceOf:distance:] - -> [farthestContinuation := farthestContinuation max: pc + inst arguments last]. - [#branchIfNotInstanceOf:distance:] - -> [farthestContinuation := farthestContinuation max: pc + inst arguments last] } - otherwise: []. - pc := is pc - 1]. - ^end -] - { #category : 'interpreter shell' } StackInterpreterSimulator >> fetchByte [ ^objectMemory byteAt: (instructionPointer := instructionPointer + 1). @@ -1197,11 +1156,6 @@ StackInterpreterSimulator >> printNum: anInteger [ traceOn ifTrue: [ transcript print: anInteger ]. ] -{ #category : 'debug printing' } -StackInterpreterSimulator >> printSends [ - ^printSends or: [printBytecodeAtEachStep] -] - { #category : 'debug printing' } StackInterpreterSimulator >> printSends: aBoolean [ printSends := aBoolean diff --git a/smalltalksrc/VMMaker/StackToRegisterMappingCogit.class.st b/smalltalksrc/VMMaker/StackToRegisterMappingCogit.class.st index 543a6778d65..ad388f463cf 100644 --- a/smalltalksrc/VMMaker/StackToRegisterMappingCogit.class.st +++ b/smalltalksrc/VMMaker/StackToRegisterMappingCogit.class.st @@ -115,14 +115,6 @@ Class { #name : 'StackToRegisterMappingCogit', #superclass : 'SimpleStackBasedCogit', #instVars : [ - 'prevBCDescriptor', - 'numPushNilsFunction', - 'pushNilSizeFunction', - 'methodOrBlockNumTemps', - 'regArgsHaveBeenPushed', - 'simStack', - 'simStackPtr', - 'simSpillBase', 'ceCallCogCodePopReceiverArg0Regs', 'ceCallCogCodePopReceiverArg1Arg0Regs', 'methodAbortTrampolines', @@ -131,13 +123,10 @@ Class { 'ceCall0ArgsPIC', 'ceCall1ArgsPIC', 'ceCall2ArgsPIC', - 'debugStackPointers', - 'debugFixupBreaks', 'realCECallCogCodePopReceiverArg0Regs', 'realCECallCogCodePopReceiverArg1Arg0Regs', - 'deadCode', - 'useTwoPaths', - 'counterIndex' + 'counterIndex', + 'compileTimeState' ], #pools : [ 'CogCompilationConstants', @@ -145,10 +134,6 @@ Class { 'VMObjectIndices', 'VMStackFrameOffsets' ], - #classInstVars : [ - 'numPushNilsFunction', - 'pushNilSizeFunction' - ], #category : 'VMMaker-JIT', #package : 'VMMaker', #tag : 'JIT' @@ -156,8 +141,14 @@ Class { { #category : 'translation' } StackToRegisterMappingCogit class >> ancilliaryClasses [ - ^super ancilliaryClasses, - { self basicNew simStackEntryClass. self basicNew bytecodeFixupClass. CogSSOptStatus } + + ^ super ancilliaryClasses , { + self basicNew simStackEntryClass. + self basicNew bytecodeFixupClass. + + "Declare CogCompileTimeStackState before, it's used by CogStackToRegisterCompilationState" + CogCompileTimeStackState. + CogStackToRegisterCompilationState } ] { #category : 'documentation' } @@ -238,31 +229,16 @@ StackToRegisterMappingCogit class >> declareCVarsIn: aCodeGen [ declareC: 'void (*ceCallCogCodePopReceiverArg1Arg0Regs)(void)'; var: #realCECallCogCodePopReceiverArg1Arg0Regs declareC: 'void (*realCECallCogCodePopReceiverArg1Arg0Regs)(void)'; - var: 'simStack' - declareC: 'SimStackEntry simStack[', self simStackSlots asString, ']'; - var: 'simSelf' - type: #CogSimStackEntry; - var: #optStatus - type: #CogSSOptStatus; - var: 'prevBCDescriptor' - type: #'BytecodeDescriptor *'. - - self numPushNilsFunction ifNotNil: - [aCodeGen - var: 'numPushNilsFunction' - declareC: 'sqInt (* const numPushNilsFunction)(struct _BytecodeDescriptor *,sqInt,sqInt,sqInt) = ', (aCodeGen cFunctionNameFor: self numPushNilsFunction); - var: 'pushNilSizeFunction' - declareC: 'sqInt (* const pushNilSizeFunction)(sqInt,sqInt) = ', (aCodeGen cFunctionNameFor: self pushNilSizeFunction)]. + declareVar: #aCompileTimeState + type: #CogStackToRegisterCompilationState; + var: #compileTimeState + declareC: 'CogStackToRegisterCompilationState * const compileTimeState = &aCompileTimeState' ] { #category : 'class initialization' } StackToRegisterMappingCogit class >> initializeBytecodeTableForSistaV1 [ "StackToRegisterMappingCogit initializeBytecodeTableForSistaV1" - numPushNilsFunction := #sistaV1:Num:Push:Nils:. - pushNilSizeFunction := #sistaV1PushNilSize:numInitialNils:. - BytecodeSetHasDirectedSuperSend := true. - BytecodeSetHasExtensions := true. FirstSpecialSelector := 96. NumSpecialSelectors := 32. self flag: @@ -436,14 +412,7 @@ StackToRegisterMappingCogit class >> mustBeGlobalAndExport: var [ { #category : 'translation' } StackToRegisterMappingCogit class >> mustBeGlobalInFile: var [ - ^ #( #aMethodLabel #generatorTable ) includes: var -] - -{ #category : 'accessing' } -StackToRegisterMappingCogit class >> numPushNilsFunction [ - "Answer the value of numPushNilsFunction" - - ^numPushNilsFunction + ^ #( #aMethodLabel #generatorTable aCompileTimeState ) includes: var ] { #category : 'accessing' } @@ -454,21 +423,6 @@ StackToRegisterMappingCogit class >> numTrampolines [ "self instVarNames select: [:ea| ea beginsWith: 'ce']" ] -{ #category : 'accessing' } -StackToRegisterMappingCogit class >> pushNilSizeFunction [ - "Answer the value of pushNilSizeFunction" - - ^ pushNilSizeFunction -] - -{ #category : 'translation' } -StackToRegisterMappingCogit class >> requiredMethodNames: options [ - ^(super requiredMethodNames: options) - add: self numPushNilsFunction; - add: self pushNilSizeFunction; - yourself -] - { #category : 'translation' } StackToRegisterMappingCogit class >> shouldGenerateTypedefFor: aStructClass [ "Hack to work-around mutliple definitions. Sometimes a type has been defined in an include." @@ -476,11 +430,6 @@ StackToRegisterMappingCogit class >> shouldGenerateTypedefFor: aStructClass [ and: [super shouldGenerateTypedefFor: aStructClass] ] -{ #category : 'translation' } -StackToRegisterMappingCogit class >> simNativeStackSlots [ - ^ self basicNew simNativeStackSlots -] - { #category : 'translation' } StackToRegisterMappingCogit class >> simStackSlots [ ^ self basicNew simStackSlots @@ -619,14 +568,14 @@ StackToRegisterMappingCogit >> allocateEqualsEqualsRegistersArgNeedsReg: argNeed self allocateRegForStackTopTwoEntriesInto: [ :rTop :rNext | argReg := rTop. rcvrReg := rNext ]. - self ssTop copyToReg: argReg. + compileTimeState simStackState ssTop copyToReg: argReg. (self ssValue: 1) copyToReg: rcvrReg ] ifFalse: [ argReg := self allocateRegForStackEntryAt: 0. - self ssTop copyToReg: argReg ] ] + compileTimeState simStackState ssTop copyToReg: argReg ] ] ifFalse: [ self assert: rcvrNeedsReg. - self deny: self ssTop spilled. + self deny: compileTimeState simStackState ssTop spilled. rcvrReg := self allocateRegForStackEntryAt: 1. (self ssValue: 1) copyToReg: rcvrReg ]. @@ -695,8 +644,8 @@ StackToRegisterMappingCogit >> allocateRegForStackTopThreeEntriesInto: trinaryBl topRegistersMask := 0. rTop := rNext := rThird := NoReg. - (self ssTop registerOrNone ~= NoReg and: [ thirdIsReceiver not or: [ self ssTop registerOrNone ~= ReceiverResultReg ] ]) ifTrue: - [ topRegistersMask := self registerMaskFor: (rTop := self ssTop registerOrNone)]. + (compileTimeState simStackState ssTop registerOrNone ~= NoReg and: [ thirdIsReceiver not or: [ compileTimeState simStackState ssTop registerOrNone ~= ReceiverResultReg ] ]) ifTrue: + [ topRegistersMask := self registerMaskFor: (rTop := compileTimeState simStackState ssTop registerOrNone)]. ((self ssValue: 1) registerOrNone ~= NoReg and: [ thirdIsReceiver not or: [ (self ssValue: 1) registerOrNone ~= ReceiverResultReg ] ]) ifTrue: [ topRegistersMask := topRegistersMask bitOr: (self registerMaskFor: (rNext := (self ssValue: 1) registerOrNone))]. ((self ssValue: 2) registerOrNone ~= NoReg and: [thirdIsReceiver not or: [ (self ssValue: 2) registerOrNone = ReceiverResultReg ] ]) ifTrue: @@ -733,8 +682,8 @@ StackToRegisterMappingCogit >> allocateRegForStackTopTwoEntriesInto: binaryBlock topRegistersMask := 0. rTop := rNext := NoReg. - self ssTop registerOrNone ~= NoReg ifTrue: - [ rTop := self ssTop registerOrNone]. + compileTimeState simStackState ssTop registerOrNone ~= NoReg ifTrue: + [ rTop := compileTimeState simStackState ssTop registerOrNone]. (self ssValue: 1) registerOrNone ~= NoReg ifTrue: [ topRegistersMask := self registerMaskFor: (rNext := (self ssValue: 1) registerOrNone)]. @@ -818,9 +767,9 @@ StackToRegisterMappingCogit >> annotateInstructionForBytecode [ StackToRegisterMappingCogit >> anyReferencesToRegister: reg inAllButTopNItems: n [ | regMask | regMask := self registerMaskFor: reg. - simStackPtr - n to: 0 by: -1 do: + compileTimeState simStackState simStackPtr - n to: 0 by: -1 do: [:i| - ((self simStackAt: i) registerMask anyMask: regMask) ifTrue: + ((compileTimeState simStackState simStackAt: i) registerMask anyMask: regMask) ifTrue: [^true]]. ^false ] @@ -829,26 +778,31 @@ StackToRegisterMappingCogit >> anyReferencesToRegister: reg inAllButTopNItems: n StackToRegisterMappingCogit >> anyReferencesToRegister: reg inTopNItems: n [ | regMask | regMask := self registerMaskFor: reg. - simStackPtr to: simStackPtr - n + 1 by: -1 do: + compileTimeState simStackState simStackPtr to: compileTimeState simStackState simStackPtr - n + 1 by: -1 do: [:i| - ((self simStackAt: i) registerMask anyMask: regMask) ifTrue: + ((compileTimeState simStackState simStackAt: i) registerMask anyMask: regMask) ifTrue: [^true]]. ^false ] { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> assertCorrectSimStackPtr [ - "Would like to assert simply simSpillBase > methodOrBlockNumTemps but can't because of the initialNils hack for nested blocks in SqueakV3PlusClosures" - self assert: (simSpillBase >= methodOrBlockNumTemps). - (needsFrame and: [simSpillBase > 0]) ifTrue: - [self assert: (self simStackAt: simSpillBase - 1) spilled == true. - self assert: (simSpillBase > simStackPtr or: [(self simStackAt: simSpillBase) spilled == false])]. - self cCode: '' inSmalltalk: - [deadCode ifFalse: - [self assert: simStackPtr + (needsFrame ifTrue: [0] ifFalse: [1]) - = (self debugStackPointerFor: bytecodePC)]]. + + + self assert: + compileTimeState simStackState simSpillBase + >= compileTimeState methodOrBlockNumTemps. + (needsFrame and: [ compileTimeState simStackState simSpillBase > 0 ]) + ifTrue: [ + self assert: (compileTimeState simStackState simStackAt: + compileTimeState simStackState simSpillBase - 1) spilled + == true. + self assert: (compileTimeState simStackState simSpillBase + > compileTimeState simStackState simStackPtr or: [ + (compileTimeState simStackState simStackAt: + compileTimeState simStackState simSpillBase) spilled == false ]) ] ] { #category : 'simulation stack' } @@ -936,11 +890,11 @@ StackToRegisterMappingCogit >> compileAbstractInstructionsFrom: start through: e bytecodePC := start. nExts := result := 0. descriptor := nil. - deadCode := false. + compileTimeState deadCode: false. [self mergeWithFixupIfRequired: (fixup := self fixupAt: bytecodePC). descriptor := self loadBytesAndGetDescriptor. nextOpcodeIndex := opcodeIndex. - result := deadCode + result := compileTimeState deadCode ifTrue: [self mapDeadDescriptorIfNeeded: descriptor] ifFalse: [self perform: descriptor generator]. result = 0 ifTrue: [self assertExtsAreConsumed: descriptor]. @@ -955,24 +909,20 @@ StackToRegisterMappingCogit >> compileAbstractInstructionsFrom: start through: e { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> compileCogFullBlockMethod: numCopied [ - methodOrBlockNumTemps := coInterpreter tempCountOf: methodObj. - self cCode: '' inSmalltalk: - [debugStackPointers := coInterpreter debugStackPointersFor: methodObj]. + compileTimeState methodOrBlockNumTemps: (coInterpreter tempCountOf: methodObj). ^super compileCogFullBlockMethod: numCopied ] { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> compileCogMethod: selector [ - methodOrBlockNumTemps := coInterpreter tempCountOf: methodObj. - self cCode: '' inSmalltalk: - [debugStackPointers := coInterpreter debugStackPointersFor: methodObj]. + compileTimeState methodOrBlockNumTemps: (coInterpreter tempCountOf: methodObj). ^super compileCogMethod: selector ] { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> compileEntireMethod [ "Compile the abstract instructions for the entire method, including blocks." - regArgsHaveBeenPushed := false. + compileTimeState regArgsHaveBeenPushed: false. ^super compileEntireMethod ] @@ -981,15 +931,15 @@ StackToRegisterMappingCogit >> compileFrameBuild [ "Build a frame for a CogMethod activation. See CoInterpreter class>>initializeFrameIndices. Override to push the register receiver and register arguments, if any." self cppIf: IMMUTABILITY ifTrue: - [useTwoPaths ifTrue: + [compileTimeState useTwoPaths ifTrue: [self compileTwoPathFrameBuild. ^self]]. needsFrame ifFalse: - [useTwoPaths ifTrue: + [compileTimeState useTwoPaths ifTrue: [self compileTwoPathFramelessInit]. self initSimStackForFramelessMethod: initialPC. ^self]. - self deny: useTwoPaths. + self deny: compileTimeState useTwoPaths. self genPushRegisterArgs. super compileFrameBuild. self initSimStackForFramefulMethod: initialPC @@ -1005,9 +955,9 @@ StackToRegisterMappingCogit >> compileFullBlockFramelessEntry: numCopied [ { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> compileFullBlockMethodFrameBuild: numCopied [ - useTwoPaths ifTrue: + compileTimeState useTwoPaths ifTrue: [ "method with only inst var store, we compile only slow path for now" - useTwoPaths := false. + compileTimeState useTwoPaths: false. self cppIf: IMMUTABILITY ifTrue: [ needsFrame := true ] ]. needsFrame ifFalse: [self assert: numCopied = 0. @@ -1018,6 +968,11 @@ StackToRegisterMappingCogit >> compileFullBlockMethodFrameBuild: numCopied [ self initSimStackForFramefulMethod: initialPC ] +{ #category : 'accessing' } +StackToRegisterMappingCogit >> compileTimeState [ + ^ compileTimeState +] + { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> compileTwoPathFrameBuild [ "We are in a method where the frame is needed *only* for instance variable store, typically a setter method. @@ -1029,7 +984,7 @@ StackToRegisterMappingCogit >> compileTwoPathFrameBuild [ similar for literal variable stores, but we don't as it's too uncommon." | jumpImmutable jumpOld | - self assert: useTwoPaths. + self assert: compileTimeState useTwoPaths. jumpImmutable := objectRepresentation genJumpImmutable: ReceiverResultReg scratchReg: TempReg. jumpOld := objectRepresentation genJumpInOldSpace: ReceiverResultReg. "first path. The receiver is mutable" @@ -1037,7 +992,7 @@ StackToRegisterMappingCogit >> compileTwoPathFrameBuild [ self initSimStackForFramelessMethod: initialPC. self compileMethodBody. "second path. The receiver is mutable" - useTwoPaths := false. "reset because it impacts inst var store compilation" + compileTimeState useTwoPaths: false. "reset because it impacts inst var store compilation" needsFrame := true. jumpOld jmpTarget: (jumpImmutable jmpTarget: self Label). self genPushRegisterArgs. @@ -1053,22 +1008,16 @@ StackToRegisterMappingCogit >> compileTwoPathFramelessInit [ | jumpOld | self deny: IMMUTABILITY. self deny: needsFrame. - self assert: useTwoPaths. + self assert: compileTimeState useTwoPaths. jumpOld := objectRepresentation genJumpInOldSpace: ReceiverResultReg. "first path. The receiver is young" self initSimStackForFramelessMethod: initialPC. self compileMethodBody. "second path. The receiver is old" - useTwoPaths := false. "reset because it impacts inst var store compilation" + compileTimeState useTwoPaths: false. "reset because it impacts inst var store compilation" jumpOld jmpTarget: self Label ] -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> debugStackPointerFor: bcpc [ - - ^(debugStackPointers at: bcpc) + (needsFrame ifTrue: [0] ifFalse: [1]) -] - { #category : 'bytecode generators' } StackToRegisterMappingCogit >> doubleExtendedDoAnythingBytecode [ "Replaces the Blue Book double-extended send [132], in which the first byte was wasted on 8 bits of argument count. @@ -1112,44 +1061,43 @@ StackToRegisterMappingCogit >> doubleExtendedDoAnythingBytecode [ StackToRegisterMappingCogit >> duplicateTopBytecode [ | desc | - desc := self ssTopDescriptor. + desc := compileTimeState simStackState ssTopDescriptor. ^self ssPushDesc: desc ] { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> ensureFixupAt: targetPC [ - ^ self ensureFixupAt: targetPC withStackPointer: simStackPtr + ^ self ensureFixupAt: targetPC withStackPointer: compileTimeState simStackState simStackPtr ] { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> ensureFixupAt: targetPC withStackPointer: aStackPointer [ "Make sure there's a flagged fixup at the target pc in fixups. Initially a fixup's target is just a flag. Later on it is replaced with a proper instruction." + - | fixup | - fixup := self fixupAt: targetPC. - self cCode: '' inSmalltalk: - [self assert: aStackPointer = (self debugStackPointerFor: targetPC). - (fixup isMergeFixupOrIsFixedUp - and: [fixup isBackwardBranchFixup not]) ifTrue: "ignore backward branch targets" - [self assert: fixup simStackPtr = aStackPointer]]. - + | fixup | + fixup := self fixupAt: targetPC. + self cCode: '' inSmalltalk: [ + (fixup isMergeFixupOrIsFixedUp and: [ + fixup isBackwardBranchFixup not ]) ifTrue: [ "ignore backward branch targets" + self assert: fixup simStackPtr = aStackPointer ] ]. + fixup isNonMergeFixupOrNotAFixup - ifTrue: "convert a non-merge into a merge" - [fixup becomeMergeFixup. - fixup simStackPtr: aStackPointer ] - ifFalse: - [fixup isBackwardBranchFixup - ifTrue: "this is the target of a backward branch and + ifTrue: [ "convert a non-merge into a merge" + fixup becomeMergeFixup. + fixup simStackPtr: aStackPointer ] + ifFalse: [ + fixup isBackwardBranchFixup + ifTrue: [ "this is the target of a backward branch and so doesn't have a simStackPtr assigned yet." - [fixup simStackPtr: aStackPointer ] - ifFalse: - [self assert: fixup simStackPtr = aStackPointer ]]. + fixup simStackPtr: aStackPointer ] + ifFalse: [ self assert: fixup simStackPtr = aStackPointer ] ]. fixup recordBcpc: bytecodePC. - ^fixup + ^ fixup ] { #category : 'compile abstract instructions' } @@ -1162,11 +1110,6 @@ StackToRegisterMappingCogit >> ensureNonMergeFixupAt: targetPC [ fixup := self fixupAt: targetPC. fixup notAFixup ifTrue: [fixup becomeNonMergeFixup]. - self cCode: '' inSmalltalk: - [fixup isMergeFixupOrIsFixedUp ifTrue: - [self assert: - (fixup isBackwardBranchFixup - or: [fixup simStackPtr = (self debugStackPointerFor: targetPC)])]]. fixup recordBcpc: bytecodePC. ^fixup ] @@ -1335,7 +1278,7 @@ StackToRegisterMappingCogit >> freeAnyFloatRegNotConflictingWith: regMask [ | reg index | self assert: needsFrame. reg := NoReg. - index := simSpillBase max: 0. + index := compileTimeState simStackState simSpillBase max: 0. self deny: reg = NoReg. self ssAllocateRequiredFloatReg: reg. ^ reg @@ -1349,10 +1292,10 @@ StackToRegisterMappingCogit >> freeAnyRegNotConflictingWith: regMask [ | reg index | self assert: needsFrame. reg := NoReg. - index := simSpillBase max: 0. - [reg = NoReg and: [index < simStackPtr]] whileTrue: + index := compileTimeState simStackState simSpillBase max: 0. + [reg = NoReg and: [index < compileTimeState simStackState simStackPtr]] whileTrue: [ | desc | - desc := self simStackAt: index. + desc := compileTimeState simStackState simStackAt: index. desc type = SSRegister ifTrue: [(regMask anyMask: (self registerMaskFor: desc registerr)) ifFalse: [reg := desc registerr]]. @@ -1406,7 +1349,7 @@ StackToRegisterMappingCogit >> genAddFloat64Vector [ StackToRegisterMappingCogit >> genBlockReturn [ "Return from block, assuming result already loaded into ReceiverResultReg." super genBlockReturn. - deadCode := true. "can't fall through" + compileTimeState deadCode: true. "can't fall through" ^0 ] @@ -1474,7 +1417,7 @@ StackToRegisterMappingCogit >> genCmpArgIsConstant: argIsConstant rcvrIsConstant self assert: (argReg ~= NoReg or: [rcvrReg ~= NoReg]). argIsConstant - ifTrue: [ self genCmpConstant: self ssTop constant R: rcvrReg ] + ifTrue: [ self genCmpConstant: compileTimeState simStackState ssTop constant R: rcvrReg ] ifFalse: [ rcvrIsConstant ifTrue: [ self genCmpConstant: (self ssValue: 1) constant R: argReg ] ifFalse: [ self CmpR: argReg R: rcvrReg ] ]. @@ -1598,7 +1541,7 @@ StackToRegisterMappingCogit >> genForwardersInlinedIdenticalOrNotIf: orNot [ However, if one of the operand is an unnanotable constant, does not allocate a register for it (machine code will use operations on constants) and does not generate forwarder checks." unforwardRcvr := (objectRepresentation isUnannotatableConstant: (self ssValue: 1)) not. - unforwardArg := (objectRepresentation isUnannotatableConstant: self ssTop) not. + unforwardArg := (objectRepresentation isUnannotatableConstant: compileTimeState simStackState ssTop) not. self allocateEqualsEqualsRegistersArgNeedsReg: unforwardArg rcvrNeedsReg: unforwardRcvr into: [ :rcvr :arg | rcvrReg := rcvr. @@ -1623,7 +1566,7 @@ StackToRegisterMappingCogit >> genForwardersInlinedIdenticalOrNotIf: orNot [ receiverConstant := rcvrIsConstant ifTrue: [ (self ssValue: 1) constant ]. - argumentConstant := argIsConstant ifTrue: [ self ssTop constant ]. + argumentConstant := argIsConstant ifTrue: [ compileTimeState simStackState ssTop constant ]. self ssPop: 2. label := self Label. @@ -1639,10 +1582,10 @@ StackToRegisterMappingCogit >> genForwardersInlinedIdenticalOrNotIf: orNot [ define non-merge fixups and leave the cond bytecode to set the mergeness." (self fixupAt: nextPC) notAFixup ifTrue: [ "The next instruction is dead. we can skip it." - deadCode := true. + compileTimeState deadCode: true. self ensureFixupAt: targetBytecodePC. self ensureFixupAt: postBranchPC ] - ifFalse: [ self deny: deadCode ]. "push dummy value below" + ifFalse: [ self deny: compileTimeState deadCode ]. "push dummy value below" self assert: (unforwardArg or: [ unforwardRcvr ]). orNot == branchDescriptor isBranchTrue @@ -1665,7 +1608,7 @@ StackToRegisterMappingCogit >> genForwardersInlinedIdenticalOrNotIf: orNot [ ifNotForwarder: (self cCoerceSimple: fixup to: #'AbstractInstruction *'). "Not reached, execution flow has jumped to fixup" - deadCode ifFalse: [ self ssPushConstant: objectMemory trueObject ]. "dummy value" + compileTimeState deadCode ifFalse: [ self ssPushConstant: objectMemory trueObject ]. "dummy value" ^ 0 ] @@ -1690,7 +1633,7 @@ StackToRegisterMappingCogit >> genGenericStorePop: popBoolean MaybeContextSlotIn "Avoid allocating ClassReg if at the top the stack, to avoid extra push/pops, given that we are going to pop it next" self ssAllocateCallReg: ClassReg - upThrough: simStackPtr - 1. + upThrough: compileTimeState simStackState simStackPtr - 1. self ssStoreAndReplacePop: popBoolean toReg: ClassReg. "Flush the rest of the stack now that all stack manipulations have been done. @@ -1738,7 +1681,7 @@ StackToRegisterMappingCogit >> genGenericStorePop: popBoolean slotIndex: slotInd self cppIf: IMMUTABILITY ifTrue: [needsImmCheck ifTrue: - [self ssAllocateRequiredReg: ClassReg upThrough: simStackPtr - 1. "If already classReg don't spill it" + [self ssAllocateRequiredReg: ClassReg upThrough: compileTimeState simStackState simStackPtr - 1. "If already classReg don't spill it" "we replace the top value for the flush" self ssStoreAndReplacePop: popBoolean toReg: ClassReg. self ssFlushStack. @@ -1772,7 +1715,7 @@ StackToRegisterMappingCogit >> genIdenticalNoBranchArgIsConstant: argIsConstant | label jumpEqual jumpNotEqual resultReg receiverStackSlot argumentStackSlot | receiverStackSlot := (self ssValue: 1). - argumentStackSlot := self ssTop. + argumentStackSlot := compileTimeState simStackState ssTop. self ssPop: 2. label := self Label. @@ -1811,12 +1754,12 @@ StackToRegisterMappingCogit >> genInlinedIdenticalOrNotIf: orNot [ primDescriptor := self generatorAt: byte0. - ((objectRepresentation isUnannotatableConstant: self ssTop) + ((objectRepresentation isUnannotatableConstant: compileTimeState simStackState ssTop) and: [ objectRepresentation isUnannotatableConstant: (self ssValue: 1) ]) ifTrue: [self assert: primDescriptor isMapped not. result := (orNot - ifFalse: [self ssTop constant = (self ssValue: 1) constant] - ifTrue: [self ssTop constant ~= (self ssValue: 1) constant]) + ifFalse: [compileTimeState simStackState ssTop constant = (self ssValue: 1) constant] + ifTrue: [compileTimeState simStackState ssTop constant ~= (self ssValue: 1) constant]) ifTrue: [objectMemory trueObject] ifFalse: [objectMemory falseObject]. self ssPop: 2. @@ -1828,7 +1771,7 @@ StackToRegisterMappingCogit >> genInlinedIdenticalOrNotIf: orNot [ { #category : 'bytecode generator support' } StackToRegisterMappingCogit >> genJumpBackTo: targetBytecodePC [ self ssFlushStack. - deadCode := true. "can't fall through" + compileTimeState deadCode: true. "can't fall through" ^super genJumpBackTo: targetBytecodePC ] @@ -1842,7 +1785,7 @@ StackToRegisterMappingCogit >> genJumpIf: boolean to: targetBytecodePC [ | desc fixup ok eventualTarget | eventualTarget := self eventualTargetOf: targetBytecodePC. self ssFlushStackExceptTop: 1. - desc := self ssTop. + desc := compileTimeState simStackState ssTop. (self stackEntryIsBoolean: desc) ifTrue: [ "Must arrange there's a fixup at the target whether it is jumped to or not so that the simStackPtr can be kept correct." @@ -1894,17 +1837,17 @@ StackToRegisterMappingCogit >> genJumpTo: targetBytecodePC [ "If the jump target is a conditional branch and we have a boolean, thread the jumps and output a single one" eventualTarget := eventualTarget + generator numBytes - + (generator isBranchTrue == (self ssTop constant = objectMemory trueObject) + + (generator isBranchTrue == (compileTimeState simStackState ssTop constant = objectMemory trueObject) ifTrue: [self spanFor: generator at: eventualTarget exts: 0 in: methodObj] ifFalse: [0]). "Since we are threading the jumps, spill everything above the top. Leave the top for the next instruction that is assuming that this JUMP instruction did not consume the top" self ssFlushStackExceptTop: 1. - fixup := self ensureFixupAt: eventualTarget withStackPointer: simStackPtr - 1] + fixup := self ensureFixupAt: eventualTarget withStackPointer: compileTimeState simStackState simStackPtr - 1] ifFalse: [self ssFlushStack. fixup := self ensureFixupAt: eventualTarget]. - deadCode := true. "can't fall through" + compileTimeState deadCode: true. "can't fall through" self Jump: fixup. ^0 ] @@ -1961,27 +1904,30 @@ StackToRegisterMappingCogit >> genMappedInlinePrimitive: primIndex [ { #category : 'bytecode generator support' } StackToRegisterMappingCogit >> genMarshalledSend: selectorIndex numArgs: numArgs sendTable: sendTable [ + | annotation | self assert: needsFrame. annotation := self annotationForSendTable: sendTable. "Deal with stale super sends; see SpurMemoryManager's class comment." - (self annotationIsForUncheckedEntryPoint: annotation) ifTrue: - [objectRepresentation genEnsureOopInRegNotForwarded: ReceiverResultReg scratchReg: TempReg]. + (self annotationIsForUncheckedEntryPoint: annotation) ifTrue: [ + objectRepresentation + genEnsureOopInRegNotForwarded: ReceiverResultReg + scratchReg: TempReg ]. "0 through (NumSendTrampolines - 2) numArgs sends have the arg count implciti in the trampoline. The last send trampoline (NumSendTrampolines - 1) passes numArgs in SendNumArgsReg." - numArgs >= (NumSendTrampolines - 1) ifTrue: - [self MoveCq: numArgs R: SendNumArgsReg]. - (BytecodeSetHasDirectedSuperSend - and: [annotation - between: IsDirectedSuperSend - and: IsDirectedSuperBindingSend]) ifTrue: - [self genMoveConstant: tempOop R: TempReg]. + numArgs >= (NumSendTrampolines - 1) ifTrue: [ + self MoveCq: numArgs R: SendNumArgsReg ]. + (annotation + between: IsDirectedSuperSend + and: IsDirectedSuperBindingSend) ifTrue: [ + self genMoveConstant: tempOop R: TempReg ]. self genLoadInlineCacheWithSelector: selectorIndex. - (self Call: (sendTable at: (numArgs min: NumSendTrampolines - 1))) annotation: annotation. + (self Call: (sendTable at: (numArgs min: NumSendTrampolines - 1))) + annotation: annotation. self voidReceiverOptStatus. - ^self ssPushRegister: ReceiverResultReg + ^ self ssPushRegister: ReceiverResultReg ] { #category : 'initialization' } @@ -2232,20 +2178,23 @@ StackToRegisterMappingCogit >> genPushLiteralIndex: literalIndex [ "> genPushLiteralVariable: literalIndex [ + | association freeReg | association := self getLiteral: literalIndex. "If followed by a directed super send bytecode, avoid generating any code yet. The association will be passed to the directed send trampoline in a register and fully dereferenced only when first linked. It will be ignored in later sends." - BytecodeSetHasDirectedSuperSend ifTrue: - [self deny: directedSendUsesBinding. - self nextDescriptorExtensionsAndNextPCInto: - [:descriptor :exta :extb :followingPC| - (self isDirectedSuper: descriptor extA: exta extB: extb) ifTrue: - [self ssPushConstant: association. - directedSendUsesBinding := true. - ^0]]]. + self deny: directedSendUsesBinding. + self nextDescriptorExtensionsAndNextPCInto: [ + :descriptor + :exta + :extb + :followingPC | + (self isDirectedSuper: descriptor extA: exta extB: extb) ifTrue: [ + self ssPushConstant: association. + directedSendUsesBinding := true. + ^ 0 ] ]. freeReg := self allocateRegNotConflictingWith: 0. "N.B. Do _not_ use ReceiverResultReg to avoid overwriting receiver in assignment in frameless methods." "So far descriptors are not rich enough to describe the entire dereference so generate the register @@ -2259,7 +2208,7 @@ StackToRegisterMappingCogit >> genPushLiteralVariable: literalIndex [ sourceReg: TempReg destReg: freeReg. self ssPushRegister: freeReg. - ^0 + ^ 0 ] { #category : 'bytecode generator support' } @@ -2359,10 +2308,10 @@ StackToRegisterMappingCogit >> genPushRegisterArgs [ "This won't be as clumsy on a RISC. But putting the receiver and args above the return address means the CoInterpreter has a single machine-code frame format which saves us a lot of work." - (regArgsHaveBeenPushed + (compileTimeState regArgsHaveBeenPushed or: [methodOrBlockNumArgs > self numRegArgs]) ifFalse: [backEnd genPushRegisterArgsForNumArgs: methodOrBlockNumArgs scratchReg: SendNumArgsReg. - regArgsHaveBeenPushed := true] + compileTimeState regArgsHaveBeenPushed: true] ] { #category : 'bytecode generator support' } @@ -2404,7 +2353,7 @@ StackToRegisterMappingCogit >> genPushTemporaryVariable: index [ "If a frameless method (not a block), only argument temps can be accessed. This is assured by the use of needsFrameIfMod16GENumArgs: in pushTemp." self assert: (inBlock > 0 or: [needsFrame or: [index < methodOrBlockNumArgs]]). - ^self ssPushDesc: (simStack at: index + 1) + ^self ssPushDesc: (compileTimeState simStackState simStackDescriptorAt: index + 1) ] { #category : 'bytecode generators' } @@ -2439,8 +2388,8 @@ StackToRegisterMappingCogit >> genSend: selectorIndex numArgs: numArgs [ { #category : 'bytecode generator support' } StackToRegisterMappingCogit >> genSendDirectedSuper: selectorIndex numArgs: numArgs [ | result | - self assert: self ssTop type = SSConstant. - tempOop := self ssTop constant. + self assert: compileTimeState simStackState ssTop type = SSConstant. + tempOop := compileTimeState simStackState ssTop constant. self ssPop: 1. self marshallSendArguments: numArgs. result := self @@ -2541,9 +2490,9 @@ StackToRegisterMappingCogit >> genSpecialSelectorArithmetic [ primDescriptor := self generatorAt: byte0. - argIsInt := ((argIsConst := self ssTop type = SSConstant) - and: [objectMemory isIntegerObject: (argInt := self ssTop constant)]) - or: [self mclassIsSmallInteger and: [self ssTop isSameEntryAs: self simSelf]]. + argIsInt := ((argIsConst := compileTimeState simStackState ssTop type = SSConstant) + and: [objectMemory isIntegerObject: (argInt := compileTimeState simStackState ssTop constant)]) + or: [self mclassIsSmallInteger and: [compileTimeState simStackState ssTop isSameEntryAs: self simSelf]]. rcvrIsInt := ((rcvrIsConst := (self ssValue: 1) type = SSConstant) and: [objectMemory isIntegerObject: (rcvrInt := (self ssValue: 1) constant)]) @@ -2642,10 +2591,10 @@ StackToRegisterMappingCogit >> genSpecialSelectorArithmetic [ { #category : 'bytecode generators' } StackToRegisterMappingCogit >> genSpecialSelectorClass [ | topReg | - topReg := self ssTop registerOrNone. + topReg := compileTimeState simStackState ssTop registerOrNone. (topReg = NoReg or: [topReg = ClassReg]) - ifTrue: [self ssAllocateRequiredReg: (topReg := SendNumArgsReg) and: ClassReg upThrough: simStackPtr - 1] - ifFalse: [self ssAllocateRequiredReg: ClassReg upThrough: simStackPtr - 1]. + ifTrue: [self ssAllocateRequiredReg: (topReg := SendNumArgsReg) and: ClassReg upThrough: compileTimeState simStackState simStackPtr - 1] + ifFalse: [self ssAllocateRequiredReg: ClassReg upThrough: compileTimeState simStackState simStackPtr - 1]. self ssPopTopToReg: topReg. objectRepresentation @@ -2665,9 +2614,9 @@ StackToRegisterMappingCogit >> genSpecialSelectorComparison [ | nextPC postBranchPC targetPC primDescriptor branchDescriptor rcvrIsInt rcvrIsConst argIsIntConst argInt jumpNotSmallInts inlineCAB index | self ssFlushStackExceptTop: 2. primDescriptor := self generatorAt: byte0. - argIsIntConst := self ssTop type = SSConstant and: [ + argIsIntConst := compileTimeState simStackState ssTop type = SSConstant and: [ objectMemory isIntegerObject: - (argInt := self ssTop constant) ]. + (argInt := compileTimeState simStackState ssTop constant) ]. rcvrIsInt := ((rcvrIsConst := (self ssValue: 1) type = SSConstant) and: [ objectMemory isIntegerObject: @@ -2745,7 +2694,7 @@ StackToRegisterMappingCogit >> genSpecialSelectorComparison [ self annotateInstructionForBytecode. self ensureFixupAt: postBranchPC. self ensureFixupAt: targetPC. - deadCode := true. + compileTimeState deadCode: true. ^ 0 ]. jumpNotSmallInts jmpTarget: self Label. @@ -2766,7 +2715,7 @@ StackToRegisterMappingCogit >> genStaticallyResolvedSpecialSelectorComparison [ | rcvrInt argInt primDescriptor result | primDescriptor := self generatorAt: byte0. - argInt := self ssTop constant. + argInt := compileTimeState simStackState ssTop constant. rcvrInt := (self ssValue: 1) constant. self cCode: '' inSmalltalk: "In Simulator ints are unsigned..." [rcvrInt := objectMemory integerValueOf: rcvrInt. @@ -2937,9 +2886,9 @@ StackToRegisterMappingCogit >> genStorePop: popBoolean ReceiverVariable: slotInd genGenericStorePop: popBoolean slotIndex: slotIndex destReg: ReceiverResultReg - needsStoreCheck: (useTwoPaths not and: [needsStoreCheck]) + needsStoreCheck: (compileTimeState useTwoPaths not and: [needsStoreCheck]) needsRestoreRcvr: true "ReceiverResultReg is kept live with the receiver across the operation" - needsImmutabilityCheck: (needsImmCheck and: [useTwoPaths not]) + needsImmutabilityCheck: (needsImmCheck and: [compileTimeState useTwoPaths not]) ] @@ -3001,7 +2950,7 @@ StackToRegisterMappingCogit >> genStorePop: popBoolean TemporaryVariable: tempIn self MoveR: reg Mw: (self frameOffsetOfTemporary: tempIndex) r: FPReg. - (self simStackAt: tempIndex + 1) bcptr: bytecodePC. "for debugging" + (compileTimeState simStackState simStackAt: tempIndex + 1) bcptr: bytecodePC. "for debugging" ^0 ] @@ -3027,14 +2976,6 @@ StackToRegisterMappingCogit >> genSubFloat64Vector [ ^0 ] -{ #category : 'bytecode generator stores' } -StackToRegisterMappingCogit >> genTraceStores [ - - traceStores > 0 ifTrue: - [ self MoveR: ClassReg R: TempReg. - self CallRT: ceTraceStoreTrampoline ]. -] - { #category : 'bytecode generators' } StackToRegisterMappingCogit >> genUpArrowReturn [ "Generate a method return from within a method or a block. @@ -3049,14 +2990,14 @@ StackToRegisterMappingCogit >> genUpArrowReturn [ ret pc in LR. A fully framed activation is described in CoInterpreter class>initializeFrameIndices. Return pops receiver and arguments off the stack. Callee pushes the result." - deadCode := true. "can't fall through" + compileTimeState deadCode: true. "can't fall through" inBlock > 0 ifTrue: [self assert: needsFrame. self ssFlushStack. self CallRT: ceNonLocalReturnTrampoline. self annotateBytecode: self Label. ^0]. - (self cppIf: IMMUTABILITY ifTrue: [needsFrame and: [useTwoPaths not]] ifFalse: [needsFrame]) + (self cppIf: IMMUTABILITY ifTrue: [needsFrame and: [compileTimeState useTwoPaths not]] ifFalse: [needsFrame]) ifTrue: [ self MoveR: FPReg R: SPReg. self PopR: FPReg. @@ -3067,7 +3008,7 @@ StackToRegisterMappingCogit >> genUpArrowReturn [ [self RetN: ((methodOrBlockNumArgs > self numRegArgs "A method with an interpreter prim will push its register args for the prim. If the failure body is frameless the args must still be popped, see e.g. Behavior>>nextInstance." - or: [regArgsHaveBeenPushed]) + or: [compileTimeState regArgsHaveBeenPushed]) ifTrue: [methodOrBlockNumArgs + 1 * objectMemory wordSize] ifFalse: [0])]. ^0 @@ -3191,52 +3132,44 @@ StackToRegisterMappingCogit >> generateMissAbortTrampolines [ { #category : 'initialization' } StackToRegisterMappingCogit >> generateSendTrampolines [ "Override to generate code to push the register arg(s) for <= numRegArg arity sends." - 0 to: NumSendTrampolines - 1 do: - [:numArgs| - ordinarySendTrampolines - at: numArgs - put: (self genSendTrampolineFor: #ceSend:super:to:numArgs: - numArgs: numArgs - called: (self trampolineName: 'ceSend' numArgs: numArgs) - arg: ClassReg - arg: (self trampolineArgConstant: false) - arg: ReceiverResultReg - arg: (self numArgsOrSendNumArgsReg: numArgs))]. - "Generate these in the middle so they are within [firstSend, lastSend]." - BytecodeSetHasDirectedSuperSend ifTrue: [ - 0 to: NumSendTrampolines - 1 do: [:numArgs| - self - generateSuperSendTrampolineTo: #ceSend:above:to:numArgs: - named: 'ceDirectedSuperSend' - numArgs: numArgs - in: directedSuperSendTrampolines. - self - generateSuperSendTrampolineTo: #ceSend:aboveClassBinding:to:numArgs: - named: 'ceDirectedSuperBindingSend' - numArgs: numArgs - in: directedSuperBindingSendTrampolines ] ]. + 0 to: NumSendTrampolines - 1 do: [ :numArgs | + ordinarySendTrampolines at: numArgs put: (self + genSendTrampolineFor: #ceSend:super:to:numArgs: + numArgs: numArgs + called: (self trampolineName: 'ceSend' numArgs: numArgs) + arg: ClassReg + arg: (self trampolineArgConstant: false) + arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs)) ]. - 0 to: NumSendTrampolines - 1 do: - [:numArgs| - superSendTrampolines - at: numArgs - put: (self genSendTrampolineFor: #ceSend:super:to:numArgs: - numArgs: numArgs - called: (self trampolineName: 'ceSuperSend' numArgs: numArgs) - arg: ClassReg - arg: (self trampolineArgConstant: true) - arg: ReceiverResultReg - arg: (self numArgsOrSendNumArgsReg: numArgs))]. + "Generate these in the middle so they are within [firstSend, lastSend]." + 0 to: NumSendTrampolines - 1 do: [ :numArgs | + self + generateSuperSendTrampolineTo: #ceSend:above:to:numArgs: + named: 'ceDirectedSuperSend' + numArgs: numArgs + in: directedSuperSendTrampolines. + self + generateSuperSendTrampolineTo: + #ceSend:aboveClassBinding:to:numArgs: + named: 'ceDirectedSuperBindingSend' + numArgs: numArgs + in: directedSuperBindingSendTrampolines ]. + + 0 to: NumSendTrampolines - 1 do: [ :numArgs | + superSendTrampolines at: numArgs put: (self + genSendTrampolineFor: #ceSend:super:to:numArgs: + numArgs: numArgs + called: (self trampolineName: 'ceSuperSend' numArgs: numArgs) + arg: ClassReg + arg: (self trampolineArgConstant: true) + arg: ReceiverResultReg + arg: (self numArgsOrSendNumArgsReg: numArgs)) ]. firstSend := ordinarySendTrampolines at: 0. lastSend := superSendTrampolines at: NumSendTrampolines - 1 ] -{ #category : 'initialization' } -StackToRegisterMappingCogit >> generateSistaRuntime [ - "No sita vm" -] - { #category : 'initialization' } StackToRegisterMappingCogit >> generateSuperSendTrampolineTo: function named: name numArgs: numArgs in: table [ @@ -3255,37 +3188,11 @@ StackToRegisterMappingCogit >> generateSuperSendTrampolineTo: function named: na ^ trampoline ] -{ #category : 'initialization' } -StackToRegisterMappingCogit >> generateTracingTrampolines [ - "Generate trampolines for tracing. In the simulator we can save a lot of time - and avoid noise instructions in the lastNInstructions log by short-cutting these - trampolines, but we need them in the real vm." - ceTraceLinkedSendTrampoline := - self genTrampolineFor: #ceTraceLinkedSend: - called: 'ceTraceLinkedSendTrampoline' - arg: ReceiverResultReg - regsToSave: CallerSavedRegisterMask.. - ceTraceBlockActivationTrampoline := - self genTrampolineFor: #ceTraceBlockActivation - called: 'ceTraceBlockActivationTrampoline' - regsToSave: CallerSavedRegisterMask.. - ceTraceStoreTrampoline := - self genTrampolineFor: #ceTraceStoreOf:into: - called: 'ceTraceStoreTrampoline' - arg: TempReg - arg: ReceiverResultReg - regsToSave: CallerSavedRegisterMask.. - self cCode: [] inSmalltalk: - [ceTraceLinkedSendTrampoline := self simulatedTrampolineFor: #ceShortCutTraceLinkedSend:. - ceTraceBlockActivationTrampoline := self simulatedTrampolineFor: #ceShortCutTraceBlockActivation:. - ceTraceStoreTrampoline := self simulatedTrampolineFor: #ceShortCutTraceStore:] -] - { #category : 'simulation stack' } StackToRegisterMappingCogit >> initSimStackForFramefulMethod: startpc [ - simStackPtr := methodOrBlockNumTemps. "N.B. Includes num args" - simSpillBase := methodOrBlockNumTemps + 1. + compileTimeState simStackState simStackPtr: compileTimeState methodOrBlockNumTemps. "N.B. Includes num args" + compileTimeState simStackState simSpillBase: compileTimeState methodOrBlockNumTemps + 1. self simSelf type: SSBaseOffset; spilled: true; @@ -3295,7 +3202,7 @@ StackToRegisterMappingCogit >> initSimStackForFramefulMethod: startpc [ "args" 1 to: methodOrBlockNumArgs do: [:i| | desc | - desc := self simStackAt: i. + desc := compileTimeState simStackState simStackAt: i. desc type: SSBaseOffset; spilled: true; @@ -3303,9 +3210,9 @@ StackToRegisterMappingCogit >> initSimStackForFramefulMethod: startpc [ offset: FoxCallerSavedIP + ((methodOrBlockNumArgs - i + 1) * objectMemory wordSize); bcptr: startpc]. "temps" - methodOrBlockNumArgs + 1 to: simStackPtr do: + methodOrBlockNumArgs + 1 to: compileTimeState simStackState simStackPtr do: [:i| | desc | - desc := self simStackAt: i. + desc := compileTimeState simStackState simStackAt: i. desc type: SSBaseOffset; spilled: true; @@ -3325,10 +3232,10 @@ StackToRegisterMappingCogit >> initSimStackForFramelessBlock: startpc [ spilled: false; registerr: ReceiverResultReg; liveRegister: ReceiverResultReg. - self assert: methodOrBlockNumTemps >= methodOrBlockNumArgs. - 1 to: methodOrBlockNumTemps do: + self assert: compileTimeState methodOrBlockNumTemps >= methodOrBlockNumArgs. + 1 to: compileTimeState methodOrBlockNumTemps do: [:i| | desc | - desc := self simStackAt: i. + desc := compileTimeState simStackState simStackAt: i. desc type: SSBaseOffset; spilled: true; @@ -3337,8 +3244,8 @@ StackToRegisterMappingCogit >> initSimStackForFramelessBlock: startpc [ ifTrue: [methodOrBlockNumArgs - i] ifFalse: [methodOrBlockNumArgs + 1 - i]) * objectMemory wordSize); bcptr: startpc]. - simStackPtr := methodOrBlockNumTemps. "N.B. Includes num args" - simSpillBase := methodOrBlockNumTemps + 1. + compileTimeState simStackState simStackPtr: compileTimeState methodOrBlockNumTemps. "N.B. Includes num args" + compileTimeState simStackState simSpillBase: compileTimeState methodOrBlockNumTemps + 1. ] { #category : 'simulation stack' } @@ -3350,18 +3257,18 @@ StackToRegisterMappingCogit >> initSimStackForFramelessMethod: startpc [ spilled: false; registerr: ReceiverResultReg; liveRegister: ReceiverResultReg. - self assert: methodOrBlockNumTemps = methodOrBlockNumArgs. + self assert: compileTimeState methodOrBlockNumTemps = methodOrBlockNumArgs. self assert: self numRegArgs <= 2. (methodOrBlockNumArgs between: 1 and: self numRegArgs) ifTrue: - [desc := self simStackAt: 1. + [desc := compileTimeState simStackState simStackAt: 1. desc type: SSRegister; spilled: false; registerr: Arg0Reg; bcptr: startpc. methodOrBlockNumArgs > 1 ifTrue: - [desc := self simStackAt: 2. + [desc := compileTimeState simStackState simStackAt: 2. desc type: SSRegister; spilled: false; @@ -3370,7 +3277,7 @@ StackToRegisterMappingCogit >> initSimStackForFramelessMethod: startpc [ ifFalse: [1 to: methodOrBlockNumArgs do: [:i| - desc := self simStackAt: i. + desc := compileTimeState simStackState simStackAt: i. desc type: SSBaseOffset; registerr: SPReg; @@ -3379,15 +3286,15 @@ StackToRegisterMappingCogit >> initSimStackForFramelessMethod: startpc [ ifTrue: [methodOrBlockNumArgs - i] ifFalse: [methodOrBlockNumArgs + 1 - i]) * objectMemory wordSize); bcptr: startpc]]. - simStackPtr := methodOrBlockNumArgs. - simSpillBase := methodOrBlockNumArgs + 1. + compileTimeState simStackState simStackPtr: methodOrBlockNumArgs. + compileTimeState simStackState simSpillBase: methodOrBlockNumArgs + 1. ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> initSimStackPointer: wat [ - simStackPtr := methodOrBlockNumTemps. - simSpillBase := methodOrBlockNumTemps + 1 + compileTimeState simStackState simStackPtr: compileTimeState methodOrBlockNumTemps. + compileTimeState simStackState simSpillBase: compileTimeState methodOrBlockNumTemps + 1 ] { #category : 'compile abstract instructions' } @@ -3398,7 +3305,7 @@ StackToRegisterMappingCogit >> initializeFixup: fixup [ fixup - simStackPtr: simStackPtr; + simStackPtr: compileTimeState simStackState simStackPtr; becomeMergeFixup; setIsBackwardBranchFixup ] @@ -3415,24 +3322,13 @@ StackToRegisterMappingCogit >> initializeFixupAt: targetPC [ self initializeFixup: fixup ] -{ #category : 'span functions' } -StackToRegisterMappingCogit >> isPushNil: descriptor pc: pc nExts: nExts method: aMethodObj [ - - - ^self perform: numPushNilsFunction - with: descriptor - with: pc - with: nExts - with: aMethodObj -] - { #category : 'simulation stack' } StackToRegisterMappingCogit >> liveFloatRegisters [ | regsSet | regsSet := 0. - (simSpillBase max: 0) to: simStackPtr do: + (compileTimeState simStackState simSpillBase max: 0) to: compileTimeState simStackState simStackPtr do: [:i| - regsSet := regsSet bitOr: (self simStackAt: i) floatRegisterMask]. + regsSet := regsSet bitOr: (compileTimeState simStackState simStackAt: i) floatRegisterMask]. ^regsSet ] @@ -3448,9 +3344,9 @@ StackToRegisterMappingCogit >> liveRegisters [ [regsSet := regsSet bitOr: (self registerMaskFor: Arg0Reg). (self numRegArgs > 1 and: [methodOrBlockNumArgs > 1]) ifTrue: [regsSet := regsSet bitOr: (self registerMaskFor: Arg1Reg)]]]. - (simSpillBase max: 0) to: simStackPtr do: + (compileTimeState simStackState simSpillBase max: 0) to: compileTimeState simStackState simStackPtr do: [:i| - regsSet := regsSet bitOr: (self simStackAt: i) registerMask]. + regsSet := regsSet bitOr: (compileTimeState simStackState simStackAt: i) registerMask]. ^regsSet ] @@ -3459,9 +3355,9 @@ StackToRegisterMappingCogit >> liveVectorRegisters [ | regsSet | regsSet := 0. - (simSpillBase max: 0) to: simStackPtr do: [ :i | + (compileTimeState simStackState simSpillBase max: 0) to: compileTimeState simStackState simStackPtr do: [ :i | | ssEntry | - ssEntry := self simStackAt: i. + ssEntry := compileTimeState simStackState simStackAt: i. (ssEntry type = SSVectorRegister) ifTrue: [ regsSet := regsSet bitOr: ssEntry registerMask ] ]. ^ regsSet @@ -3497,9 +3393,9 @@ StackToRegisterMappingCogit >> marshallSendArguments: numArgs [ (numSpilled > 0 or: [ anyRefs ]) ifTrue: [ self ssFlushStack. - (self simStackAt: simStackPtr - numArgs) copyToReg: ReceiverResultReg ] + (compileTimeState simStackState simStackAt: compileTimeState simStackState simStackPtr - numArgs) copyToReg: ReceiverResultReg ] ifFalse: [ - (self simStackAt: simStackPtr - numArgs) + (compileTimeState simStackState simStackAt: compileTimeState simStackState simStackPtr - numArgs) copyToReg: ReceiverResultReg; type: SSRegister; registerr: ReceiverResultReg. @@ -3516,14 +3412,14 @@ StackToRegisterMappingCogit >> marshallSendArguments: numArgs [ numArgs > 0 ifTrue: [ (self numRegArgs > 1 and: [ numArgs > 1 ]) ifTrue: [ - self ssAllocateRequiredReg: Arg0Reg upThrough: simStackPtr - 2. - self ssAllocateRequiredReg: Arg1Reg upThrough: simStackPtr - 1 ] - ifFalse: [ self ssAllocateRequiredReg: Arg0Reg upThrough: simStackPtr - 1 ] ]. + self ssAllocateRequiredReg: Arg0Reg upThrough: compileTimeState simStackState simStackPtr - 2. + self ssAllocateRequiredReg: Arg1Reg upThrough: compileTimeState simStackState simStackPtr - 1 ] + ifFalse: [ self ssAllocateRequiredReg: Arg0Reg upThrough: compileTimeState simStackState simStackPtr - 1 ] ]. - (self numRegArgs > 1 and: [ numArgs > 1 ]) ifTrue: [ (self simStackAt: simStackPtr) copyToReg: Arg1Reg ]. + (self numRegArgs > 1 and: [ numArgs > 1 ]) ifTrue: [ (compileTimeState simStackState simStackAt: compileTimeState simStackState simStackPtr) copyToReg: Arg1Reg ]. - numArgs > 0 ifTrue: [ (self simStackAt: simStackPtr - numArgs + 1) copyToReg: Arg0Reg ]. - (self simStackAt: simStackPtr - numArgs) copyToReg: ReceiverResultReg. + numArgs > 0 ifTrue: [ (compileTimeState simStackState simStackAt: compileTimeState simStackState simStackPtr - numArgs + 1) copyToReg: Arg0Reg ]. + (compileTimeState simStackState simStackAt: compileTimeState simStackState simStackPtr - numArgs) copyToReg: ReceiverResultReg. "Pop from the stack, so that subsequent compilation in this unit make as if they were popped. Here, DO discard the entries in the runtime stack. @@ -3601,27 +3497,25 @@ StackToRegisterMappingCogit >> mergeWithFixupIfRequired: fixup [ "case 2" fixup isNonMergeFixup ifTrue: - [deadCode := false. ^0]. + [compileTimeState deadCode: false. ^0]. "cases 3 and 4" self assert: fixup isMergeFixup. - deadCode + compileTimeState deadCode ifTrue: "case 3" ["Would like to assert fixup simStackPtr >= methodOrBlockNumTemps but can't because of the initialNils hack." - self assert: (fixup simStackPtr >= methodOrBlockNumTemps). - simStackPtr := fixup simStackPtr ] + self assert: (fixup simStackPtr >= compileTimeState methodOrBlockNumTemps). + compileTimeState simStackState simStackPtr: fixup simStackPtr ] ifFalse: "case 4" [self ssFlushStack]. "cases 3 and 4" - deadCode := false. + compileTimeState deadCode: false. fixup isBackwardBranchFixup ifTrue: - [fixup simStackPtr: simStackPtr ]. + [fixup simStackPtr: compileTimeState simStackState simStackPtr ]. fixup targetInstruction: self Label. - self assert: simStackPtr = fixup simStackPtr. - self cCode: '' inSmalltalk: - [self assert: fixup simStackPtr = (self debugStackPointerFor: bytecodePC)]. + self assert: compileTimeState simStackState simStackPtr = fixup simStackPtr. self restoreSimStackAtMergePoint: fixup. ^0 @@ -3644,10 +3538,17 @@ StackToRegisterMappingCogit >> methodFoundInvalidPostScan [ mostly in asserts, and yet they matter not at all for performance. Shun them." needsFrame ifFalse: - [^methodOrBlockNumTemps > methodOrBlockNumArgs]. + [^compileTimeState methodOrBlockNumTemps > methodOrBlockNumArgs]. ^super methodFoundInvalidPostScan ] +{ #category : 'accessing' } +StackToRegisterMappingCogit >> methodOrBlockNumTemps: anInteger [ + + + compileTimeState methodOrBlockNumTemps: anInteger +] + { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> needsFrameIfExtBGT2: stackDelta [ ^extB < 0 or: [extB > 2] @@ -3661,9 +3562,9 @@ StackToRegisterMappingCogit >> needsFrameIfFollowsSend: stackDelta [ following sends as in e.g. TextColor>>#dominates: other ^other class == self class. Only need to check for the frameless sends since all other sends will force a frame." - self assert: (prevBCDescriptor notNil and: [prevBCDescriptor needsFrameFunction notNil]). - ^prevBCDescriptor generator == #genSpecialSelectorEqualsEquals - or: [prevBCDescriptor generator == #genSpecialSelectorClass] + self assert: (compileTimeState prevBCDescriptor notNil and: [compileTimeState prevBCDescriptor needsFrameFunction notNil]). + ^compileTimeState prevBCDescriptor generator == #genSpecialSelectorEqualsEquals + or: [compileTimeState prevBCDescriptor generator == #genSpecialSelectorClass] ] { #category : 'compile abstract instructions' } @@ -3682,17 +3583,6 @@ StackToRegisterMappingCogit >> needsFrameIfStackGreaterThanOne: stackDelta [ ^stackDelta > 1 ] -{ #category : 'span functions' } -StackToRegisterMappingCogit >> numPushNils: descriptor pc: pc nExts: nExts method: aMethodObj [ - - - ^self perform: numPushNilsFunction - with: descriptor - with: pc - with: nExts - with: aMethodObj -] - { #category : 'compile abstract instructions' } StackToRegisterMappingCogit >> numRegArgs [ @@ -3701,9 +3591,9 @@ StackToRegisterMappingCogit >> numRegArgs [ { #category : 'simulation stack' } StackToRegisterMappingCogit >> numberOfSpillsInTopNItems: n [ - simStackPtr to: simStackPtr - n + 1 by: -1 do: - [:i| (self simStackAt: i) type = SSSpill ifTrue: - [^n - (simStackPtr - i)]]. + compileTimeState simStackState simStackPtr to: compileTimeState simStackState simStackPtr - n + 1 by: -1 do: + [:i| (compileTimeState simStackState simStackAt: i) type = SSSpill ifTrue: + [^n - (compileTimeState simStackState simStackPtr - i)]]. ^0 ] @@ -3815,56 +3705,6 @@ StackToRegisterMappingCogit >> printRegisterMask: registerMask on: aStream [ aStream nextPut: $}; flush ] -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> printSimStack [ - - self printSimStack: simStack toDepth: simStackPtr spillBase: simSpillBase on: coInterpreter transcript -] - -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> printSimStack: aSimStackOrFixup [ - - (aSimStackOrFixup isKindOf: CogRASSBytecodeFixup) - ifTrue: - [self printSimStack: aSimStackOrFixup mergeSimStack toDepth: aSimStackOrFixup simStackPtr spillBase: -1 on: coInterpreter transcript] - ifFalse: - [self printSimStack: aSimStackOrFixup toDepth: simStackPtr spillBase: simSpillBase on: coInterpreter transcript] -] - -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> printSimStack: aSimStack toDepth: limit spillBase: spillBase on: aStream [ - - - aStream newLine. - limit < 0 ifTrue: [ - ^ aStream - nextPutAll: 'simStackEmpty'; - cr; - flush ]. - aSimStack ifNil: [ - ^ aStream - nextPutAll: 'nil simStack'; - cr; - flush ]. - 0 to: limit do: [ :i | - aStream print: i. - i = simStackPtr ifTrue: [ aStream nextPutAll: '<-' ]. - i = spillBase ifTrue: [ aStream nextPutAll: '(sb)' ]. - aStream tab: (i = spillBase - ifTrue: [ 1 ] - ifFalse: [ 2 ]). - aStream - cr; - flush ]. - simSpillBase > limit ifTrue: [ - aStream - nextPutAll: '(sb: '; - print: simSpillBase; - nextPut: $); - cr; - flush ] -] - { #category : 'method introspection' } StackToRegisterMappingCogit >> profilingDataFor: descriptor Annotation: isBackwardBranchAndAnnotation Mcpc: mcpc Bcpc: bcpc Method: cogMethodArg [ @@ -4011,12 +3851,6 @@ StackToRegisterMappingCogit >> profilingDataForSendTo: cogCodeSendTarget methodC ^0 "to get Slang to type this method as answering sqInt" ] -{ #category : 'span functions' } -StackToRegisterMappingCogit >> pushNilSize: aMethodObj numInitialNils: numInitialNils [ - - ^self perform: pushNilSizeFunction with: aMethodObj with: numInitialNils -] - { #category : 'bytecode generator support' } StackToRegisterMappingCogit >> putSelfInReceiverResultReg [ @@ -4033,7 +3867,9 @@ StackToRegisterMappingCogit >> receiverIsInReceiverResultReg [ { #category : 'accessing' } StackToRegisterMappingCogit >> regArgsHaveBeenPushed: aBoolean [ - regArgsHaveBeenPushed := aBoolean + + + compileTimeState regArgsHaveBeenPushed: aBoolean ] { #category : 'simulation stack' } @@ -4042,14 +3878,14 @@ StackToRegisterMappingCogit >> restoreSimStackAtMergePoint: fixup [ "All the execution paths reaching a merge point expect everything to be spilled on stack. Throw away all simStack optimization state." self voidReceiverOptStatus. - methodOrBlockNumTemps + 1 to: simStackPtr do: + compileTimeState methodOrBlockNumTemps + 1 to: compileTimeState simStackState simStackPtr do: [:i| - (self simStackAt: i) + (compileTimeState simStackState simStackAt: i) type: SSSpill; offset: FoxMFReceiver - (i - methodOrBlockNumArgs * objectMemory bytesPerOop); registerr: FPReg; spilled: true]. - simSpillBase := simStackPtr + 1. + compileTimeState simStackState simSpillBase: compileTimeState simStackState simStackPtr + 1. ^ 0 ] @@ -4061,10 +3897,10 @@ StackToRegisterMappingCogit >> scanMethod [ - what are the targets of any backward branches" | latestContinuation nExts descriptor pc distance targetPC framelessStackDelta seenInstVarStore | - needsFrame := useTwoPaths := seenInstVarStore := false. + compileTimeState useTwoPaths: (needsFrame := seenInstVarStore := false). self maybeInitNumFixups. self maybeInitNumCounters. - prevBCDescriptor := nil. + compileTimeState prevBCDescriptor: nil. (primitiveIndex > 0 and: [coInterpreter isQuickPrimitiveIndex: primitiveIndex]) ifTrue: [^0]. @@ -4089,9 +3925,9 @@ StackToRegisterMappingCogit >> scanMethod [ ["With immutability we win simply by avoiding a frame build if the receiver is young and not immutable." self cppIf: IMMUTABILITY ifTrue: [descriptor is1ByteInstVarStore - ifTrue: [useTwoPaths := true] - ifFalse: [needsFrame := true. useTwoPaths := false]] - ifFalse: [needsFrame := true. useTwoPaths := false]] + ifTrue: [compileTimeState useTwoPaths: true] + ifFalse: [needsFrame := true. compileTimeState useTwoPaths: false]] + ifFalse: [needsFrame := true. compileTimeState useTwoPaths: false]] ifFalse: [framelessStackDelta := framelessStackDelta + descriptor stackDelta. "Without immutability we win if there are two or more stores and the receiver is new." @@ -4100,7 +3936,7 @@ StackToRegisterMappingCogit >> scanMethod [ ifFalse: [descriptor is1ByteInstVarStore ifTrue: [seenInstVarStore - ifTrue: [useTwoPaths := true] + ifTrue: [compileTimeState useTwoPaths: true] ifFalse: [seenInstVarStore := true]]]]]. descriptor isBranch ifTrue: @@ -4120,7 +3956,7 @@ StackToRegisterMappingCogit >> scanMethod [ pc := pc + descriptor numBytes. nExts := descriptor isExtension ifTrue: [nExts + 1] ifFalse: [extA := numExtB := extB := 0]. - prevBCDescriptor := descriptor]. + compileTimeState prevBCDescriptor: descriptor]. "ok" ^ 0 @@ -4131,18 +3967,22 @@ StackToRegisterMappingCogit >> 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." + + | simStack | super setInterpreter: aCoInterpreter. - methodAbortTrampolines := CArrayAccessor on: (Array new: self numRegArgs + 2). - picAbortTrampolines := CArrayAccessor on: (Array new: self numRegArgs + 2). - picMissTrampolines := CArrayAccessor on: (Array new: self numRegArgs + 2). + methodAbortTrampolines := CArrayAccessor on: + (Array new: self numRegArgs + 2). + picAbortTrampolines := CArrayAccessor on: + (Array new: self numRegArgs + 2). + picMissTrampolines := CArrayAccessor on: + (Array new: self numRegArgs + 2). + compileTimeState := CogStackToRegisterCompilationState new. + compileTimeState simStackStateField: CogCompileTimeStackState new. simStack := CArrayAccessor on: ((1 to: self class simStackSlots) collect: [:i| self simStackEntryClass new cogit: self]). - debugFixupBreaks := self class initializationOptions at: #debugFixupBreaks ifAbsent: [Set new]. - - numPushNilsFunction := self class numPushNilsFunction. - pushNilSizeFunction := self class pushNilSizeFunction + compileTimeState simStackState simStack: simStack ] { #category : 'simulation stack' } @@ -4156,16 +3996,8 @@ StackToRegisterMappingCogit >> simNativeStackSlots [ { #category : 'accessing' } StackToRegisterMappingCogit >> simSelf [ - - ^self simStackAt: 0 -] - -{ #category : 'simulation stack' } -StackToRegisterMappingCogit >> simStackAt: index [ - - - ^self addressOf: (simStack at: index) + ^compileTimeState simStackState simStackAt: 0 ] { #category : 'initialization' } @@ -4174,12 +4006,6 @@ StackToRegisterMappingCogit >> simStackEntryClass [ ^CogSimStackEntry ] -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> simStackPrintString [ - - ^String streamContents: [:s| self printSimStack: simStack toDepth: simStackPtr spillBase: simSpillBase on: s] -] - { #category : 'simulation stack' } StackToRegisterMappingCogit >> simStackSlots [ "Answer the number of slots to include in a simulated stack. @@ -4221,7 +4047,7 @@ StackToRegisterMappingCogit >> ssAllocateCallReg: requiredReg [ self ssAllocateRequiredRegMask: (CallerSavedRegisterMask bitOr: (self registerMaskFor: requiredReg)) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4233,7 +4059,7 @@ StackToRegisterMappingCogit >> ssAllocateCallReg: requiredReg1 and: requiredReg2 self ssAllocateRequiredRegMask: (CallerSavedRegisterMask bitOr: ((self registerMaskFor: requiredReg1) bitOr: (self registerMaskFor: requiredReg2))) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4244,7 +4070,7 @@ StackToRegisterMappingCogit >> ssAllocateCallReg: requiredReg1 and: requiredReg2 self ssAllocateRequiredRegMask: (CallerSavedRegisterMask bitOr: (self registerMaskFor: requiredReg1 and: requiredReg2 and: requiredReg3)) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4258,7 +4084,7 @@ StackToRegisterMappingCogit >> ssAllocateCallReg: requiredReg1 and: requiredReg2 bitOr: ((self registerMaskFor: requiredReg2) bitOr: ((self registerMaskFor: requiredReg3) bitOr: (self registerMaskFor: requiredReg4))))) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4287,7 +4113,7 @@ StackToRegisterMappingCogit >> ssAllocateCallReg: requiredReg upThrough: aStackP { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssAllocateRequiredFloatReg: requiredReg [ self ssAllocateRequiredFloatRegMask: (self registerMaskFor: requiredReg) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4299,10 +4125,10 @@ StackToRegisterMappingCogit >> ssAllocateRequiredFloatRegMask: requiredRegsMask If these are not free we must spill from simSpillBase to last occurrence. Note we are conservative here; we could allocate FPReg in frameless methods." liveRegs := NoReg. - (simSpillBase max: 0) to: stackPtr do: + (compileTimeState simStackState simSpillBase max: 0) to: stackPtr do: [:i| - liveRegs := liveRegs bitOr: (self simStackAt: i) registerMask. - ((self simStackAt: i) floatRegisterMask bitAnd: requiredRegsMask) ~= 0 ifTrue: + liveRegs := liveRegs bitOr: (compileTimeState simStackState simStackAt: i) registerMask. + ((compileTimeState simStackState simStackAt: i) floatRegisterMask bitAnd: requiredRegsMask) ~= 0 ifTrue: [lastRequired := i]]. "If any of requiredRegsMask are live we must spill." @@ -4316,7 +4142,7 @@ StackToRegisterMappingCogit >> ssAllocateRequiredFloatRegMask: requiredRegsMask StackToRegisterMappingCogit >> ssAllocateRequiredReg: requiredReg [ self ssAllocateRequiredRegMask: (self registerMaskFor: requiredReg) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4324,7 +4150,7 @@ StackToRegisterMappingCogit >> ssAllocateRequiredReg: requiredReg1 and: required self ssAllocateRequiredRegMask: ((self registerMaskFor: requiredReg1) bitOr: (self registerMaskFor: requiredReg2)) - upThrough: simStackPtr + upThrough: compileTimeState simStackState simStackPtr ] { #category : 'simulation stack' } @@ -4351,10 +4177,10 @@ StackToRegisterMappingCogit >> ssAllocateRequiredRegMask: requiredRegsMask upThr If these are not free we must spill from simSpillBase to last occurrence. Note we are conservative here; we could allocate FPReg in frameless methods." liveRegs := self registerMaskFor: FPReg and: SPReg. - (simSpillBase max: 0) to: stackPtr do: + (compileTimeState simStackState simSpillBase max: 0) to: stackPtr do: [:i| - liveRegs := liveRegs bitOr: (self simStackAt: i) registerMask. - ((self simStackAt: i) registerMask anyMask: requiredRegsMask) ifTrue: + liveRegs := liveRegs bitOr: (compileTimeState simStackState simStackAt: i) registerMask. + ((compileTimeState simStackState simStackAt: i) registerMask anyMask: requiredRegsMask) ifTrue: [lastRequired := i]]. "If any of requiredRegsMask are live we must spill." (liveRegs anyMask: requiredRegsMask) ifTrue: @@ -4362,30 +4188,30 @@ StackToRegisterMappingCogit >> ssAllocateRequiredRegMask: requiredRegsMask upThr self deny: (self liveRegisters anyMask: requiredRegsMask)] ] -{ #category : 'as yet unclassified' } +{ #category : 'simulation stack' } StackToRegisterMappingCogit >> ssFlushStack [ self ssFlushStackExceptTop: 0 ] -{ #category : 'as yet unclassified' } +{ #category : 'simulation stack' } StackToRegisterMappingCogit >> ssFlushStackExceptTop: n [ - self ssFlushTo: simStackPtr - n + self ssFlushTo: compileTimeState simStackState simStackPtr - n ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssFlushTo: index [ self assert: self tempsValidAndVolatileEntriesSpilled. - simSpillBase <= index ifTrue: - [(((simSpillBase max: methodOrBlockNumTemps + 1) min: simStackPtr) min: index) to: index do: + compileTimeState simStackState simSpillBase <= index ifTrue: + [(((compileTimeState simStackState simSpillBase max: compileTimeState methodOrBlockNumTemps + 1) min: compileTimeState simStackState simStackPtr) min: index) to: index do: [:i| self assert: needsFrame. - (self simStackAt: i) + (compileTimeState simStackState simStackAt: i) ensureSpilledAt: (self frameOffsetOfTemporary: i - 1) "frameOffsetOfTemporary: is 0-relative" from: FPReg]. - simSpillBase := index + 1] + compileTimeState simStackState simSpillBase: index + 1] ] { #category : 'simulation stack' } @@ -4393,10 +4219,10 @@ StackToRegisterMappingCogit >> ssFlushUpThrough: unaryBlock [ "Any occurrences on the stack of the value being stored (which is the top of stack) must be flushed, and hence any values colder than them stack." - self assert: simSpillBase >= 0. - simStackPtr - 1 to: simSpillBase by: -1 do: + self assert: compileTimeState simStackState simSpillBase >= 0. + compileTimeState simStackState simStackPtr - 1 to: compileTimeState simStackState simSpillBase by: -1 do: [ :index | - (unaryBlock value: (self simStackAt: index)) ifTrue: [ ^ self ssFlushTo: index ] ] + (unaryBlock value: (compileTimeState simStackState simStackAt: index)) ifTrue: [ ^ self ssFlushTo: index ] ] ] { #category : 'simulation stack' } @@ -4425,7 +4251,7 @@ StackToRegisterMappingCogit >> ssFlushUpThroughTemporaryVariable: tempIndex [ must be flushed, and hence any values colder than them stack." | offset | - offset := (self simStackAt: tempIndex + 1) offset. + offset := (compileTimeState simStackState simStackAt: tempIndex + 1) offset. self assert: offset = (self frameOffsetOfTemporary: tempIndex). self ssFlushUpThrough: [ :desc | @@ -4448,22 +4274,22 @@ StackToRegisterMappingCogit >> ssPop: popBoolean andCopyReg: reg [ popBoolean ifTrue: [ self ssPopTopToReg: reg ] - ifFalse: [ self ssTop copyToReg: reg ] + ifFalse: [ compileTimeState simStackState ssTop copyToReg: reg ] ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPop: n popSpilled: popSpilled [ | spilledToPop | - self assert: (simStackPtr - n >= methodOrBlockNumTemps - or: [(needsFrame not and: [simStackPtr - n >= 0])]). + self assert: (compileTimeState simStackState simStackPtr - n >= compileTimeState methodOrBlockNumTemps + or: [(needsFrame not and: [compileTimeState simStackState simStackPtr - n >= 0])]). "Pop from the simulated stack" - simStackPtr := simStackPtr - n. + compileTimeState simStackState simStackPtr: compileTimeState simStackState simStackPtr - n. "Check how many elements to pop from the stack have been spilled. If the spill base is above the stack, it means we popped spilled elements. - If the spill base is below or equals to the stack pointer, we don't need ot do anything" - spilledToPop := simSpillBase - 1 - simStackPtr. + If the spill base is below or equals to the stack pointer, we don't need ot do anything" + spilledToPop := compileTimeState simStackState simSpillBase - 1 - compileTimeState simStackState simStackPtr. (popSpilled and: [spilledToPop > 0]) ifTrue: [self AddCq: spilledToPop * objectMemory wordSize R: SPReg]. @@ -4475,9 +4301,9 @@ StackToRegisterMappingCogit >> ssPopTopToReg: aRegister [ "Peephole optimisation: generate always a single instruction. If the top is spilled, generate just a pop instruction. Otherwise a copy/load" - self ssTop spilled + compileTimeState simStackState ssTop spilled ifTrue: [ self PopR: aRegister ] - ifFalse: [ self ssTop copyToReg: aRegister ]. + ifFalse: [ compileTimeState simStackState ssTop copyToReg: aRegister ]. "No need to spill from the physical stack, we already did it" self ssPop: 1 popSpilled: false. ] @@ -4485,13 +4311,13 @@ StackToRegisterMappingCogit >> ssPopTopToReg: aRegister [ { #category : 'mapped inline primitive generators - vectorial' } StackToRegisterMappingCogit >> ssPopTopToVectorReg: aVectorRegister [ - self ssTop moveToVectorReg: aVectorRegister. + compileTimeState simStackState ssTop moveToVectorReg: aVectorRegister. self ssPop: 1 ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPush: n [ - simStackPtr := simStackPtr + n + compileTimeState simStackState simStackPtr: compileTimeState simStackState simStackPtr + n ] { #category : 'simulation stack' } @@ -4504,7 +4330,7 @@ StackToRegisterMappingCogit >> ssPushAnnotatedConstant: literal [ { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPushBase: reg offset: offset [ self ssPush: 1. - self ssTop + compileTimeState simStackState ssTop type: SSBaseOffset; spilled: false; registerr: reg; @@ -4517,7 +4343,7 @@ StackToRegisterMappingCogit >> ssPushBase: reg offset: offset [ { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPushConstant: literal [ self ssPush: 1. - self ssTop + compileTimeState simStackState ssTop type: SSConstant; spilled: false; constant: literal; @@ -4528,32 +4354,37 @@ StackToRegisterMappingCogit >> ssPushConstant: literal [ { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPushDesc: simStackEntry [ + - self cCode: - [simStackEntry type = SSSpill ifTrue: - [simStackEntry type: SSBaseOffset]. + self + cCode: [ + simStackEntry type = SSSpill ifTrue: [ + simStackEntry type: SSBaseOffset ]. simStackEntry spilled: false; bcptr: bytecodePC. - simStack - at: (simStackPtr := simStackPtr + 1) - put: simStackEntry] - inSmalltalk: - [(simStack at: (simStackPtr := simStackPtr + 1)) + compileTimeState simStackState + simStackAt: (compileTimeState simStackState simStackPtr: + compileTimeState simStackState simStackPtr + 1) + put: simStackEntry ] + inSmalltalk: [ + (compileTimeState simStackState simStackAt: + (compileTimeState simStackState simStackPtr: + compileTimeState simStackState simStackPtr + 1)) copyFrom: simStackEntry; type: (simStackEntry type = SSSpill - ifTrue: [SSBaseOffset] - ifFalse: [simStackEntry type]); + ifTrue: [ SSBaseOffset ] + ifFalse: [ simStackEntry type ]); spilled: false; - bcptr: bytecodePC]. + bcptr: bytecodePC ]. self updateSimSpillBase. - ^0 + ^ 0 ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPushRegister: reg [ self ssPush: 1. - self ssTop + compileTimeState simStackState ssTop type: SSRegister; spilled: false; registerr: reg; @@ -4565,12 +4396,12 @@ StackToRegisterMappingCogit >> ssPushRegister: reg [ { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssPushVectorRegister: reg [ self ssPush: 1. - self ssTop + compileTimeState simStackState ssTop type: SSVectorRegister; spilled: false; registerr: reg; bcptr: bytecodePC. - self ssTop. + compileTimeState simStackState ssTop. self updateSimSpillBase. ^0 ] @@ -4579,13 +4410,13 @@ StackToRegisterMappingCogit >> ssPushVectorRegister: reg [ StackToRegisterMappingCogit >> ssSelfDescriptor [ - ^simStack at: 0 + ^compileTimeState simStackState simStackDescriptorAt: 0 ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssSize [ - ^ simStackPtr + 1 + ^ compileTimeState simStackState simStackPtr + 1 ] { #category : 'simulation stack' } @@ -4594,7 +4425,7 @@ StackToRegisterMappingCogit >> ssStoreAndReplacePop: popBoolean toReg: reg [ a popInto I change the simulated stack to use the register for the top value" | topSpilled | - topSpilled := self ssTop spilled. + topSpilled := compileTimeState simStackState ssTop spilled. self ssPop: (popBoolean or: [topSpilled]) andCopyReg: reg. popBoolean ifFalse: [ topSpilled ifFalse: [self ssPop: 1 popSpilled: false ]. @@ -4608,38 +4439,25 @@ StackToRegisterMappingCogit >> ssStorePop: popBoolean toPreferredReg: preferredR Answer the actual register the result ends up in." | actualReg | actualReg := preferredReg. - self ssTop type = SSRegister ifTrue: - [self assert: self ssTop spilled not. - actualReg := self ssTop registerr]. + compileTimeState simStackState ssTop type = SSRegister ifTrue: + [self assert: compileTimeState simStackState ssTop spilled not. + actualReg := compileTimeState simStackState ssTop registerr]. self ssPop: popBoolean andCopyReg: actualReg. "generates nothing if ssTop is already in actualReg" ^ actualReg ] -{ #category : 'simulation stack' } -StackToRegisterMappingCogit >> ssTop [ - - ^self simStackAt: simStackPtr -] - -{ #category : 'simulation stack' } -StackToRegisterMappingCogit >> ssTopDescriptor [ - - - ^simStack at: simStackPtr -] - { #category : 'testing' } StackToRegisterMappingCogit >> ssTopNeedsStoreCheck [ - ^self ssTop type ~= SSConstant - or: [(objectMemory isNonImmediate: self ssTop constant) - and: [objectRepresentation shouldAnnotateObjectReference: self ssTop constant]] + ^compileTimeState simStackState ssTop type ~= SSConstant + or: [(objectMemory isNonImmediate: compileTimeState simStackState ssTop constant) + and: [objectRepresentation shouldAnnotateObjectReference: compileTimeState simStackState ssTop constant]] ] { #category : 'simulation stack' } StackToRegisterMappingCogit >> ssValue: n [ - ^self simStackAt: simStackPtr - n + ^compileTimeState simStackState simStackAt: compileTimeState simStackState simStackPtr - n ] { #category : 'testing' } @@ -4654,42 +4472,26 @@ StackToRegisterMappingCogit >> stackEntryIsBoolean: simStackEntry [ { #category : 'testing' } StackToRegisterMappingCogit >> stackTopIsBoolean [ - ^simStackPtr >= methodOrBlockNumArgs and: [self stackEntryIsBoolean: self ssTop] + ^compileTimeState simStackState simStackPtr >= methodOrBlockNumArgs and: [self stackEntryIsBoolean: compileTimeState simStackState ssTop] ] { #category : 'debugging' } StackToRegisterMappingCogit >> tempsValidAndVolatileEntriesSpilled [ "Answer if the stack is valid up to, but not including, simSpillBase." | culprit | - 1 to: methodOrBlockNumTemps do: + 1 to: compileTimeState methodOrBlockNumTemps do: [:i| - ((self simStackAt: i) type = SSBaseOffset) ifFalse: + ((compileTimeState simStackState simStackAt: i) type = SSBaseOffset) ifFalse: [culprit ifNil: [culprit := i]. ^false]]. - methodOrBlockNumTemps + 1 to: simSpillBase - 1 do: + compileTimeState methodOrBlockNumTemps + 1 to: compileTimeState simStackState simSpillBase - 1 do: [:i| - (self simStackAt: i) spilled ifFalse: + (compileTimeState simStackState simStackAt: i) spilled ifFalse: [culprit ifNil: [culprit := i]. ^false]]. ^true ] -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> traceDescriptor: descriptor [ - - (compilationTrace anyMask: 2) ifTrue: - [coInterpreter transcript cr; print: bytecodePC; space; nextPutAll: descriptor generator. - deadCode ifTrue: [coInterpreter transcript nextPutAll: ' => deadCode']. - coInterpreter flush] -] - -{ #category : 'simulation only' } -StackToRegisterMappingCogit >> traceSpill: simStackEntry [ - - (compilationTrace anyMask: 8) ifTrue: - [coInterpreter transcript cr; print: bytecodePC; space; print: simStackEntry; flush] -] - { #category : 'peephole optimizations' } StackToRegisterMappingCogit >> tryCollapseTempVectorInitializationOfSize: slots [ "If the sequence of bytecodes is @@ -4767,36 +4569,29 @@ StackToRegisterMappingCogit >> tryCollapseTempVectorInitializationOfSize: slots StackToRegisterMappingCogit >> updateSimSpillBase [ "Something volatile has been pushed on the stack; update simSpillBase accordingly." - self assert: ((simSpillBase > methodOrBlockNumTemps - and: [simStackPtr >= methodOrBlockNumTemps])). - simSpillBase > simStackPtr + self assert: ((compileTimeState simStackState simSpillBase > compileTimeState methodOrBlockNumTemps + and: [compileTimeState simStackState simStackPtr >= compileTimeState methodOrBlockNumTemps])). + compileTimeState simStackState simSpillBase > compileTimeState simStackState simStackPtr ifTrue: - [simSpillBase := simStackPtr + 1. - [simSpillBase - 1 > methodOrBlockNumTemps - and: [(self simStackAt: simSpillBase - 1) spilled not]] whileTrue: - [simSpillBase := simSpillBase - 1]] + [compileTimeState simStackState simSpillBase: compileTimeState simStackState simStackPtr + 1. + [compileTimeState simStackState simSpillBase - 1 > compileTimeState methodOrBlockNumTemps + and: [(compileTimeState simStackState simStackAt: compileTimeState simStackState simSpillBase - 1) spilled not]] whileTrue: + [compileTimeState simStackState simSpillBase: compileTimeState simStackState simSpillBase - 1]] ifFalse: - [[(self simStackAt: simSpillBase) spilled - and: [simSpillBase <= simStackPtr]] whileTrue: - [simSpillBase := simSpillBase + 1]]. - methodOrBlockNumTemps + 1 to: (simSpillBase - 1 min: simStackPtr) do: + [[(compileTimeState simStackState simStackAt: compileTimeState simStackState simSpillBase) spilled + and: [compileTimeState simStackState simSpillBase <= compileTimeState simStackState simStackPtr]] whileTrue: + [compileTimeState simStackState simSpillBase: compileTimeState simStackState simSpillBase + 1]]. + compileTimeState methodOrBlockNumTemps + 1 to: (compileTimeState simStackState simSpillBase - 1 min: compileTimeState simStackState simStackPtr) do: [:i| - self assert: (self simStackAt: i) spilled == true]. - self assert: (simSpillBase > simStackPtr or: [(self simStackAt: simSpillBase) spilled == false]) + self assert: (compileTimeState simStackState simStackAt: i) spilled == true]. + self assert: (compileTimeState simStackState simSpillBase > compileTimeState simStackState simStackPtr or: [(compileTimeState simStackState simStackAt: compileTimeState simStackState simSpillBase) spilled == false]) ] { #category : 'accessing' } StackToRegisterMappingCogit >> useTwoPaths: aBoolean [ - - useTwoPaths := aBoolean -] -{ #category : 'span functions' } -StackToRegisterMappingCogit >> v4PushNilSize: aMethodObj numInitialNils: numInitialNils [ - "77 01001101 Push false [* 1:true, 2:nil, 3:thisContext, ..., -N: pushExplicitOuter: N, N = Extend B] - 225 11100001 sbbbbbbb Extend B (Ext B = Ext B prev * 256 + Ext B)" - - ^3 * numInitialNils + + compileTimeState useTwoPaths: aBoolean ] { #category : 'testing' } @@ -4819,9 +4614,9 @@ StackToRegisterMappingCogit >> voidReceiverResultRegContainsSelf [ | spillIndex | self voidReceiverOptStatus. spillIndex := 0. - (methodOrBlockNumTemps + 1 max: simSpillBase) to: simStackPtr do: + (compileTimeState methodOrBlockNumTemps + 1 max: compileTimeState simStackState simSpillBase) to: compileTimeState simStackState simStackPtr do: [:i| - (self simStackAt: i) registerOrNone = ReceiverResultReg ifTrue: + (compileTimeState simStackState simStackAt: i) registerOrNone = ReceiverResultReg ifTrue: [spillIndex := i]]. spillIndex > 0 ifTrue: [self ssFlushTo: spillIndex] diff --git a/smalltalksrc/VMMaker/VMBytecodeConstants.class.st b/smalltalksrc/VMMaker/VMBytecodeConstants.class.st index 4af2f7779b0..36329d152ae 100644 --- a/smalltalksrc/VMMaker/VMBytecodeConstants.class.st +++ b/smalltalksrc/VMMaker/VMBytecodeConstants.class.st @@ -8,7 +8,6 @@ Class { #name : 'VMBytecodeConstants', #superclass : 'SharedPool', #classVars : [ - 'BytecodeSetHasDirectedSuperSend', 'CtxtTempFrameStart', 'LargeContextBit', 'LargeContextSlots', @@ -21,15 +20,3 @@ Class { #package : 'VMMaker', #tag : 'Interpreter' } - -{ #category : 'simulator initialization' } -VMBytecodeConstants class >> falsifyBytecodeSetFlags: initializationOptions [ - - classPool keys do: - [:k| - (k endsWith: 'BytecodeSet') ifTrue: - [classPool at: k put: false. - initializationOptions at: k put: false]] - - "classPool keys select: [:k| k endsWith: 'BytecodeSet']" -] diff --git a/smalltalksrc/VMMakerTests/StackToRegisterMappingCogit.extension.st b/smalltalksrc/VMMakerTests/StackToRegisterMappingCogit.extension.st deleted file mode 100644 index f2768e954fa..00000000000 --- a/smalltalksrc/VMMakerTests/StackToRegisterMappingCogit.extension.st +++ /dev/null @@ -1,7 +0,0 @@ -Extension { #name : 'StackToRegisterMappingCogit' } - -{ #category : '*VMMakerTests' } -StackToRegisterMappingCogit >> methodOrBlockNumTemps: anInteger [ - - methodOrBlockNumTemps := anInteger -] diff --git a/smalltalksrc/VMMakerTests/UnicornProcessor.class.st b/smalltalksrc/VMMakerTests/UnicornProcessor.class.st index a6d46573c2f..8cf7380699d 100644 --- a/smalltalksrc/VMMakerTests/UnicornProcessor.class.st +++ b/smalltalksrc/VMMakerTests/UnicornProcessor.class.st @@ -321,7 +321,7 @@ UnicornProcessor >> rsp: anInteger [ ] { #category : 'as yet unclassified' } -UnicornProcessor >> runInMemory: aMemory minimumAddress: minimumAddress readOnlyBelow: minimumWritableAddress [ +UnicornProcessor >> run [ ^ machineSimulator startAt: machineSimulator instructionPointerRegisterValue diff --git a/smalltalksrc/VMMakerTests/VMJitSimdBytecode.class.st b/smalltalksrc/VMMakerTests/VMJitSimdBytecode.class.st index 871859c6b2f..8a0a50c3271 100644 --- a/smalltalksrc/VMMakerTests/VMJitSimdBytecode.class.st +++ b/smalltalksrc/VMMakerTests/VMJitSimdBytecode.class.st @@ -125,7 +125,7 @@ VMJitSimdBytecode >> testAddVectorPushesArraySumIntoSimulatedStack [ self runFrom: primitiveAddress until: endInstruction address. - entry := cogit ssTop. + entry := cogit compileTimeState simStackStateField ssTop. "The register with the result is the same as the first one" self assert: (entry type) equals: SSVectorRegister. self assert: (entry registerr) equals: 0. @@ -187,7 +187,7 @@ VMJitSimdBytecode >> testPushArrayToRegisterPushesArrayChunkIntoSimulatedStack [ self runFrom: primitiveAddress until: endInstruction address. - entry := cogit ssTop. + entry := cogit compileTimeState simStackStateField ssTop. self assert: (entry type) equals: SSVectorRegister. self assert: (entry registerr) equals: 0. diff --git a/smalltalksrc/VMMakerTests/VMPrimitiveCallAbstractTest.class.st b/smalltalksrc/VMMakerTests/VMPrimitiveCallAbstractTest.class.st index 7ca880da0b6..51216f1e458 100644 --- a/smalltalksrc/VMMakerTests/VMPrimitiveCallAbstractTest.class.st +++ b/smalltalksrc/VMMakerTests/VMPrimitiveCallAbstractTest.class.st @@ -171,12 +171,7 @@ VMPrimitiveCallAbstractTest >> setUp [ 1 to: interpreter primitiveTable size do: [ :i | primitiveAccessorDepthTable at: i put: -1 ]. - interpreter primitiveAccessorDepthTable: primitiveAccessorDepthTable. - - cogit lastNInstructions: OrderedCollection new. - - cogit guardPageSize: cogit class guardPageSize. - + interpreter primitiveAccessorDepthTable: primitiveAccessorDepthTable ] { #category : 'running' } diff --git a/smalltalksrc/VMMakerTests/VMStackToRegisterMappingTest.class.st b/smalltalksrc/VMMakerTests/VMStackToRegisterMappingTest.class.st index f67ef4a7558..0cc6d1c6ab4 100644 --- a/smalltalksrc/VMMakerTests/VMStackToRegisterMappingTest.class.st +++ b/smalltalksrc/VMMakerTests/VMStackToRegisterMappingTest.class.st @@ -66,7 +66,7 @@ VMStackToRegisterMappingTest >> testPopConstant [ cogit ssPop: 1. self assert: cogit ssSize equals: 1. - self assert: cogit ssTop equals: cogit simSelf. + self assert: cogit compileTimeState simStackStateField ssTop equals: cogit simSelf. ] { #category : 'tests' } @@ -103,7 +103,7 @@ VMStackToRegisterMappingTest >> testPopRegister [ cogit ssPop: 1. self assert: cogit ssSize equals: 1. - self assert: cogit ssTop equals: cogit simSelf + self assert: cogit compileTimeState simStackStateField ssTop equals: cogit simSelf ] { #category : 'tests' } @@ -192,9 +192,9 @@ VMStackToRegisterMappingTest >> testPushConstant [ cogit ssPushConstant: 1. self assert: cogit ssSize equals: 2. - self assert: cogit ssTop type equals: SSConstant. - self assert: cogit ssTop constant equals: 1. - self deny: cogit ssTop spilled + self assert: cogit compileTimeState simStackStateField ssTop type equals: SSConstant. + self assert: cogit compileTimeState simStackStateField ssTop constant equals: 1. + self deny: cogit compileTimeState simStackStateField ssTop spilled ] { #category : 'tests' } @@ -203,9 +203,9 @@ VMStackToRegisterMappingTest >> testPushRegister [ cogit ssPushRegister: TempReg. self assert: cogit ssSize equals: 2. - self assert: cogit ssTop type equals: SSRegister. - self assert: cogit ssTop registerr equals: TempReg. - self deny: cogit ssTop spilled + self assert: cogit compileTimeState simStackStateField ssTop type equals: SSRegister. + self assert: cogit compileTimeState simStackStateField ssTop registerr equals: TempReg. + self deny: cogit compileTimeState simStackStateField ssTop spilled ] { #category : 'tests' } @@ -218,11 +218,11 @@ VMStackToRegisterMappingTest >> testSpillConstant [ self assert: cogit ssSize equals: 2. "The element should be the same as before" - self assert: cogit ssTop type equals: SSConstant. - self assert: cogit ssTop constant equals: 1. + self assert: cogit compileTimeState simStackStateField ssTop type equals: SSConstant. + self assert: cogit compileTimeState simStackStateField ssTop constant equals: 1. "But not it is spilled" - self assert: cogit ssTop spilled + self assert: cogit compileTimeState simStackStateField ssTop spilled ] { #category : 'tests' } @@ -236,17 +236,17 @@ VMStackToRegisterMappingTest >> testSpillRegister [ "The element should now be in a spilled position in the stack. I.e., Relative to FPReg, with offset 4 (base 0) in the frame (the first three are saved FP, method, context, receiver)" - self assert: cogit ssTop type equals: SSSpill. - self assert: cogit ssTop base equals: FPReg. - self assert: cogit ssTop offset equals: -4 * memory wordSize. + self assert: cogit compileTimeState simStackStateField ssTop type equals: SSSpill. + self assert: cogit compileTimeState simStackStateField ssTop base equals: FPReg. + self assert: cogit compileTimeState simStackStateField ssTop offset equals: -4 * memory wordSize. "But it is spilled" - self assert: cogit ssTop spilled + self assert: cogit compileTimeState simStackStateField ssTop spilled ] { #category : 'tests' } VMStackToRegisterMappingTest >> testTopOfEmptyIsSimSelf [ self assert: cogit ssSize equals: 1. - self assert: cogit ssTop equals: cogit simSelf + self assert: cogit compileTimeState simStackStateField ssTop equals: cogit simSelf ]