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

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

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

Name: VMMaker.oscog-eem.2643
Author: eem
Time: 28 December 2019, 2:52:25.430511 pm
UUID: ba23b8e2-c51b-4687-85a2-177db278e3c2
Ancestors: VMMaker.oscog-eem.2642

Cogit: Another small simplification to context creation.
ObjectMemory: safeLastPointerOf: for more robust printing when the JIT is producing bogus code.

=============== Diff against VMMaker.oscog-eem.2642 ===============

Item was changed:
  ----- Method: CogObjectRepresentationForSpur>>genGetActiveContextLarge:inBlock: (in category 'initialization') -----
  genGetActiveContextLarge: isLarge inBlock: isInBlock
  "Create a trampoline to answer the active context that will
  answer it if a frame is already married, and create it otherwise.
  Assume numArgs is in SendNumArgsReg and ClassReg is free."
  | header slotSize jumpSingle loopHead jumpNeedScavenge continuation exit |
  <var: #jumpNeedScavenge type: #'AbstractInstruction *'>
  <var: #continuation type: #'AbstractInstruction *'>
  <var: #jumpSingle type: #'AbstractInstruction *'>
  <var: #loopHead type: #'AbstractInstruction *'>
  <var: #exit type: #'AbstractInstruction *'>
  cogit
  MoveMw: FoxMethod r: FPReg R: ClassReg;
  TstCq: MFMethodFlagHasContextFlag R: ClassReg.
  jumpSingle := cogit JumpZero: 0. "jump if flag bit not set"
  cogit "since the flag bit was set, get the context in the receiver reg and return"
  MoveMw: FoxThisContext r: FPReg R: ReceiverResultReg;
  RetN: 0.
  jumpSingle jmpTarget: cogit Label.
 
  "OK, it doesn't exist; instantiate and initialize it"
  "set the hasContext flag; See CoInterpreter class>>initializeFrameIndices"
  cogit
  OrCq: MFMethodFlagHasContextFlag R: ClassReg;
  MoveR: ClassReg Mw: FoxMethod r: FPReg.
  "now get the home CogMethod into ClassReg and save for post-instantiation."
  isInBlock caseOf: {
  [InFullBlock] -> [cogit SubCq: 3 R: ClassReg]. "-3 is -(hasContext+isBlock) flags"
  [InVanillaBlock] -> [cogit
  SubCq: 3 R: ClassReg; "-3 is -(hasContext+isBlock) flags"
  MoveM16: 0 r: ClassReg R: TempReg;
  SubR: TempReg R: ClassReg].
  [0] -> [cogit SubCq: 1 R: ClassReg]. "-1 is hasContext flag" }.
 
  "instantiate the context..."
  slotSize := isLarge ifTrue: [LargeContextSlots] ifFalse: [SmallContextSlots].
  header := objectMemory
  headerForSlots: slotSize
  format: objectMemory indexablePointersFormat
  classIndex: ClassMethodContextCompactIndex.
  self flag: #endianness.
  cogit MoveAw: objectMemory freeStartAddress R: ReceiverResultReg.
  self genStoreHeader: header intoNewInstance: ReceiverResultReg using: TempReg.
  cogit
+ LoadEffectiveAddressMw: (objectMemory smallObjectBytesForSlots: slotSize) r: ReceiverResultReg R: TempReg;
- MoveR: ReceiverResultReg R: TempReg;
- AddCq: (objectMemory smallObjectBytesForSlots: slotSize) R: TempReg;
  MoveR: TempReg Aw: objectMemory freeStartAddress;
  CmpCq: objectMemory getScavengeThreshold R: TempReg.
  jumpNeedScavenge := cogit JumpAboveOrEqual: 0.
 
  "Now initialize the fields of the context.  See CoInterpreter>>marryFrame:SP:copyTemps:"
  "sender gets frame pointer as a SmallInteger"
  continuation :=
  cogit MoveR: FPReg R: TempReg.
  self genSetSmallIntegerTagsIn: TempReg.
  cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (SenderIndex * objectMemory bytesPerOop) r: ReceiverResultReg.
 
  "pc gets frame caller as a SmallInteger"
  cogit MoveMw: FoxSavedFP r: FPReg R: TempReg.
  self genSetSmallIntegerTagsIn: TempReg.
  cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (InstructionPointerIndex * objectMemory bytesPerOop) r: ReceiverResultReg.
 
  "Set the method field, freeing up ClassReg again, and frame's context field,"
  cogit
  MoveMw: (cogit offset: CogMethod of: #methodObject) r: ClassReg R: TempReg;
  MoveR: TempReg Mw: objectMemory baseHeaderSize + (MethodIndex * objectMemory wordSize) r: ReceiverResultReg;
  MoveR: ReceiverResultReg Mw: FoxThisContext r: FPReg.
 
  "Now compute stack pointer; this is stackPointer (- 1 for return pc if a CISC) - framePointer - wordSize (1 each for saved pc, method, context, receiver) + 1 (1-relative) + numArgs"
  "TPR note - the code here is actually doing
  context stackPointer := ((((fp - sp) / wordSize) - [3|4]) + num args) asSmallInteger"
  cogit
  SubR: SPReg R: FPReg R: TempReg; "TempReg := FPReg - SPReg"
  LogicalShiftRightCq: self log2BytesPerWord R: TempReg;
  SubCq: (cogit backEnd hasLinkRegister ifTrue: [3] ifFalse: [4]) R: TempReg;
  AddR: SendNumArgsReg R: TempReg.
  self genConvertIntegerToSmallIntegerInReg: TempReg.
  cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (StackPointerIndex * objectMemory bytesPerOop) r: ReceiverResultReg.
 
  "Set closureOrNil to either the stacked receiver or nil"
  isInBlock > 0
  ifTrue:
  [cogit
  MoveR: SendNumArgsReg R: TempReg;
  AddCq: 2 R: TempReg; "+2 for saved fp and saved pc"
  MoveXwr: TempReg R: FPReg R: TempReg]
  ifFalse:
  [cogit genMoveNilR: TempReg].
  cogit MoveR: TempReg Mw: objectMemory baseHeaderSize + (ClosureIndex * objectMemory bytesPerOop) r: ReceiverResultReg.
 
  "Set the receiver"
  cogit
  MoveMw: FoxMFReceiver r: FPReg R: TempReg;
  MoveR: TempReg Mw: objectMemory baseHeaderSize + (ReceiverIndex * objectMemory bytesPerOop) r: ReceiverResultReg.
 
  "Now copy the arguments.  This is tricky because of the shortage of registers,.  ClassReg ranges
  from 1 to numArgs (SendNumArgsReg), and from ReceiverIndex + 1 to ReceiverIndex + numArgs.
  1 to: numArgs do:
  [:i|
  temp := longAt(FPReg + ((SendNumArgs - i + 2) * wordSize)). +2 for saved pc and savedfp
  longAtput(FPReg + FoxMFReceiver + (i * wordSize), temp)]"
  "TPR note: this is a prime candidate for passing off to the backend to do at least faintly optimal code"
  cogit MoveCq: 1 R: ClassReg.
  loopHead := cogit CmpR: SendNumArgsReg R: ClassReg.
  exit := cogit JumpGreater: 0.
  cogit
  MoveR: SendNumArgsReg R: TempReg;
  SubR: ClassReg R: TempReg;
  AddCq: 2 R: TempReg; "+2 for saved fp and saved pc"
  MoveXwr: TempReg R: FPReg R: TempReg;
  AddCq: ReceiverIndex + (objectMemory baseHeaderSize / objectMemory wordSize) R: ClassReg; "Now convert ClassReg from frame index to context index"
  MoveR: TempReg Xwr: ClassReg R: ReceiverResultReg;
  SubCq: ReceiverIndex + (objectMemory baseHeaderSize / objectMemory wordSize) - 1 R: ClassReg; "convert back adding 1 ;-)"
  Jump: loopHead.
  exit jmpTarget: cogit Label.
 
  "Finally nil or copy the non-argument temps.
  ClassReg := FPReg + FoxMFReceiver.
  SendNumArgsReg := SendNumArgsReg+ReceiverIndex.
  [ClassReg := ClassReg - wordSize.
   backEnd hasLinkRegister
  ifTrue: [ClassReg > SPReg]
  ifFalse: [ClassReg >= SPReg]] whileTrue:
  [receiver[SendNumArgsReg] := *ClassReg.
  SendNumArgsReg := SendNumArgsReg + 1]]"
  coInterpreter marryFrameCopiesTemps ifFalse:
  [cogit MoveCq: objectMemory nilObject R: TempReg].
  cogit
  MoveR: FPReg R: ClassReg;
  AddCq: FoxMFReceiver R: ClassReg;
  AddCq: ReceiverIndex + 1 + (objectMemory baseHeaderSize / objectMemory wordSize) R: SendNumArgsReg.
  loopHead :=
  cogit SubCq: objectMemory wordSize R: ClassReg.
  cogit CmpR: ClassReg R: SPReg.
  "If on a CISC there's a retpc for the trampoline call on top of stack; if on a RISC there isn't."
  exit := cogit backEnd hasLinkRegister
  ifTrue: [cogit JumpAboveOrEqual: 0]
  ifFalse: [cogit JumpBelow: 0].
  coInterpreter marryFrameCopiesTemps ifTrue:
  [cogit MoveMw: 0 r: ClassReg R: TempReg].
  cogit
  MoveR: TempReg Xwr: SendNumArgsReg R: ReceiverResultReg;
  AddCq: 1 R: SendNumArgsReg;
  Jump: loopHead.
  exit jmpTarget: cogit Label.
 
  cogit RetN: 0.
 
  jumpNeedScavenge jmpTarget: cogit Label.
  cogit backEnd saveAndRestoreLinkRegAround:
  [cogit
  CallRT: ceScheduleScavengeTrampoline
  registersToBeSavedMask: (cogit registerMaskFor: ReceiverResultReg and: SendNumArgsReg and: ClassReg)].
  cogit Jump: continuation.
  ^0!

Item was added:
+ ----- Method: NewObjectMemory>>safeLastPointerOf: (in category 'object enumeration') -----
+ safeLastPointerOf: objOop
+ "Return the byte offset of the last pointer field of the given object.  
+ Can be used even when the type bits are not correct.
+ Works with CompiledMethods, as well as ordinary objects."
+ <api>
+ <inline: true>
+ | byteSize fmt header contextSize |
+ byteSize := (self sizeBitsOfSafe: objOop) - self baseHeaderSize.
+ header := self baseHeader: objOop.
+ fmt := self formatOfHeader: header.
+ fmt <= self lastPointerFormat ifTrue:
+ [(fmt = self indexablePointersFormat
+  and: [self isContextHeader: header]) ifTrue:
+ ["contexts end at the stack pointer"
+ contextSize := coInterpreter fetchStackPointerOf: objOop.
+ ^CtxtTempFrameStart + contextSize * self bytesPerOop min: byteSize].
+ ^byteSize  "all pointers"].
+ fmt < self firstCompiledMethodFormat ifTrue: [^0]. "no pointers"
+
+ "CompiledMethod: contains both pointers and bytes"
+ header := self methodHeaderOf: objOop.
+ ^(self lastPointerOfMethodHeader: header) min: byteSize!

Item was added:
+ ----- Method: SpurMemoryManager>>safeLastPointerOf: (in category 'object enumeration') -----
+ safeLastPointerOf: objOop
+ "Answer the byte offset of the last pointer field of the given object.
+ Works with CompiledMethods, as well as ordinary objects."
+ <inline: true>
+ | fmt contextSize header byteSize |
+ byteSize := (self numSlotsOf: objOop) - 1 * self bytesPerOop + self baseHeaderSize.
+ fmt := self formatOf: objOop.
+ self assert: fmt ~= self forwardedFormat.
+ fmt <= self lastPointerFormat ifTrue:
+ [(fmt = self indexablePointersFormat
+  and: [self isContextNonImm: objOop]) ifTrue:
+ ["contexts end at the stack pointer"
+ contextSize := coInterpreter fetchStackPointerOf: objOop.
+ ^CtxtTempFrameStart - 1 + contextSize * self bytesPerOop + self baseHeaderSize min: byteSize].
+ ^byteSize  "all pointers"].
+ fmt < self firstCompiledMethodFormat ifTrue: [^0]. "no pointers"
+
+ "CompiledMethod: contains both pointers and bytes"
+ header := self methodHeaderOf: objOop.
+ ^(self lastPointerOfMethodHeader: header) min: byteSize!