VM Maker: VMMaker.oscog-nice.2500.mcz

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

VM Maker: VMMaker.oscog-nice.2500.mcz

commits-2
 
Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2500.mcz

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

Name: VMMaker.oscog-nice.2500
Author: nice
Time: 27 December 2018, 3:09:23.063219 pm
UUID: c991a570-d1c2-4445-b94d-83b6da74f435
Ancestors: VMMaker.oscog-nice.2499

Fix a few C compiler warnings for LLP64:

1) always declare primitiveRoutine as 'void (*primitiveRoutine)(void)'
  It was sometimes declared '(*primitiveRoutine)()'

2) correct the printNum macro
printf("%ld",(long) n) should be printf("%ld",(long) (n)) otherwise printNum: x + y will be interpreted printf("%ld",(long) x + y), that is printf("%ld",((long) x) +y) and if y is sqInt (most of the time), then %lld is required in LLP64 and the compiler barks...
While at it, use the dedicated macro PRIdSQINT for printing sqInt.

3) remove cast statSGCDeltaUsecs asUnsignedLong in writeScavengeLog
The PRIdSQINT expects a lon long (64 bits) not an unsigned long (32 bits in LLP64)

=============== Diff against VMMaker.oscog-nice.2499 ===============

Item was changed:
  ----- Method: Cogit>>printNum: (in category 'printing') -----
  printNum: n
+ <cmacro: '(n) printf("%" PRIdSQINT, (sqInt) (n)'>
- <cmacro: '(n) printf("%ld", (long) n)'>
  coInterpreter transcript printNum: n!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>compileInterpreterPrimitive (in category 'primitive generators') -----
  compileInterpreterPrimitive
  <inline: true>
  | primitiveRoutine |
+ <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
- <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
  primitiveRoutine := coInterpreter
  functionPointerForCompiledMethod: methodObj
  primitiveIndex: primitiveIndex.
  ^ self
  compileInterpreterPrimitive: primitiveRoutine
  flags: (coInterpreter primitivePropertyFlags: primitiveIndex)!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveClosureValue (in category 'primitive generators') -----
  genPrimitiveClosureValue
  "Check the argument count.  Fail if wrong.
  Get the method from the outerContext and see if it is cogged.  If so, jump to the
  block entry or the no-context-switch entry, as appropriate, and we're done.  If not,
  invoke the interpreter primitive."
  | jumpFailNArgs jumpFail1 jumpFail2 jumpFail3 jumpFail4 jumpBCMethod primitiveRoutine result |
  <var: #jumpFail1 type: #'AbstractInstruction *'>
  <var: #jumpFail2 type: #'AbstractInstruction *'>
  <var: #jumpFail3 type: #'AbstractInstruction *'>
  <var: #jumpFail4 type: #'AbstractInstruction *'>
  <var: #jumpFailNArgs type: #'AbstractInstruction *'>
  <var: #jumpBCMethod type: #'AbstractInstruction *'>
+ <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
- <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
  objectRepresentation genLoadSlot: ClosureNumArgsIndex sourceReg: ReceiverResultReg destReg: TempReg.
  self CmpCq: (objectMemory integerObjectOf: methodOrBlockNumArgs) R: TempReg.
  jumpFailNArgs := self JumpNonZero: 0.
  objectRepresentation genLoadSlot: ClosureOuterContextIndex sourceReg: ReceiverResultReg destReg: ClassReg.
  jumpFail1 := objectRepresentation genJumpImmediate: ClassReg.
  objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: TempReg.
  objectRepresentation genCmpClassMethodContextCompactIndexR: TempReg.
  jumpFail2 := self JumpNonZero: 0.
  "We defer unforwarding the receiver to the prologue; scanning blocks
  for inst var refs and only unforwarding if the block refers to inst vars."
  (false
  and: [objectRepresentation hasSpurMemoryManagerAPI]) ifTrue:
  [objectRepresentation
  genLoadSlot: ReceiverIndex sourceReg: ClassReg destReg: SendNumArgsReg;
  genEnsureOopInRegNotForwarded: SendNumArgsReg
  scratchReg: TempReg
  updatingSlot: ReceiverIndex
  in: ClassReg].
  objectRepresentation genLoadSlot: MethodIndex sourceReg: ClassReg destReg: SendNumArgsReg.
  jumpFail3 := objectRepresentation genJumpImmediate: SendNumArgsReg.
  objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg.
  self CmpCq: objectMemory firstCompiledMethodFormat R: TempReg.
  jumpFail4 := self JumpLess: 0.
  objectRepresentation genLoadSlot: HeaderIndex sourceReg: SendNumArgsReg destReg: ClassReg.
  jumpBCMethod := objectRepresentation genJumpImmediate: ClassReg.
  self MoveM16: (self offset: CogMethod of: #blockEntryOffset) r: ClassReg R: TempReg.
  self AddR: ClassReg R: TempReg.
  primitiveRoutine := coInterpreter
  functionPointerForCompiledMethod: methodObj
  primitiveIndex: primitiveIndex.
  primitiveRoutine = #primitiveClosureValueNoContextSwitch ifTrue:
  [blockNoContextSwitchOffset = nil ifTrue:
  [^NotFullyInitialized].
  self SubCq: blockNoContextSwitchOffset R: TempReg].
  self JumpR: TempReg.
  jumpBCMethod jmpTarget: (jumpFail1 jmpTarget: (jumpFail2 jmpTarget: (jumpFail3 jmpTarget: (jumpFail4 jmpTarget: self Label)))).
  (result := self
  compileInterpreterPrimitive: primitiveRoutine
  flags: (coInterpreter primitivePropertyFlags: primitiveIndex)) < 0 ifTrue:
  [^result].
  jumpFailNArgs jmpTarget: self Label.
  ^CompletePrimitive!

Item was changed:
  ----- Method: SimpleStackBasedCogit>>genPrimitiveFullClosureValue (in category 'primitive generators') -----
  genPrimitiveFullClosureValue
  "Check the argument count.  Fail if wrong.
  Get the method from the outerContext and see if it is cogged.  If so, jump to the
  block entry or the no-context-switch entry, as appropriate, and we're done.  If not,
  invoke the interpreter primitive."
  | jumpFailNArgs jumpFailImmediateMethod jumpFail4 jumpBCMethod primitiveRoutine result |
  <option: #SistaV1BytecodeSet>
  <var: #jumpFailImmediateMethod type: #'AbstractInstruction *'>
  <var: #jumpFail4 type: #'AbstractInstruction *'>
  <var: #jumpFailNArgs type: #'AbstractInstruction *'>
  <var: #jumpBCMethod type: #'AbstractInstruction *'>
+ <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
- <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
  objectRepresentation genLoadSlot: ClosureNumArgsIndex sourceReg: ReceiverResultReg destReg: TempReg.
  self CmpCq: (objectMemory integerObjectOf: methodOrBlockNumArgs) R: TempReg.
  jumpFailNArgs := self JumpNonZero: 0.
 
  "We defer unforwarding the receiver to the prologue; scanning blocks
  for inst var refs and only unforwarding if the block refers to inst vars."
  (false
  and: [objectRepresentation hasSpurMemoryManagerAPI]) ifTrue:
  [objectRepresentation
  genLoadSlot: FullClosureReceiverIndex sourceReg: ReceiverResultReg destReg: SendNumArgsReg;
  genEnsureOopInRegNotForwarded: SendNumArgsReg
  scratchReg: TempReg
  updatingSlot: FullClosureReceiverIndex
  in: ReceiverResultReg].
  objectRepresentation genLoadSlot: FullClosureCompiledBlockIndex sourceReg: ReceiverResultReg destReg: SendNumArgsReg.
  jumpFailImmediateMethod := objectRepresentation genJumpImmediate: SendNumArgsReg.
  objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg.
  self CmpCq: objectMemory firstCompiledMethodFormat R: TempReg.
  jumpFail4 := self JumpLess: 0.
  objectRepresentation genLoadSlot: HeaderIndex sourceReg: SendNumArgsReg destReg: ClassReg.
  jumpBCMethod := objectRepresentation genJumpImmediate: ClassReg.
 
  primitiveRoutine := coInterpreter
  functionPointerForCompiledMethod: methodObj
  primitiveIndex: primitiveIndex.
  self AddCq: (primitiveRoutine = #primitiveFullClosureValueNoContextSwitch
  ifTrue: [self fullBlockNoContextSwitchEntryOffset]
  ifFalse: [self fullBlockEntryOffset])
  R: ClassReg.
  self JumpR: ClassReg.
  jumpBCMethod jmpTarget: (jumpFailImmediateMethod jmpTarget: (jumpFail4 jmpTarget: self Label)).
  (result := self
  compileInterpreterPrimitive: primitiveRoutine
  flags: (coInterpreter primitivePropertyFlags: primitiveIndex)) < 0 ifTrue:
  [^result].
  jumpFailNArgs jmpTarget: self Label.
  ^CompletePrimitive!

Item was changed:
  ----- Method: SpurGenerationScavenger>>writeScavengeLog (in category 'logging') -----
  writeScavengeLog
  "Output the entire record."
  <inline: #never>
  | policyNames |
  <var: 'policyNames' declareC: 'static char *policyNames[] = {"", "by age", "by class", "to shrink rt", "don''t tenure", "mark on tenure"}'>
  self cCode: []
  inSmalltalk: [policyNames := CLiteralArray on: #('' 'by age' 'by class' 'to shrink rt' 'don''t tenure' 'mark on tenure')].
  scavengeLog "log data collected by logStartScavenge"
  f: 'scavenge %ld eden bytes: 0x%lx/%ld past bytes: 0x%lx/%ld\n\trem set: %ld redzone: %ld size: %ld\n'
  printf:{ manager statScavenges.
  scavengeLogRecord sEdenBytes.
  scavengeLogRecord sEdenBytes.
  scavengeLogRecord sPastBytes.
  scavengeLogRecord sPastBytes.
  scavengeLogRecord sRememberedSetSize.
  scavengeLogRecord sRememberedSetRedZone.
  scavengeLogRecord sRememberedSetLimit }.
  scavengeLog "log data collected by logTenuringPolicy"
  f: (scavengeLogRecord tTenureCriterion = TenureToShrinkRT
  ifFalse: [' tenure below 0x%lx/%ld %s\n']
  ifTrue: [' tenure below 0x%lx/%ld %s refct %ld\n'])
  printf:{ scavengeLogRecord tTenureThreshold.
  scavengeLogRecord tTenureThreshold.
  policyNames at: scavengeLogRecord tTenureCriterion.
  scavengeLogRecord tRefCountToShrinkRT }.
  scavengeLog "log data collected by logEndScavenge"
  f: ' survivor bytes: 0x%lx/%ld rem set: %ld tenured: %ld usecs: %ld\n'
  printf:{ scavengeLogRecord eSurvivorBytes.
  scavengeLogRecord eSurvivorBytes.
  scavengeLogRecord eRememberedSetSize.
  scavengeLogRecord eStatTenures - scavengeLogRecord sStatTenures.
+ manager statSGCDeltaUsecs}.
- manager statSGCDeltaUsecs asUnsignedLong }.
  scavengeLog fflush!

Reply | Threaded
Open this post in threaded view
|

Re: VM Maker: VMMaker.oscog-nice.2500.mcz

Eliot Miranda-2
 
Hi Nicolas, Hi All,

  re genPrimitiveClosureValue and all the other Cogit hierarchy generators full of declarations such as

     <var: #jumpFail1 type: #'AbstractInstruction *'>
     <var: #jumpFail2 type: #'AbstractInstruction *'>
     <var: #jumpFail3 type: #'AbstractInstruction *'>

The type inferencer in Slang is now much stronger that when Cogit was first written, specifically to support 64-bit Spur using the same abstract base classes as 32-bit Spur.  So feel free to nuke those explicit declarations as you commit.  There is a test expression for translating a single method in image/Slang Test Workspace.text one can use to check that types are correctly inferred.  So run the expression, save the output (which appears in the transcript), delete the declarations, repeat, and one can quickly check that the same code is produced. Look for the third doit in image/Slang Test Workspace.text that translates compileEntry.  It contains the line

    sel := #compileEntry.

On Dec 27, 2018, at 6:10 AM, [hidden email] wrote:


Nicolas Cellier uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-nice.2500.mcz

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

Name: VMMaker.oscog-nice.2500
Author: nice
Time: 27 December 2018, 3:09:23.063219 pm
UUID: c991a570-d1c2-4445-b94d-83b6da74f435
Ancestors: VMMaker.oscog-nice.2499

Fix a few C compiler warnings for LLP64:

1) always declare primitiveRoutine as 'void (*primitiveRoutine)(void)'
 It was sometimes declared '(*primitiveRoutine)()'

2) correct the printNum macro
printf("%ld",(long) n) should be printf("%ld",(long) (n)) otherwise printNum: x + y will be interpreted printf("%ld",(long) x + y), that is printf("%ld",((long) x) +y) and if y is sqInt (most of the time), then %lld is required in LLP64 and the compiler barks...
While at it, use the dedicated macro PRIdSQINT for printing sqInt.

3) remove cast statSGCDeltaUsecs asUnsignedLong in writeScavengeLog
The PRIdSQINT expects a lon long (64 bits) not an unsigned long (32 bits in LLP64)

=============== Diff against VMMaker.oscog-nice.2499 ===============

Item was changed:
 ----- Method: Cogit>>printNum: (in category 'printing') -----
 printNum: n
+    <cmacro: '(n) printf("%" PRIdSQINT, (sqInt) (n)'>
-    <cmacro: '(n) printf("%ld", (long) n)'>
     coInterpreter transcript printNum: n!

Item was changed:
 ----- Method: SimpleStackBasedCogit>>compileInterpreterPrimitive (in category 'primitive generators') -----
 compileInterpreterPrimitive
     <inline: true>
     | primitiveRoutine |
+    <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
-    <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
     primitiveRoutine := coInterpreter
                             functionPointerForCompiledMethod: methodObj
                             primitiveIndex: primitiveIndex.
     ^ self
         compileInterpreterPrimitive: primitiveRoutine
         flags: (coInterpreter primitivePropertyFlags: primitiveIndex)!

Item was changed:
 ----- Method: SimpleStackBasedCogit>>genPrimitiveClosureValue (in category 'primitive generators') -----
 genPrimitiveClosureValue
     "Check the argument count.  Fail if wrong.
      Get the method from the outerContext and see if it is cogged.  If so, jump to the
      block entry or the no-context-switch entry, as appropriate, and we're done.  If not,
      invoke the interpreter primitive."
     | jumpFailNArgs jumpFail1 jumpFail2 jumpFail3 jumpFail4 jumpBCMethod primitiveRoutine result |
     <var: #jumpFail1 type: #'AbstractInstruction *'>
     <var: #jumpFail2 type: #'AbstractInstruction *'>
     <var: #jumpFail3 type: #'AbstractInstruction *'>
     <var: #jumpFail4 type: #'AbstractInstruction *'>
     <var: #jumpFailNArgs type: #'AbstractInstruction *'>
     <var: #jumpBCMethod type: #'AbstractInstruction *'>
+    <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
-    <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
     objectRepresentation genLoadSlot: ClosureNumArgsIndex sourceReg: ReceiverResultReg destReg: TempReg.
     self CmpCq: (objectMemory integerObjectOf: methodOrBlockNumArgs) R: TempReg.
     jumpFailNArgs := self JumpNonZero: 0.
     objectRepresentation genLoadSlot: ClosureOuterContextIndex sourceReg: ReceiverResultReg destReg: ClassReg.
     jumpFail1 := objectRepresentation genJumpImmediate: ClassReg.
     objectRepresentation genGetCompactClassIndexNonImmOf: ClassReg into: TempReg.
     objectRepresentation genCmpClassMethodContextCompactIndexR: TempReg.
     jumpFail2 := self JumpNonZero: 0.
     "We defer unforwarding the receiver to the prologue; scanning blocks
      for inst var refs and only unforwarding if the block refers to inst vars."
     (false
      and: [objectRepresentation hasSpurMemoryManagerAPI]) ifTrue:
         [objectRepresentation
             genLoadSlot: ReceiverIndex sourceReg: ClassReg destReg: SendNumArgsReg;
             genEnsureOopInRegNotForwarded: SendNumArgsReg
             scratchReg: TempReg
             updatingSlot: ReceiverIndex
             in: ClassReg].
     objectRepresentation genLoadSlot: MethodIndex sourceReg: ClassReg destReg: SendNumArgsReg.
     jumpFail3 := objectRepresentation genJumpImmediate: SendNumArgsReg.
     objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg.
     self CmpCq: objectMemory firstCompiledMethodFormat R: TempReg.
     jumpFail4 := self JumpLess: 0.
     objectRepresentation genLoadSlot: HeaderIndex sourceReg: SendNumArgsReg destReg: ClassReg.
     jumpBCMethod := objectRepresentation genJumpImmediate: ClassReg.
     self MoveM16: (self offset: CogMethod of: #blockEntryOffset) r: ClassReg R: TempReg.
     self AddR: ClassReg R: TempReg.
     primitiveRoutine := coInterpreter
                             functionPointerForCompiledMethod: methodObj
                             primitiveIndex: primitiveIndex.
     primitiveRoutine = #primitiveClosureValueNoContextSwitch ifTrue:
         [blockNoContextSwitchOffset = nil ifTrue:
             [^NotFullyInitialized].
          self SubCq: blockNoContextSwitchOffset R: TempReg].
     self JumpR: TempReg.
     jumpBCMethod jmpTarget: (jumpFail1 jmpTarget: (jumpFail2 jmpTarget: (jumpFail3 jmpTarget: (jumpFail4 jmpTarget: self Label)))).
     (result := self
                 compileInterpreterPrimitive: primitiveRoutine
                 flags: (coInterpreter primitivePropertyFlags: primitiveIndex)) < 0 ifTrue:
         [^result].
     jumpFailNArgs jmpTarget: self Label.
     ^CompletePrimitive!

Item was changed:
 ----- Method: SimpleStackBasedCogit>>genPrimitiveFullClosureValue (in category 'primitive generators') -----
 genPrimitiveFullClosureValue
     "Check the argument count.  Fail if wrong.
      Get the method from the outerContext and see if it is cogged.  If so, jump to the
      block entry or the no-context-switch entry, as appropriate, and we're done.  If not,
      invoke the interpreter primitive."
     | jumpFailNArgs jumpFailImmediateMethod jumpFail4 jumpBCMethod primitiveRoutine result |
     <option: #SistaV1BytecodeSet>
     <var: #jumpFailImmediateMethod type: #'AbstractInstruction *'>
     <var: #jumpFail4 type: #'AbstractInstruction *'>
     <var: #jumpFailNArgs type: #'AbstractInstruction *'>
     <var: #jumpBCMethod type: #'AbstractInstruction *'>
+    <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)(void)'>
-    <var: #primitiveRoutine declareC: 'void (*primitiveRoutine)()'>
     objectRepresentation genLoadSlot: ClosureNumArgsIndex sourceReg: ReceiverResultReg destReg: TempReg.
     self CmpCq: (objectMemory integerObjectOf: methodOrBlockNumArgs) R: TempReg.
     jumpFailNArgs := self JumpNonZero: 0.

     "We defer unforwarding the receiver to the prologue; scanning blocks
      for inst var refs and only unforwarding if the block refers to inst vars."
     (false
      and: [objectRepresentation hasSpurMemoryManagerAPI]) ifTrue:
         [objectRepresentation
             genLoadSlot: FullClosureReceiverIndex sourceReg: ReceiverResultReg destReg: SendNumArgsReg;
             genEnsureOopInRegNotForwarded: SendNumArgsReg
             scratchReg: TempReg
             updatingSlot: FullClosureReceiverIndex
             in: ReceiverResultReg].
     objectRepresentation genLoadSlot: FullClosureCompiledBlockIndex sourceReg: ReceiverResultReg destReg: SendNumArgsReg.
     jumpFailImmediateMethod := objectRepresentation genJumpImmediate: SendNumArgsReg.
     objectRepresentation genGetFormatOf: SendNumArgsReg into: TempReg.
     self CmpCq: objectMemory firstCompiledMethodFormat R: TempReg.
     jumpFail4 := self JumpLess: 0.
     objectRepresentation genLoadSlot: HeaderIndex sourceReg: SendNumArgsReg destReg: ClassReg.
     jumpBCMethod := objectRepresentation genJumpImmediate: ClassReg.

     primitiveRoutine := coInterpreter
                             functionPointerForCompiledMethod: methodObj
                             primitiveIndex: primitiveIndex.
     self AddCq: (primitiveRoutine = #primitiveFullClosureValueNoContextSwitch
                     ifTrue: [self fullBlockNoContextSwitchEntryOffset]
                     ifFalse: [self fullBlockEntryOffset])
          R: ClassReg.
     self JumpR: ClassReg.
     jumpBCMethod jmpTarget: (jumpFailImmediateMethod jmpTarget: (jumpFail4 jmpTarget: self Label)).
     (result := self
                 compileInterpreterPrimitive: primitiveRoutine
                  flags: (coInterpreter primitivePropertyFlags: primitiveIndex)) < 0 ifTrue:
         [^result].
     jumpFailNArgs jmpTarget: self Label.
     ^CompletePrimitive!

Item was changed:
 ----- Method: SpurGenerationScavenger>>writeScavengeLog (in category 'logging') -----
 writeScavengeLog
     "Output the entire record."
     <inline: #never>
     | policyNames |
     <var: 'policyNames' declareC: 'static char *policyNames[] = {"", "by age", "by class", "to shrink rt", "don''t tenure", "mark on tenure"}'>
     self cCode: []
         inSmalltalk: [policyNames := CLiteralArray on: #('' 'by age' 'by class' 'to shrink rt' 'don''t tenure' 'mark on tenure')].
     scavengeLog "log data collected by logStartScavenge"
         f: 'scavenge %ld eden bytes: 0x%lx/%ld past bytes: 0x%lx/%ld\n\trem set: %ld redzone: %ld size: %ld\n'
         printf:{    manager statScavenges.
                 scavengeLogRecord sEdenBytes.
                 scavengeLogRecord sEdenBytes.
                 scavengeLogRecord sPastBytes.
                 scavengeLogRecord sPastBytes.
                 scavengeLogRecord sRememberedSetSize.
                 scavengeLogRecord sRememberedSetRedZone.
                 scavengeLogRecord sRememberedSetLimit }.
     scavengeLog "log data collected by logTenuringPolicy"
         f: (scavengeLogRecord tTenureCriterion = TenureToShrinkRT
                 ifFalse: ['    tenure below 0x%lx/%ld %s\n']
                 ifTrue: ['    tenure below 0x%lx/%ld %s refct %ld\n'])
         printf:{    scavengeLogRecord tTenureThreshold.
                 scavengeLogRecord tTenureThreshold.
                 policyNames at: scavengeLogRecord tTenureCriterion.
                 scavengeLogRecord tRefCountToShrinkRT }.
     scavengeLog "log data collected by logEndScavenge"
         f: '    survivor bytes: 0x%lx/%ld rem set: %ld tenured: %ld usecs: %ld\n'
         printf:{    scavengeLogRecord eSurvivorBytes.
                 scavengeLogRecord eSurvivorBytes.
                 scavengeLogRecord eRememberedSetSize.
                 scavengeLogRecord eStatTenures - scavengeLogRecord sStatTenures.
+                manager statSGCDeltaUsecs}.
-                manager statSGCDeltaUsecs asUnsignedLong }.
     scavengeLog fflush!