VM Maker: VMMaker.oscog-eem.2621.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-eem.2621.mcz

commits-2
 
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!