Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2621.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.2621 Author: eem Time: 18 December 2019, 7:33:27.184028 pm UUID: 0ccf8a55-3118-4810-8098-c1ded0a6aad8 Ancestors: VMMaker.oscog-eem.2620 Simulation: Provide context when fake addresses are not found in the mapping dictionaries but printRegisters and/or printInstructions is not in effect. Improve generation breaqkpointing to break if the address is anywhere within the instruction, not just at the start of it. =============== Diff against VMMaker.oscog-eem.2620 =============== Item was added: + ----- Method: Cogit>>errorProcessingSimulationTrap:in: (in category 'simulation processor access') ----- + errorProcessingSimulationTrap: aProcessorSimulationTrap in: aDictionary + printRegisters ifFalse: + [processor printRegistersOn: coInterpreter transcript]. + printInstructions ifFalse: + [self disassembleFrom: processor pc to: processor pc]. + ^aDictionary errorKeyNotFound: aProcessorSimulationTrap address! Item was changed: ----- Method: Cogit>>generateInstructionsAt: (in category 'generate machine code') ----- generateInstructionsAt: eventualAbsoluteAddress "Size pc-dependent instructions and assign eventual addresses to all instructions. Answer the size of the code. Compute forward branches based on virtual address (abstract code starts at 0), assuming that any branches branched over are long. Compute backward branches based on actual address. Reuse the fixups array to record the pc-dependent instructions that need to have their code generation postponed until after the others." | absoluteAddress pcDependentIndex abstractInstruction fixup | <var: #abstractInstruction type: #'AbstractInstruction *'> <var: #fixup type: #'BytecodeFixup *'> absoluteAddress := eventualAbsoluteAddress. pcDependentIndex := 0. 0 to: opcodeIndex - 1 do: [:i| - self maybeBreakGeneratingAt: absoluteAddress. abstractInstruction := self abstractInstructionAt: i. + self maybeBreakGeneratingFrom: absoluteAddress to: absoluteAddress + abstractInstruction maxSize - 1. abstractInstruction isPCDependent ifTrue: [abstractInstruction sizePCDependentInstructionAt: absoluteAddress. fixup := self fixupAtIndex: pcDependentIndex. pcDependentIndex := pcDependentIndex + 1. fixup instructionIndex: i. absoluteAddress := absoluteAddress + abstractInstruction machineCodeSize] ifFalse: [absoluteAddress := abstractInstruction concretizeAt: absoluteAddress]]. 0 to: pcDependentIndex - 1 do: [:j| fixup := self fixupAtIndex: j. abstractInstruction := self abstractInstructionAt: fixup instructionIndex. + self maybeBreakGeneratingFrom: abstractInstruction address to: abstractInstruction address + abstractInstruction maxSize - 1. - self maybeBreakGeneratingAt: abstractInstruction address. abstractInstruction concretizeAt: abstractInstruction address]. ^absoluteAddress - eventualAbsoluteAddress! Item was changed: ----- Method: Cogit>>handleCallOrJumpSimulationTrap: (in category 'simulation only') ----- handleCallOrJumpSimulationTrap: aProcessorSimulationTrap <doNotGenerate> | evaluable function memory result savedFramePointer savedStackPointer savedArgumentCount rpc | + evaluable := simulatedTrampolines + at: aProcessorSimulationTrap address + ifAbsent: [self errorProcessingSimulationTrap: aProcessorSimulationTrap + in: simulatedTrampolines]. - evaluable := simulatedTrampolines at: aProcessorSimulationTrap address. 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]. aProcessorSimulationTrap type == #call ifTrue: [processor simulateCallOf: aProcessorSimulationTrap address nextpc: aProcessorSimulationTrap nextpc memory: (memory := coInterpreter memory). self recordInstruction: {'(simulated call of '. aProcessorSimulationTrap address. '/'. function. ')'}] ifFalse: [processor simulateJumpCallOf: aProcessorSimulationTrap address memory: (memory := coInterpreter memory). self recordInstruction: {'(simulated jump to '. aProcessorSimulationTrap address. '/'. function. ')'}]. 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: memory)] 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: [(#( primitiveClosureValue primitiveClosureValueWithArgs primitiveClosureValueNoContextSwitch 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]]) "coInterpreter cr. processor sp + 32 to: processor sp - 32 by: -4 do: [:sp| sp = processor sp ifTrue: [coInterpreter print: 'sp->'; tab] ifFalse: [coInterpreter printHex: sp]. coInterpreter tab; printHex: (coInterpreter longAt: sp); cr]"! Item was changed: ----- Method: Cogit>>handleReadSimulationTrap: (in category 'simulation only') ----- handleReadSimulationTrap: aProcessorSimulationTrap <doNotGenerate> | variableValue accessor | + variableValue := (simulatedVariableGetters + at: aProcessorSimulationTrap address + ifAbsent: [self errorProcessingSimulationTrap: aProcessorSimulationTrap + in: simulatedVariableGetters]) + value asInteger. - variableValue := (simulatedVariableGetters at: aProcessorSimulationTrap address) value asInteger. accessor := aProcessorSimulationTrap registerAccessor. processor perform: accessor with: variableValue signedIntToLong. accessor ~~ #pc: ifTrue: [processor pc: aProcessorSimulationTrap nextpc]! Item was changed: ----- Method: Cogit>>handleWriteSimulationTrap: (in category 'simulation only') ----- handleWriteSimulationTrap: aProcessorSimulationTrap <doNotGenerate> | variableValue | (self addressIsInCodeZone: aProcessorSimulationTrap address) ifTrue: [self error: 'attempt to write to code space']. variableValue := processor perform: aProcessorSimulationTrap registerAccessor. + (simulatedVariableSetters + at: aProcessorSimulationTrap address + ifAbsent: [self errorProcessingSimulationTrap: aProcessorSimulationTrap + in: simulatedVariableSetters]) + value: variableValue. - (simulatedVariableSetters at: aProcessorSimulationTrap address) value: variableValue. processor pc: aProcessorSimulationTrap nextpc! Item was removed: - ----- Method: Cogit>>maybeBreakGeneratingAt: (in category 'simulation only') ----- - maybeBreakGeneratingAt: address - "Variation on maybeBreakAt: that only works for integer breakPCs, - so we can have break blocks that stop at any pc, except when generating." - <cmacro: '(address) 0'> "Simulation only; void in C" - (breakPC = address - and: [breakBlock shouldStopIfAtPC: address]) ifTrue: - [coInterpreter changed: #byteCountText. - self halt: 'machine code generation at ', address hex, ' in ', thisContext sender selector]! Item was added: + ----- Method: Cogit>>maybeBreakGeneratingFrom:to: (in category 'simulation only') ----- + maybeBreakGeneratingFrom: address to: end + "Variation on maybeBreakAt: that only works for integer breakPCs, + so we can have break blocks that stop at any pc, except when generating." + <cmacro: '(address) 0'> "Simulation only; void in C" + (breakPC isInteger + and: [(breakPC between: address and: end) + and: [breakBlock shouldStopIfAtPC: address]]) ifTrue: + [coInterpreter changed: #byteCountText. + self halt: 'machine code generation at ', address hex, ' in ', thisContext sender selector]! Item was changed: ----- Method: StackToRegisterMappingCogit>>generateInstructionsAt: (in category 'generate machine code') ----- generateInstructionsAt: eventualAbsoluteAddress "Size pc-dependent instructions and assign eventual addresses to all instructions. Answer the size of the code. Compute forward branches based on virtual address (abstract code starts at 0), assuming that any branches branched over are long. Compute backward branches based on actual address. Reuse the fixups array to record the pc-dependent instructions that need to have their code generation postponed until after the others. Override to andd handling for null branches (branches to the immediately following instruction) occasioned by StackToRegisterMapping's following of jumps." | absoluteAddress pcDependentIndex abstractInstruction fixup | <var: #abstractInstruction type: #'AbstractInstruction *'> <var: #fixup type: #'BytecodeFixup *'> absoluteAddress := eventualAbsoluteAddress. pcDependentIndex := 0. 0 to: opcodeIndex - 1 do: [:i| abstractInstruction := self abstractInstructionAt: i. + self maybeBreakGeneratingFrom: absoluteAddress to: absoluteAddress + abstractInstruction maxSize - 1. - self maybeBreakGeneratingAt: absoluteAddress. abstractInstruction isPCDependent ifTrue: [abstractInstruction sizePCDependentInstructionAt: absoluteAddress. (abstractInstruction isJump and: [(i + 1 < opcodeIndex and: [abstractInstruction getJmpTarget == (self abstractInstructionAt: i + 1)]) or: [i + 2 < opcodeIndex and: [abstractInstruction getJmpTarget == (self abstractInstructionAt: i + 2) and: [(self abstractInstructionAt: i + 1) opcode = Nop]]]]) ifTrue: [abstractInstruction opcode: Nop; concretizeAt: absoluteAddress] ifFalse: [fixup := self fixupAtIndex: pcDependentIndex. pcDependentIndex := pcDependentIndex + 1. fixup instructionIndex: i]. absoluteAddress := absoluteAddress + abstractInstruction machineCodeSize] ifFalse: [absoluteAddress := abstractInstruction concretizeAt: absoluteAddress. self assert: abstractInstruction machineCodeSize = abstractInstruction maxSize]]. 0 to: pcDependentIndex - 1 do: [:j| fixup := self fixupAtIndex: j. abstractInstruction := self abstractInstructionAt: fixup instructionIndex. + self maybeBreakGeneratingFrom: abstractInstruction address to: abstractInstruction address + abstractInstruction maxSize - 1. - self maybeBreakGeneratingAt: abstractInstruction address. abstractInstruction concretizeAt: abstractInstruction address]. ^absoluteAddress - eventualAbsoluteAddress! |
Free forum by Nabble | Edit this page |