VM Maker: VMMaker.oscog-cb.1653.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-cb.1653.mcz

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

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

Name: VMMaker.oscog-cb.1653
Author: cb
Time: 19 January 2016, 1:28:02.308 pm
UUID: c46f2c10-6886-4558-9cc7-ffaae87ba44f
Ancestors: VMMaker.oscog-cb.1652

Simplified the generated code and code generating the machine code to make it easier to understand.

Still I have some bugs (but less).

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

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genImmutableCheck:slotIndex:sourceReg:scratchReg:popBoolean:needRestoreRcvr: (in category 'compile abstract instructions') -----
  genImmutableCheck: regHoldingObjectMutated slotIndex: index sourceReg: regHoldingValueToStore scratchReg: scratchReg popBoolean: popBoolean needRestoreRcvr: needRestoreRcvr
  | mutableJump fail |
  <var: #mutableJump type: #'AbstractInstruction *'>
  <var: #fail type: #'AbstractInstruction *'>
  <inline: true>
  <option: #IMMUTABILITY>
  "Trampoline convention:
  - objectMutated passed in ReceiverResultReg
  - index (unboxed) passed in TempReg
  - valueToStore passed in ClassReg.
+ Simulated stack is flushed, but if needRestoreRcvr is true
+ the receiver has to be live after this operation."
- Simulated stack is flushed until simulatedStackPointer - 1, which implies full flush
- if popBoolean is true, else top value may not be flushed.
- We spill the top value (the value to store) for the trampoline if needed."
  self assert: regHoldingObjectMutated == ReceiverResultReg.
  self assert: scratchReg == TempReg.
  self assert: regHoldingValueToStore == ClassReg.
+ mutableJump := self genJumpMutable: ReceiverResultReg scratchReg: TempReg.
- mutableJump := self genJumpMutable: ClassReg scratchReg: TempReg.
 
  "We reach this code if the object mutated is immutable."
- "simulatedStack state altered for the trampoline, spill top value if needed"
- (popBoolean or: [ cogit ssTop spilled ]) ifFalse:
- [ self assert: (cogit ssTop type = SSRegister and: [cogit ssTop register = ClassReg]).
-  cogit PushR: ClassReg ].
- "pass the unboxed index using TempReg"
  cogit MoveCq: index R: TempReg.
  "trampoline call and mcpc to bcpc annotation."
  cogit CallRT: ceCannotAssignToWithIndexTrampoline.
  cogit annotateBytecode: cogit Label.
+ "restore ReceiverResultReg state if needed, the rest of the state is spilled"
- "Top of stack is consumed by the trampoline. In case of store with non spilled value,
- restore ClassReg to match simulated stack state"
- (popBoolean or: [ cogit ssTop spilled ]) ifFalse:
- [cogit popR: ClassReg].
- "restore ReceiverResultReg state if needed"
  needRestoreRcvr ifTrue: [ cogit putSelfInReceiverResultReg ].
  fail := cogit Jump: 0.
 
  "We reach this code is the object mutated is mutable"
  mutableJump jmpTarget: cogit Label.
 
  ^ fail!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genStorePop:LiteralVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean LiteralVariable: litVarIndex
  <inline: false>
  | topReg association needStoreCheck immutabilityFailure |
  "The only reason we assert needsFrame here is that in a frameless method
  ReceiverResultReg must and does contain only self, but the ceStoreCheck
  trampoline expects the target of the store to be in ReceiverResultReg.  So
  in a frameless method we would have a conflict between the receiver and
  the literal store, unless we we smart enough to realise that ReceiverResultReg
  was unused after the literal variable store, unlikely given that methods
  return self by default."
  self assert: needsFrame.
  self cppIf: IMMUTABILITY ifTrue: [ self ssFlushTo: simStackPtr - 1 ].
  "N.B.  No need to check the stack for references because we generate code for
  literal variable loads that stores the result in a register, deferring only the register push."
  needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  association := self getLiteral: litVarIndex.
  optStatus isReceiverResultRegLive: false.
  self ssAllocateRequiredReg: ReceiverResultReg. "for ceStoreCheck call in genStoreSourceReg: has to be ReceiverResultReg"
  self genMoveConstant: association R: ReceiverResultReg.
  objectRepresentation genEnsureObjInRegNotForwarded: ReceiverResultReg scratchReg: TempReg.
  self
  cppIf: IMMUTABILITY
  ifTrue:
  [ self ssAllocateRequiredReg: ClassReg.
   topReg := ClassReg.
   self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
+  "stack is flushed except maybe ssTop if popBoolean is false.
+  ssTop is a SSregister in this case due to #ssStoreAndReplacePop:
+  to avoid a second indirect read / annotation in case of SSConstant
+  or SSBaseRegister"
+  self ssFlushTo: simStackPtr.
   immutabilityFailure := objectRepresentation
  genImmutableCheck: ReceiverResultReg
  slotIndex: ValueIndex
  sourceReg: ClassReg
  scratchReg: TempReg
  popBoolean: popBoolean
  needRestoreRcvr: false ]
  ifFalse:
  [ topReg := self allocateRegForStackEntryAt: 0 notConflictingWith: (self registerMaskFor: ReceiverResultReg).
   self ssStorePop: popBoolean toReg: topReg ].
  traceStores > 0 ifTrue:
  [self MoveR: topReg R: TempReg.
  self CallRT: ceTraceStoreTrampoline].
  objectRepresentation
  genStoreSourceReg: topReg
  slotIndex: ValueIndex
  destReg: ReceiverResultReg
  scratchReg: TempReg
  inFrame: needsFrame
  needsStoreCheck: needStoreCheck.
  self cppIf: IMMUTABILITY ifTrue: [ immutabilityFailure jmpTarget: self Label ].
  ^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genStorePop:MaybeContextReceiverVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean MaybeContextReceiverVariable: slotIndex
  <inline: false>
  | jmpSingle jmpDone needStoreCheck immutabilityFailure |
  <var: #jmpSingle type: #'AbstractInstruction *'>
  <var: #jmpDone type: #'AbstractInstruction *'>
  "The reason we need a frame here is that assigning to an inst var of a context may
  involve wholesale reorganization of stack pages, and the only way to preserve the
  execution state of an activation in that case is if it has a frame."
  self assert: needsFrame.
  self cppIf: IMMUTABILITY ifTrue: [ self ssFlushTo: simStackPtr - 1 ].
  self ssFlushUpThroughReceiverVariable: slotIndex.
  needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  "Note that ReceiverResultReg remains live after both
  ceStoreContextInstVarTrampoline and ceStoreCheckTrampoline."
  self ensureReceiverResultRegContainsSelf.
  self ssPop: 1.
  self ssAllocateCallReg: ClassReg and: SendNumArgsReg. "for ceStoreContextInstVarTrampoline"
  self ssPush: 1.
  objectRepresentation
  genLoadSlot: SenderIndex
  sourceReg: ReceiverResultReg
  destReg: TempReg.
  self
  cppIf: IMMUTABILITY
+ ifTrue:
+ [ self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
+  "stack is flushed except maybe ssTop if popBoolean is false.
+  ssTop is a SSregister in this case due to #ssStoreAndReplacePop:
+  to avoid a second indirect read / annotation in case of SSConstant
+  or SSBaseRegister"
+  self ssFlushTo: simStackPtr. ]
- ifTrue: [ self ssStoreAndReplacePop: popBoolean toReg: ClassReg. ]
  ifFalse: [ self ssStorePop: popBoolean toReg: ClassReg ].
  jmpSingle := objectRepresentation genJumpNotSmallIntegerInScratchReg: TempReg.
  self MoveCq: slotIndex R: SendNumArgsReg.
  self CallRT: ceStoreContextInstVarTrampoline.
  jmpDone := self Jump: 0.
  jmpSingle jmpTarget: self Label.
  traceStores > 0 ifTrue:
  [self MoveR: ClassReg R: TempReg.
  self CallRT: ceTraceStoreTrampoline].
  self
  cppIf: IMMUTABILITY
  ifTrue:
  [ immutabilityFailure := objectRepresentation
  genImmutableCheck: ReceiverResultReg
  slotIndex: ValueIndex
  sourceReg: ClassReg
  scratchReg: TempReg
  popBoolean: popBoolean
  needRestoreRcvr: true ].
  objectRepresentation
  genStoreSourceReg: ClassReg
  slotIndex: slotIndex
  destReg: ReceiverResultReg
  scratchReg: TempReg
  inFrame: true
  needsStoreCheck: needStoreCheck.
  jmpDone jmpTarget: self Label.
  self cppIf: IMMUTABILITY ifTrue: [ immutabilityFailure jmpTarget: self Label ].
  ^0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>genStorePop:ReceiverVariable: (in category 'bytecode generator support') -----
  genStorePop: popBoolean ReceiverVariable: slotIndex
  <inline: false>
  | topReg needStoreCheck immutabilityFailure |
  self cppIf: IMMUTABILITY ifTrue: [ self assert: needsFrame. self ssFlushTo: simStackPtr - 1 ].
  self ssFlushUpThroughReceiverVariable: slotIndex.
  needStoreCheck := (objectRepresentation isUnannotatableConstant: self ssTop) not.
  "Note that ReceiverResultReg remains live after ceStoreCheckTrampoline."
  self ensureReceiverResultRegContainsSelf.
  self
  cppIf: IMMUTABILITY
  ifTrue:
  [ self ssAllocateRequiredReg: ClassReg.
   topReg := ClassReg.
+  self ssStoreAndReplacePop: popBoolean toReg: ClassReg.
+  "stack is flushed except maybe ssTop if popBoolean is false.
+  ssTop is a SSregister in this case due to #ssStoreAndReplacePop:
+  to avoid a second indirect read / annotation in case of SSConstant
+  or SSBaseRegister"
+  self ssFlushTo: simStackPtr.
-  self ssStoreAndReplacePop: popBoolean toReg: topReg.
   immutabilityFailure := objectRepresentation
  genImmutableCheck: ReceiverResultReg
  slotIndex: slotIndex
  sourceReg: ClassReg
  scratchReg: TempReg
  popBoolean: popBoolean
  needRestoreRcvr: true ]
  ifFalse:
  [ topReg := self allocateRegForStackEntryAt: 0 notConflictingWith: (self registerMaskFor: ReceiverResultReg).
   self ssStorePop: popBoolean toReg: topReg ].
  traceStores > 0 ifTrue:
  [ self MoveR: topReg R: TempReg.
  self evaluateTrampolineCallBlock: [ self CallRT: ceTraceStoreTrampoline ] protectLinkRegIfNot: needsFrame ].
  objectRepresentation
  genStoreSourceReg: topReg
  slotIndex: slotIndex
  destReg: ReceiverResultReg
  scratchReg: TempReg
  inFrame: needsFrame
  needsStoreCheck: needStoreCheck.
  self cppIf: IMMUTABILITY ifTrue: [ immutabilityFailure jmpTarget: self Label ].
  ^ 0!

Item was changed:
  ----- Method: StackToRegisterMappingCogit>>ssStoreAndReplacePop:toReg: (in category 'simulation stack') -----
  ssStoreAndReplacePop: popBoolean toReg: reg
  "In addition to ssStorePop:toReg:, if this is a store and not
+ a popInto I change the simulated stack to use the register
+ for the top value"
- a popInto and the top of the simulated stack is not spilled,
- I change the simulated stack to use the register for the value"
  | topSpilled |
  topSpilled := self ssTop spilled.
  self ssStorePop: (popBoolean or: [topSpilled]) toReg: reg.
  popBoolean ifFalse:
  [ topSpilled ifFalse: [self ssPop: 1].
  self ssPushRegister: reg ].!