VM Maker: VMMaker.oscog-eem.2036.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.2036.mcz

commits-2
 
Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-eem.2036.mcz

==================== Summary ====================

Name: VMMaker.oscog-eem.2036
Author: eem
Time: 12 December 2016, 11:31:09.926368 am
UUID: f3615bfa-2eb4-49c1-9b34-0a8d37c5886b
Ancestors: VMMaker.oscog-cb.2035

SistaCogit:
Fix counter generation for 64-bits.  Remopve a #== that should be an #=.

Sista & RegisterAllocatingCogit:
Add SistaCogitClone & SistaRegisterAllocatingCogit to allow putting Sista under the RegisterAllocatingCogit.  Have SistaRegisterAllocatingCogit maintain code in SistaCogitClone.

General:
Nuke an obsolete maintennance script.

=============== Diff against VMMaker.oscog-cb.2035 ===============

Item was added:
+ ----- Method: ClassDescription>>>>> (in category '*VMMaker-accessing') -----
+ >>> aSelector
+ "Convenience for creating MethodReferences"
+ ^MethodReference class: self selector: aSelector!

Item was changed:
  ----- Method: SistaCogit>>disassembleMethod:on: (in category 'disassembly') -----
  disassembleMethod: surrogateOrAddress on: aStream
  <doNotGenerate>
  | cogMethod |
  cogMethod := super disassembleMethod: surrogateOrAddress on: aStream.
  (cogMethod cmType = CMMethod
  and: [cogMethod counters ~= 0]) ifTrue:
  [aStream nextPutAll: 'counters:'; cr.
  numCounters := objectRepresentation numCountersFor: counters.
  0 to: numCounters - 1 do:
  [:i| | addr |
  addr := i * CounterBytes + counters.
  addr printOn: aStream base: 16.
  aStream nextPut: $:; space.
+ (objectMemory long32At: addr) printOn: aStream base: 16.
- (objectMemory longAt: addr) printOn: aStream base: 16.
  aStream cr].
  aStream flush]!

Item was changed:
  ----- Method: SistaCogit>>genExecutionCountLogicInto:counterReg: (in category 'bytecode generator support') -----
  genExecutionCountLogicInto: binaryBlock counterReg: counterReg
  <var: #countTripped type: #'AbstractInstruction *'>
  <inline: true>
  | counterAddress countTripped |
+ counterAddress := counters + (CounterBytes * counterIndex).
- counterAddress := counters + ((self sizeof: #sqInt) * counterIndex).
- self assert: objectMemory wordSize = CounterBytes.
  self MoveA32: counterAddress R: counterReg.
  self SubCq: 16r10000 R: counterReg. "Count executed"
  "If counter trips simply abort the comparison continuing to the following
  branch *without* writing back.  A double decrement will not trip the second time."
  countTripped := self JumpCarry: 0.
  self MoveR: counterReg A32: counterAddress. "write back"
  binaryBlock value: counterAddress value: countTripped!

Item was changed:
  ----- Method: SistaCogit>>genJumpIf:to: (in category 'bytecode generator support') -----
  genJumpIf: boolean to: targetBytecodePC
  "The heart of performance counting in Sista.  Conditional branches are 6 times less
  frequent than sends and can provide basic block frequencies (send counters can't).
  Each conditional has a 32-bit counter split into an upper 16 bits counting executions
  and a lower half counting untaken executions of the branch.  Executing the branch
  decrements the upper half, tripping if the count goes negative.  Not taking the branch
  decrements the lower half.  N.B. We *do not* eliminate dead branches (true ifTrue:/true ifFalse:)
  so that scanning for send and branch data is simplified and that branch data is correct."
  <inline: false>
  | ok counterAddress countTripped retry nextPC nextDescriptor desc |
  <var: #ok type: #'AbstractInstruction *'>
  <var: #desc type: #'CogSimStackEntry *'>
  <var: #retry type: #'AbstractInstruction *'>
  <var: #countTripped type: #'AbstractInstruction *'>
  <var: #nextDescriptor type: #'BytecodeDescriptor *'>
 
  "In optimized code we don't generate counters to improve performance"
  (coInterpreter isOptimizedMethod: methodObj) ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ].
 
  "If the branch is reached only for the counter trip trampoline
  (typically, var1 == var2 ifTrue: falls through to the branch only for the trampoline)
  we generate a specific path to drastically reduce the number of machine instructions"
  branchReachedOnlyForCounterTrip ifTrue:
  [ branchReachedOnlyForCounterTrip := false.
  ^ self genCounterTripOnlyJumpIf: boolean to: targetBytecodePC ].
 
  "We detect and: / or:, if found, we don't generate the counters to avoid pathological counter slow down"
  boolean == objectMemory falseObject ifTrue:
  [ nextPC := bytecodePC + (self generatorAt: byte0) numBytes.
   nextDescriptor := self generatorAt: (objectMemory fetchByte: nextPC ofObject: methodObj) + bytecodeSetOffset.
   nextDescriptor generator ==  #genPushConstantTrueBytecode ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ].
   nextDescriptor := self generatorAt: (objectMemory fetchByte: targetBytecodePC ofObject: methodObj) + bytecodeSetOffset.
   nextDescriptor generator ==  #genPushConstantFalseBytecode ifTrue: [ ^ super genJumpIf: boolean to: targetBytecodePC ].  ].
 
  extA := 0. "We ignore the noMustBeBoolean flag. It should not be present in methods with counters, and if it is we don't care."
 
  "We don't generate counters on branches on true/false, the basicblock usage can be inferred"
  desc := self ssTop.
  (desc type == SSConstant
  and: [desc constant = objectMemory trueObject or: [desc constant = objectMemory falseObject]]) ifTrue:
  [ ^ super genJumpIf: boolean to: targetBytecodePC ].
 
  self ssFlushTo: simStackPtr - 1.
  desc popToReg: TempReg.
  self ssPop: 1.
 
  "We need SendNumArgsReg because of the mustBeBooleanTrampoline"
  self ssAllocateRequiredReg: SendNumArgsReg.
 
  retry := self Label.
  self
  genExecutionCountLogicInto: [ :cAddress :countTripBranch |
  counterAddress := cAddress.
  countTripped := countTripBranch ]
  counterReg: SendNumArgsReg.
  counterIndex := counterIndex + 1.
 
  "Cunning trick by LPD.  If true and false are contiguous subtract the smaller.
  Correct result is either 0 or the distance between them.  If result is not 0 or
  their distance send mustBeBoolean."
  self assert: (objectMemory objectAfter: objectMemory falseObject) = objectMemory trueObject.
  self genSubConstant: boolean R: TempReg.
  self JumpZero: (self ensureFixupAt: targetBytecodePC - initialPC).
 
  self genFallsThroughCountLogicCounterReg: SendNumArgsReg counterAddress: counterAddress.
 
+ self CmpCq: (boolean = objectMemory falseObject
- self CmpCq: (boolean == objectMemory falseObject
  ifTrue: [objectMemory trueObject - objectMemory falseObject]
  ifFalse: [objectMemory falseObject - objectMemory trueObject])
  R: TempReg.
  ok := self JumpZero: 0.
  self MoveCq: 0 R: SendNumArgsReg. "if counterReg is 0 this is a mustBeBoolean, not a counter trip."
 
  countTripped jmpTarget: (self genCallMustBeBooleanFor: boolean).
 
  "If we're in an image which hasn't got the Sista code loaded then the ceCounterTripped:
  trampoline will return directly to machine code, returning the boolean.  So the code should
  jump back to the retry point. The trampoline makes sure that TempReg has been reloaded."
  self annotateBytecode: self Label. "For some reason if I write self annotateBytecode: (self Jump: retry) the annotation is not at the correct place."
  self Jump: retry.
 
  ok jmpTarget: self Label.
  ^0!

Item was added:
+ SistaRegisterAllocatingCogit subclass: #SistaCogitClone
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'VMMaker-JIT'!

Item was added:
+ RegisterAllocatingCogit subclass: #SistaRegisterAllocatingCogit
+ instanceVariableNames: 'numCounters counters counterIndex initialCounterValue ceTrapTrampoline branchReachedOnlyForCounterTrip'
+ classVariableNames: 'CounterBytes MaxCounterValue'
+ poolDictionaries: 'VMSqueakClassIndices'
+ category: 'VMMaker-JIT'!
+
+ !SistaRegisterAllocatingCogit commentStamp: 'eem 12/12/2016 09:18' prior: 0!
+ SistaRegisterAllocatingCogit is a port of SistaCogit under RegisterAllocatingCogit.  Its subclass SistaCogitClone holds those methods that are identical to SistaCogit's.  This class holds the methods that are different.  SistaRegisterAllocatingCogit's initialize method keeps things up-to-date and arranges that no method implemented in SistaRegisterAllocatingCogit is implemented in SistaCogitClone so that super sends in SistaCogitClone activate code in RegisterAllocatingCogit as intended.
+
+ Instance Variables
+ branchReachedOnlyForCounterTrip: <Object>
+ ceTrapTrampoline: <Object>
+ counterIndex: <Object>
+ counters: <Object>
+ initialCounterValue: <Object>
+ numCounters: <Object>
+
+ branchReachedOnlyForCounterTrip
+ - xxxxx
+
+ ceTrapTrampoline
+ - xxxxx
+
+ counterIndex
+ - xxxxx
+
+ counters
+ - xxxxx
+
+ initialCounterValue
+ - xxxxx
+
+ numCounters
+ - xxxxx
+ !

Item was added:
+ ----- Method: SistaRegisterAllocatingCogit class>>dateAndTimeFrom: (in category 'clone maintennance') -----
+ dateAndTimeFrom: timeStampString
+ ^(timeStampString copyFrom: (timeStampString findFirst: [:c| c isDigit]) to: timeStampString size) asDateAndTime!

Item was added:
+ ----- Method: SistaRegisterAllocatingCogit class>>implementation:isDifferentThan: (in category 'clone maintennance') -----
+ implementation: aMethodReference isDifferentThan: bMethodReference
+ ^aMethodReference isValid
+ and: [bMethodReference isValid
+ ifTrue: [aMethodReference sourceString ~= bMethodReference sourceString]
+ ifFalse: [true]]!

Item was added:
+ ----- Method: SistaRegisterAllocatingCogit class>>initializeWithOptions: (in category 'class initialization') -----
+ initializeWithOptions: optionsDictionary
+
+ self syncCodeWithSistaCogit ifTrue: "The subclass's #initializeWithOptions: method changed; resend."
+ [^self initializeWithOptions: optionsDictionary].
+
+ "Things are up-to-date; continue"
+ ^super initializeWithOptions: optionsDictionary!

Item was added:
+ ----- Method: SistaRegisterAllocatingCogit class>>syncCodeIn:with:leavingUnchanged: (in category 'class initialization') -----
+ syncCodeIn: sourceClass with: destClass leavingUnchanged: selectorOrNil
+ "Make sure that the SistaRegisterAllocatingCogit/SistaCogitClone combination is up-to-date w.r.t. SistaCogit.
+ - SistaCogitClone should have all methods in SistaCogit except those implemented in SistaRegisterAllocatingCogit.
+ This means that super sends in SistaCogitClone will be understood in SistaRegisterAllocatingCogit, not
+ SistaRegisterAllocatingCogit.
+ - newer methods in SistaCogitClone that are implemented in SistaRegisterAllocatingCogit should be moved up to
+ SistaRegisterAllocatingCogit becaude it means that we probably changed them in SistaCogitClone by mistake
+ and forgot to copy them up.
+ - the same goes for the class side, except for the intializeWithOptions: method which /should/ exist in both
+ SistaRegisterAllocatingCogit and SistaCogitClone, because it runs this initialization."
+
+ | methodTimeStamp |
+ methodTimeStamp := selectorOrNil ifNotNil:
+ [(destClass superclass >>> selectorOrNil) isValid ifTrue:
+ [(destClass >>> selectorOrNil) isValid
+ ifTrue: [(destClass >>> selectorOrNil) timeStamp]
+ ifFalse: ['ancient 01/01/1901 00:00']]].
+
+ destClass selectorsDo:
+ [:s|
+ (s ~~ selectorOrNil
+ and: [(destClass superclass >>> s) isValid
+ and: [self implementation: destClass >>> s isNewerThan: destClass superclass >>> s]]) ifTrue:
+ [destClass superclass recompile: s from: destClass.
+ (destClass superclass whichCategoryIncludesSelector: s) ~= (destClass whichCategoryIncludesSelector: s) ifTrue:
+ [destClass superclass organization classify: s under: (destClass whichCategoryIncludesSelector: s)]]].
+
+ sourceClass selectorsDo:
+ [:s|
+ (self implementation: sourceClass >>> s isDifferentThan: destClass >>> s) ifTrue:
+ [destClass recompile: s from: sourceClass.
+ (destClass whichCategoryIncludesSelector: s) ~= (sourceClass whichCategoryIncludesSelector: s) ifTrue:
+ [destClass organization classify: s under: (sourceClass whichCategoryIncludesSelector: s)]]].
+
+
+ destClass superclass selectorsDo:
+ [:s|
+ (s ~~ selectorOrNil
+ and: [(destClass >>> s) isValid]) ifTrue:
+ [destClass removeSelector: s]].
+
+ ^methodTimeStamp notNil
+  and: [(destClass >>> selectorOrNil) isValid
+  and: [(methodTimeStamp beginsWith: 'ancient')
+ or: [(self dateAndTimeFrom: (destClass >>> selectorOrNil) timeStamp) ~= (self dateAndTimeFrom: methodTimeStamp)]]]!

Item was added:
+ ----- Method: SistaRegisterAllocatingCogit class>>syncCodeWithSistaCogit (in category 'class initialization') -----
+ syncCodeWithSistaCogit
+ "Make sure that the SistaRegisterAllocatingCogit/SistaCogitClone combination is up-to-date w.r.t. SistaCogit.
+ - SistaCogitClone should have all methods in SistaCogit except those implemented in SistaRegisterAllocatingCogit.
+ This means that super sends in SistaCogitClone will be understood in SistaRegisterAllocatingCogit, not
+ SistaRegisterAllocatingCogit.
+ - newer methods in SistaCogitClone that are implemented in SistaRegisterAllocatingCogit should be moved up to
+ SistaRegisterAllocatingCogit becaude it means that we probably changed them in SistaCogitClone by mistake
+ and forgot to copy them up.
+ - the same goes for the class side, except for the intializeWithOptions: method which /should/ exist in both
+ SistaRegisterAllocatingCogit and SistaCogitClone, because it runs this initialization."
+ | syncAction |
+ syncAction :=
+ [self syncCodeIn: SistaCogit with: SistaCogitClone leavingUnchanged: nil.
+ self syncCodeIn: SistaCogit class with: SistaCogitClone class leavingUnchanged: #initializeWithOptions:].
+ ^(Smalltalk classNamed: #CurrentReadOnlySourceFiles)
+ ifNil: syncAction
+ ifNotNil: [:crosf| crosf cacheDuring: syncAction]!

Item was removed:
- ----- Method: VMClass class>>removeThreadedSubSystem (in category 'utilities') -----
- removeThreadedSubSystem
- "VMClass removeQwaqPlugins.
- VMClass removeThreadedSubSystem"
- "For releasing/merging OSCog"
- SystemChangeNotifier uniqueInstance doSilently:
- [CogVMSimulator
- removeSelector: #isThreadedVM;
- removeSelector: #initializeThreadSupport;
- removeSelector: #initialEnterSmalltalkExecutive;
- removeSelector: #ensureMultiThreadingOverridesAreUpToDate.
- (CogVMSimulator organization listAtCategoryNamed: #'multi-threading simulation switch') do:
- [:s| CogVMSimulator removeSelector: s].
- CoInterpreterPrimitives
- subclass: #CogVMSimulator
- instanceVariableNames: CogVMSimulator instanceVariablesString
- classVariableNames: CogVMSimulator classVariablesString
- poolDictionaries: CogVMSimulator sharedPoolsString
- category: CogVMSimulator category.
- SystemOrganization removeSystemCategory: #'VMMaker-Multithreading'.
- self class removeSelector: thisContext selector].
- (Smalltalk classNamed: #MCWorkingCopy) ifNotNil:
- [:mcwc|
- (mcwc forPackage: (MCPackage named: 'VMMaker')) modified: true]!