SlideShare une entreprise Scribd logo
1  sur  53
Télécharger pour lire hors ligne
GC in Smalltalk
          now what?




Javier Burroni        gera
Smalltalk VM
         Writen in Smalltalk
.exe / .dll generation
JIT
Message dispatching
Object format
Memory management
   Object creation / copy
   GC
   Become
Primitives
FFI
Processes
Callbacks
etc
What now?


Optimizations
     Instrumentation
          Alternative GC
                Finish the VM (of course)
Optimizations

Monomorphic Inline Cache

  Linked sends

Inline Underprimitives

Replace primitives

Many others with small impact
Optimization: Linked send

self _isSmallInteger

                                  ^false
currentClass := self class



     Object >> #isNil
         currentClass == Object
                                   UndefinedObject >> #isNil
                                      currentClass == UndefinedObject



                                                   currentClass :=
                                                      currentClass superclass
      ^false                               ^true
Optimization: Linked send

self _isSmallInteger

                                  ^false
currentClass := self class



     Object >> #isNil
         currentClass == Object
                                   UndefinedObject >> #isNil
                                      currentClass == UndefinedObject



                                                   currentClass :=
                                                      currentClass superclass
      ^false                               ^true
Optimization: Linked send

                                   Object subclass: #SelectorMultiplexorNativizer




for: aClass renderJumpTo: aCompiledMethod
  | reference |
  self disableCode: [assembler breakpoint].
  assembler
    compareTempToConstant: aClass methodDictionaries oop;
    absoluteReferenceTo: aClass methodDictionaries;
    nearJumpIfEqual.




 reference := assembler relativeReferenceTo: aCompiledMethod fullName.
 reference noClassCheck.
Optimization: Linked send

                                   Object subclass: #SelectorMultiplexorNativizer




for: aClass renderJumpTo: aCompiledMethod
  | reference nextImplementation |
  self disableCode: [assembler breakpoint].
  nextImplementation := assembler
    compareTempToConstant: aClass methodDictionaries oop;
    absoluteReferenceTo: aClass methodDictionaries;
    shortJumpIfNotEqual.

 self emitMonomorphicInlineCacheTo: aCompiledMethod.

 assembler nearJump.
 reference := assembler relativeReferenceTo: aCompiledMethod fullName.
 reference noClassCheck.
 assembler jumpDestinationFor: nextImplementat
Optimization: Linked send

                                    Object subclass: #SelectorMultiplexorNativizer




for: aClass renderJumpTo: aCompiledMethod
  | reference nextImplementation skipMic |
  self disableCode: [assembler breakpoint].
  nextImplementation := assembler
    compareTempToConstant: aClass methodDictionaries oop;
    absoluteReferenceTo: aClass methodDictionaries;
    shortJumpIfNotEqual.
  skipMic := assembler compareArg; assembler shortJumpIfEqual.
  self emitMonomorphicInlineCacheTo: aCompiledMethod.
  assembler jumpDestinationFor: skipMic.
  assembler nearJump.
  reference := assembler relativeReferenceTo: aCompiledMethod fullName.
  reference noClassCheck.
  assembler jumpDestinationFor: nextImplementat
Optimization: Linked send

                                 Object subclass: #SelectorMultiplexorNativizer




emitMonomorphicInlineCacheTo: aCompiledMethod
 assembler
   loadEntrypoint: aCompiledMethod;
   patchClassCheck;
   patchCallSite
Optimization: Linked send
GenerationalGC>>#collect
 self initLocals;
   ...
   purgeRoots;
   followCodeCacheReferences;
   followRoots;
   followStack;
   ...



call     near   ptr gc_purgeRoots
mov      eax,   [esp]
call     near   ptr gc_followCodeCacheReferences
mov      eax,   [esp]
call     near   ptr gc_followRoots
mov      eax,   [esp]
call     near   ptr gc_followStack
mov      eax,   [esp]
call     near   ptr gc_rescueEphemerons
Optimization: Linked send
GenerationalGC>>#collect
 self initLocals;
   ...
   purgeRoots;
   followCodeCacheReferences;
   followRoots;
   followStack;
   ...



call     near   ptr gc_GenerationalGC__purgeRoots
mov      eax,   [esp]
call     near   ptr gc_GenerationalGC__followCodeCacheReferences
mov      eax,   [esp]
call     near   ptr gc_GenerationalGC__followRoots
mov      eax,   [esp]
call     near   ptr gc_VMGarbageCollector__followStack
mov      eax,   [esp]
call     near   ptr gc_VMGarbageCollector__rescueEphemerons
_primitives (under primitives)

                                 SmalltalkBytecode subclass: #ExtensionBytecode




assembleUnrotate
  assembler rotate: 8




assembleIsSmallInteger
  | integer nonInteger |
  integer := assembler testAndJumpIfInteger.
  nonInteger := assembler loadConstant: false oop; shortJump.
  assembler
    jumpDestinationFor: integer;
    loadConstant: true oop;
    jumpDestinationFor: nonInteger
Optimization: Inlining _primitives
MarkAndCompactGC>>#setNewPositions: space
  ....
       [
         headerBits := reference _basicAt: 1.
         reference _basicAt: 1 put: newPosition _toObject.
         nextReference := headerBits _unrotate.
         nextReference _isSmallInteger]
         whileFalse: [reference := nextReference].
...


 mov      eax, [ecx+4]
 call     near ptr gc_unrotate
 mov      [ebp-18], eax
 mov      eax, [ebp-18]
 call     near ptr gc_isSmallInteger
Optimization: Inlining _primitives
MarkAndCompactGC>>#setNewPositions: space
  ....
       [
         headerBits := reference _basicAt: 1.
         reference _basicAt: 1 put: newPosition _toObject.
         nextReference := headerBits _unrotate.
         nextReference _isSmallInteger]
         whileFalse: [reference := nextReference].
...


 mov      eax, [ecx+4]
 rol      eax, 8                   ; assembler rotate: 8.
 mov      [ebp-18h], eax
 mov      eax, [ebp-18h]
 test     al, 1
 jnz      short integer            ; assembler testAndJumpIfInteger.
 mov      eax, offset false        ; assembler loadConstant: false oop;
 jmp      notInteger               ;     shortJump.
 mov      eax, offset true         ; assembler loadConstant: true oop.
Optimization: Inlining _primitives

                    SendSelectorBytecode subclass: #UnderPrimitiveSendBytecode



assemble
  selector := methodNativizer compiledMethod selectorAt: literalNumber.
  ^self mustInline
    ifTrue: [self inlineUnderPrimitive]
    ifFalse: [super assemble]

inlineUnderPrimitive
 ^(ExtensionBytecode for: selector using: assembler) assemble




ExtensionBytecode >> #assembleUnrotate
  assembler rotate: 8
Optimization: replaced primitives
VMArray   at: index
            ^contents at: index + 1

          add: object
            | position |
            position := self nextFree.
            position >= contents size ifTrue: [self grow].
            self
              nextFree: position + 1;
              at: position put: object

          at: index
            ^contents _basicAt: index + 1

          add: object
            | position |
            position := self nextFree.
            position >= contents _size ifTrue: [self grow].
            self
              nextFree: position + 1;
              at: position put: object
Instrumenting the GC

Stats (simple) examples:

  Max graph depth

  Coefficient of Stability

  Object size histogram
Instrumenting the GC
                 “simple” example



MarkAndCompactGC >> #compact: space
 self objectsFrom: space base to: space nextFree do: [:object |
   object _hasBeenSeenInSpace ifTrue: [| moved size |
     size := object _byteSize // 4 + 1.
     size > 1024 ifTrue: [size := 1025].
     stats at: size put: (stats at: size) + 1.
     moved := auxSpace shallowCopy: object.
     moved _beUnseenInSpace]]
Instrumenting the GC
             “simple” example


MarkAndCompactGC >> #currentStats: iWantAnyArray
^Current stats: iWantAnyArray



MarkAndCompactGC >> #stats: iWantAnyArray
 | answer |
 self loadSpaces.
 answer := oldSpace shallowCopy: stats contents.
 answer _basicAt: 0 put: (iWantAnyArray _basicAt: 0).
 answer _beUnseenInSpace.
 self saveSpaces.
 ^answer
Instrumenting the GC
                                 stats how to


Object subclass: #StatisticsHarvester
 instanceVariableNames: 'contents'




Object subclass: #StatisticsAnalyzer
 instanceVariableNames: 'harvester'
Instrumenting the GC
                                 stats how to




VMBuilder>>#buildAndInstallMarkAndCompact
 ...
 statisticsSpace := GCSpace externalNew: 1024 * 1024 * 4.
 gc statisticsOn: statisticsSpace.
 StatisticsHarvester currentContents: gc statisticsContents.
 ...




       statisticsSpace: shared between the GC and the image
Instrumenting the GC
                                 stats how to

                                         Object subclass: #VMGarbageCollector




initialize
  ...
  statistics := VMArray new.
  harvester := StatisticsHarvester new
Instrumenting the GC
                                stats how to

                                     Object subclass: #VMGarbageCollector




statisticsOn: space
  statistics on: space; emptyReserving: 1000.
  harvester on: statistics.
  ...
Instrumenting the GC
                                stats how to

                      LiteralNativizer class instanceVariableNames: ' ClassesToFreeze'



initializeClassesToFreeze
  ClassesToFreeze := (OrderedCollection new: 10)
    add: VMGarbageCollector;
    add: VMArray;
    add: GCSpace;
    add: GCSpaceInfo;
    add: ExternalAddress;
    add: SLLInfo;
    add: ResidueObject;
    add: SpaceStatisticsHarvester;
    asArray
Instrumenting the GC
                                stats how to

                      LiteralNativizer class instanceVariableNames: ' ClassesToFreeze'



initializeClassesToFreeze
  ClassesToFreeze := (OrderedCollection new: 10)
    add: VMGarbageCollector;
    add: VMArray;
    add: GCSpace;
    add: GCSpaceInfo;
    add: ExternalAddress;
    add: SLLInfo;
    add: ResidueObject;
    add: SpaceStatisticsHarvester;
    asArray
Instrumenting the GC
                            stability stats



   Stable

                              First moved object
Compacted



        stability"%" := firstMoved offset / oldSpace size

A high stability coefficient implies a high level of stability in the oldSpace.
                   The converse is not necessarily true
Instrumenting the GC
                                stability stats

                                   VMGarbageCollector subclass: #MarkAndCompactGC




compact: space
  self objectsFrom: space base to: space nextFree do: [:object |
    object _hasBeenSeenInSpace ifTrue: [| moved |
      moved := auxSpace shallowCopy: object.
      moved == object ifTrue: [ harvester firstMoved: object].
      moved _beUnseenInSpace]]
Instrumenting the GC
                                stability stats

                                   VMGarbageCollector subclass: #MarkAndCompactGC




compact: space
  self objectsFrom: space base to: space nextFree do: [:object |
    object _hasBeenSeenInSpace ifTrue: [| moved |
      moved := auxSpace shallowCopy: object.
      moved == object ifTrue: [ harvester firstMoved: object].
      moved _beUnseenInSpace]]
Instrumenting the GC
                                stability stats

                                  VMGarbageCollector subclass: #MarkAndCompactGC



decommitSlack
 oldSpace decommitSlack.
 harvester oldSpace: oldSpace
Instrumenting the GC
                                stability stats

                                  VMGarbageCollector subclass: #MarkAndCompactGC



decommitSlack
 oldSpace decommitSlack.
 harvester oldSpace: oldSpace
Instrumenting the GC
                                stability stats

                                   Object subclass: #StatisticsHarvester




oldSpace: space
  contents
    at: 1 put: space base;
    at: 2 put: space nextFree
Instrumenting the GC
                             graph depth stats

                                   VMGarbageCollector subclass: #MarkAndCompactGC




follow: root count: size startingAt: base
  [
    ... harvester graphDepth: stack size.
    stack isEmpty]
    whileFalse: [

     limit := stack pop.
     index := stack pop.
     objects := stack pop]
Instrumenting the GC
                            graph depth stats

                                    VMGarbageCollector subclass: #MarkAndCompactGC




follow: root count: size startingAt: base
  [
    ...
    stack isEmpty]
    whileFalse: [
      harvester graphDepth: stack size.
      limit := stack pop.
      index := stack pop.
      objects := stack pop]
Instrumenting the GC
                           graph depth stats

                                    Object subclass: #StatisticsHarvester




graphDepth: depth
  maxGraphDepth < depth ifTrue: [
   maxGraphDepth := depth.
   contents at: 4 put: maxGraphDepth]
Instrumenting the GC
              1.2


               1
stability




              0.8


              0.6


              0.4


              0.2


               0
                    1       2       3       4       5       6       7       8       9       10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

              5100

              5050
stack depth




              5000

              4950

              4900

              4850

              4800

              4750

              4700
                        1       2       3       4       5       6       7       8       9   10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
Alternate Scavenging algorithms

Z (leaf first?) scavenger
   15% faster
   Uses lots of memory

Queue based Breadth-first scavenging
  Mark and compact
  Generational

Cheney's algorithm
  Only for generational
  Uses semi-spaces to maintain queue
Alternate Scavenging algorithms

MarkAndCompactGC subclass: #ZMarkAndCompactGC
 instanceVariableNames: ''



MarkAndCompactGC subclass: #QueuedMarkAndCompactGC
 InstanceVariableNames: ' queue '



GenerationalGC subclass: #QueuedGenerationalGC
 InstanceVariableNames: ' queue '



GenerationalGC subclass: #CheneyGC
 instanceVariableNames: ' toBase oldBase '
Alternate Scavenging algorithms
                  tests
MarkAndcompactGCTest subclass: #ZMarkAndCompactGCTest
gcClass
  ^ZMarkAndCompactGC


MarkAndcompactGCTest subclass: #QueuedMarkAndCompactGCTest
gcClass
  ^QueuedMarkAndCompactGC


GenerationalGCTest subclass: #QueuedGenerationalGCTest
gcClass
  ^QueuedGenerationalGC


GenerationalGCTest subclass: #CheneyGCTest
gcClass
  ^QueuedGenerationalGC
Depth-first

GenerationalGC>>#follow: root count: size startingAt: base
     ...
         object _isProxy
           ifTrue: [objects _basicAt: index put: object _proxee]
           ifFalse: [| moved |
             stack push: limit; push: objects; push: index.
             moved := self moveToOldOrTo: object.
             objects _basicAt: index put: moved.
             self rememberIfWeak: moved.
             index := -1.
             limit := index + (self sizeToFollow: moved).
             objects := moved]]].
   stack isEmpty]
   whileFalse: [
     index := stack pop.
     objects := stack pop.
     limit := stack pop]
Z (leaf-first?)

QueuedGenerationalGC>>#follow: root count: size startingAt: base
    ...
        object _isProxy
          ifTrue: [objects _basicAt: index put: object _proxee]
          ifFalse: [| moved |

          moved := self moveToOldOrTo: object.
          objects _basicAt: index put: moved.
          self rememberIfWeak: moved.

           stack push: moved
                              ]]].
   stack isEmpty]
   whileFalse: [
     index := -1.
     objects := stack pop.
     limit := index + (self sizeToFollow: objects)]
Breadth-first

QueuedGenerationalGC>>#follow: root count: size startingAt: base
    ...
        object _isProxy
          ifTrue: [objects _basicAt: index put: object _proxee]
          ifFalse: [| moved |

          moved := self moveToOldOrTo: object.
          objects _basicAt: index put: moved.
          self rememberIfWeak: moved.

          queue push: moved
                             ]]].
   queue isEmpty]
   whileFalse: [
    index := -1.
    objects := queue popFirst.
    limit := index + (self sizeToFollow: objects)]
Cheney

CheneyGC>>#follow: root count: size startingAt: base
    ...
        object _isProxy
          ifTrue: [objects _basicAt: index put: object _proxee]
          ifFalse: [| moved |

           moved := self moveToOldOrTo: object.
           objects _basicAt: index put: moved.



                            ]]].



           Cheney, C. J. 1970. A nonrecursive list compacting algorithm.
                 Communications of the ACM. 13, 11, 677-678.
Cheney

remb   from     to   old
 set
                      .
                      .
                      .
                      .
                      .
Cheney

remb   from     to   old
 set
                      .
                      .
                      .
                      .
                      .
Cheney

remb    from                to   old
 set
                                  .
                                  .
                                  .
                                  .
                                  .




       "Two three fingers
Cheney

remb   from     to   old
 set
                      .
                      .
                      .
                      .
                      .
Cheney
followRoots
  super followRoots.
  self followAll




followStack
  super followStack.
  self followAll




rescueEphemeron: ephemeron
  super rescueEphemeron: ephemeron.
  self followAll
Cheney
                                       GenerationalGC subclass: #CheneyGC
                                        instanceVariableNames:
                                          ' toBase oldBase '




followAll
  [toBase < toSpace nextFree or: [oldBase < oldSpace nextFree]] whileTrue: [
    toBase := self followAllFrom: toSpace using: toBase.
    oldBase := self followAllFrom: oldSpace using: oldBase]




                           "Two three fingers scavenging”
Cheney
                                  GenerationalGC subclass: #CheneyGC
                                   instanceVariableNames:
                                     ' toBase oldBase '




loadSpaces
  super loadSpaces.
  toSpace reset.
  toBase := toSpace base.
  oldBase := oldSpace nextFree
Cheney



followAllFrom: space using: scanBase
  | base |
  base := scanBase.
  [base < space nextFree] whileTrue: [| object |
    object := (base + 8) _toObject.
    object _isExtended
      ifTrue: [
        base := object _basicSize * 4 + base.
        object := base _toObject]
      ifFalse: [base := base + 8].
    base := base + object _byteSize.
    self follow: object].
  ^base
What now?

.exe / .dll generation
JIT
Message dispatching
Object format
Memory management
   Object creation / copy
   GC
   Become
Primitives
   FFI
Processes
Callbacks
Publish paper
JIT + Generational + MarkAndCompact
[Audience hasQuestions] whileTrue: [
  self answer: Audience nextQuestion].

Audience do: [:you | self thank: you].

self returnTo: Audience

Contenu connexe

Tendances

Modelling and In-Database Management of Relational, Data-aware Processes
Modelling and In-Database Management of Relational, Data-aware ProcessesModelling and In-Database Management of Relational, Data-aware Processes
Modelling and In-Database Management of Relational, Data-aware Processes
Andrey Rivkin
 

Tendances (20)

Map kit light
Map kit lightMap kit light
Map kit light
 
Modelling and In-Database Management of Relational, Data-aware Processes
Modelling and In-Database Management of Relational, Data-aware ProcessesModelling and In-Database Management of Relational, Data-aware Processes
Modelling and In-Database Management of Relational, Data-aware Processes
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
RxSwift to Combine
RxSwift to CombineRxSwift to Combine
RxSwift to Combine
 
RxSwift to Combine
RxSwift to CombineRxSwift to Combine
RxSwift to Combine
 
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
Dlr
DlrDlr
Dlr
 
Powerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesPowerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best Practices
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
ReactiveCocoa in Practice
ReactiveCocoa in PracticeReactiveCocoa in Practice
ReactiveCocoa in Practice
 
Promise pattern
Promise patternPromise pattern
Promise pattern
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
 
A Crash Course on Serverless Applications in Python
A Crash Course on Serverless Applications in PythonA Crash Course on Serverless Applications in Python
A Crash Course on Serverless Applications in Python
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
 
An Introduction to Reactive Cocoa
An Introduction to Reactive CocoaAn Introduction to Reactive Cocoa
An Introduction to Reactive Cocoa
 
Angular and The Case for RxJS
Angular and The Case for RxJSAngular and The Case for RxJS
Angular and The Case for RxJS
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 

En vedette (8)

0330 다복솔2010 001[1]
0330 다복솔2010 001[1]0330 다복솔2010 001[1]
0330 다복솔2010 001[1]
 
RBuilder and ByteSurgeon
RBuilder and ByteSurgeonRBuilder and ByteSurgeon
RBuilder and ByteSurgeon
 
Stoop 305-reflective programming5
Stoop 305-reflective programming5Stoop 305-reflective programming5
Stoop 305-reflective programming5
 
Proposals for the Reborn Pharo Developer
Proposals for the Reborn Pharo DeveloperProposals for the Reborn Pharo Developer
Proposals for the Reborn Pharo Developer
 
Stoop 390-instruction stream
Stoop 390-instruction streamStoop 390-instruction stream
Stoop 390-instruction stream
 
Behavioral Reflection
Behavioral ReflectionBehavioral Reflection
Behavioral Reflection
 
Security on JIT
Security on JITSecurity on JIT
Security on JIT
 
Logic Lessons That Last Generations
Logic Lessons That Last GenerationsLogic Lessons That Last Generations
Logic Lessons That Last Generations
 

Similaire à GC in Smalltalk - Now What?

Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Paulo Ragonha
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
IndicThreads
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
vhazrati
 
Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0
SO
 

Similaire à GC in Smalltalk - Now What? (20)

NativeBoost
NativeBoostNativeBoost
NativeBoost
 
Writing native bindings to node.js in C++
Writing native bindings to node.js in C++Writing native bindings to node.js in C++
Writing native bindings to node.js in C++
 
Day 2
Day 2Day 2
Day 2
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved again
 
Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016Async Redux Actions With RxJS - React Rally 2016
Async Redux Actions With RxJS - React Rally 2016
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
 
High Performance Core Data
High Performance Core DataHigh Performance Core Data
High Performance Core Data
 
Cocoa heads 09112017
Cocoa heads 09112017Cocoa heads 09112017
Cocoa heads 09112017
 
Day 1
Day 1Day 1
Day 1
 
TensorFlow local Python XLA client
TensorFlow local Python XLA clientTensorFlow local Python XLA client
TensorFlow local Python XLA client
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Bottom Up
Bottom UpBottom Up
Bottom Up
 
Overview Of Lift Framework
Overview Of Lift FrameworkOverview Of Lift Framework
Overview Of Lift Framework
 
Overview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web FrameworkOverview of The Scala Based Lift Web Framework
Overview of The Scala Based Lift Web Framework
 
Scala based Lift Framework
Scala based Lift FrameworkScala based Lift Framework
Scala based Lift Framework
 
Lift 2 0
Lift 2 0Lift 2 0
Lift 2 0
 
JavaScript / Web Engineering / Web Development / html + css + js/presentation
JavaScript / Web Engineering / Web Development / html + css + js/presentationJavaScript / Web Engineering / Web Development / html + css + js/presentation
JavaScript / Web Engineering / Web Development / html + css + js/presentation
 

Plus de ESUG

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
ESUG
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
ESUG
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
ESUG
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
ESUG
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
ESUG
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
ESUG
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
ESUG
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
ESUG
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
ESUG
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
ESUG
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
ESUG
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
ESUG
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and Transformations
ESUG
 

Plus de ESUG (20)

Workshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programmingWorkshop: Identifying concept inventories in agile programming
Workshop: Identifying concept inventories in agile programming
 
Technical documentation support in Pharo
Technical documentation support in PharoTechnical documentation support in Pharo
Technical documentation support in Pharo
 
The Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and RoadmapThe Pharo Debugger and Debugging tools: Advances and Roadmap
The Pharo Debugger and Debugging tools: Advances and Roadmap
 
Sequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in PharoSequence: Pipeline modelling in Pharo
Sequence: Pipeline modelling in Pharo
 
Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...Migration process from monolithic to micro frontend architecture in mobile ap...
Migration process from monolithic to micro frontend architecture in mobile ap...
 
Analyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early resultsAnalyzing Dart Language with Pharo: Report and early results
Analyzing Dart Language with Pharo: Report and early results
 
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
Transpiling Pharo Classes to JS ECMAScript 5 versus ECMAScript 6
 
A Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test GenerationA Unit Test Metamodel for Test Generation
A Unit Test Metamodel for Test Generation
 
Creating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic ProgrammingCreating Unit Tests Using Genetic Programming
Creating Unit Tests Using Genetic Programming
 
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution ModesThreaded-Execution and CPS Provide Smooth Switching Between Execution Modes
Threaded-Execution and CPS Provide Smooth Switching Between Execution Modes
 
Exploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience ReportExploring GitHub Actions through EGAD: An Experience Report
Exploring GitHub Actions through EGAD: An Experience Report
 
Pharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIsPharo: a reflective language A first systematic analysis of reflective APIs
Pharo: a reflective language A first systematic analysis of reflective APIs
 
Garbage Collector Tuning
Garbage Collector TuningGarbage Collector Tuning
Garbage Collector Tuning
 
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame CaseImproving Performance Through Object Lifetime Profiling: the DataFrame Case
Improving Performance Through Object Lifetime Profiling: the DataFrame Case
 
Pharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and FuturePharo DataFrame: Past, Present, and Future
Pharo DataFrame: Past, Present, and Future
 
thisContext in the Debugger
thisContext in the DebuggerthisContext in the Debugger
thisContext in the Debugger
 
Websockets for Fencing Score
Websockets for Fencing ScoreWebsockets for Fencing Score
Websockets for Fencing Score
 
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScriptShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
ShowUs: PharoJS.org Develop in Pharo, Run on JavaScript
 
Advanced Object- Oriented Design Mooc
Advanced Object- Oriented Design MoocAdvanced Object- Oriented Design Mooc
Advanced Object- Oriented Design Mooc
 
A New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and TransformationsA New Architecture Reconciling Refactorings and Transformations
A New Architecture Reconciling Refactorings and Transformations
 

Dernier

EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 

Dernier (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 

GC in Smalltalk - Now What?

  • 1. GC in Smalltalk now what? Javier Burroni gera
  • 2. Smalltalk VM Writen in Smalltalk .exe / .dll generation JIT Message dispatching Object format Memory management Object creation / copy GC Become Primitives FFI Processes Callbacks etc
  • 3. What now? Optimizations Instrumentation Alternative GC Finish the VM (of course)
  • 4. Optimizations Monomorphic Inline Cache Linked sends Inline Underprimitives Replace primitives Many others with small impact
  • 5. Optimization: Linked send self _isSmallInteger ^false currentClass := self class Object >> #isNil currentClass == Object UndefinedObject >> #isNil currentClass == UndefinedObject currentClass := currentClass superclass ^false ^true
  • 6. Optimization: Linked send self _isSmallInteger ^false currentClass := self class Object >> #isNil currentClass == Object UndefinedObject >> #isNil currentClass == UndefinedObject currentClass := currentClass superclass ^false ^true
  • 7. Optimization: Linked send Object subclass: #SelectorMultiplexorNativizer for: aClass renderJumpTo: aCompiledMethod | reference | self disableCode: [assembler breakpoint]. assembler compareTempToConstant: aClass methodDictionaries oop; absoluteReferenceTo: aClass methodDictionaries; nearJumpIfEqual. reference := assembler relativeReferenceTo: aCompiledMethod fullName. reference noClassCheck.
  • 8. Optimization: Linked send Object subclass: #SelectorMultiplexorNativizer for: aClass renderJumpTo: aCompiledMethod | reference nextImplementation | self disableCode: [assembler breakpoint]. nextImplementation := assembler compareTempToConstant: aClass methodDictionaries oop; absoluteReferenceTo: aClass methodDictionaries; shortJumpIfNotEqual. self emitMonomorphicInlineCacheTo: aCompiledMethod. assembler nearJump. reference := assembler relativeReferenceTo: aCompiledMethod fullName. reference noClassCheck. assembler jumpDestinationFor: nextImplementat
  • 9. Optimization: Linked send Object subclass: #SelectorMultiplexorNativizer for: aClass renderJumpTo: aCompiledMethod | reference nextImplementation skipMic | self disableCode: [assembler breakpoint]. nextImplementation := assembler compareTempToConstant: aClass methodDictionaries oop; absoluteReferenceTo: aClass methodDictionaries; shortJumpIfNotEqual. skipMic := assembler compareArg; assembler shortJumpIfEqual. self emitMonomorphicInlineCacheTo: aCompiledMethod. assembler jumpDestinationFor: skipMic. assembler nearJump. reference := assembler relativeReferenceTo: aCompiledMethod fullName. reference noClassCheck. assembler jumpDestinationFor: nextImplementat
  • 10. Optimization: Linked send Object subclass: #SelectorMultiplexorNativizer emitMonomorphicInlineCacheTo: aCompiledMethod assembler loadEntrypoint: aCompiledMethod; patchClassCheck; patchCallSite
  • 11. Optimization: Linked send GenerationalGC>>#collect self initLocals; ... purgeRoots; followCodeCacheReferences; followRoots; followStack; ... call near ptr gc_purgeRoots mov eax, [esp] call near ptr gc_followCodeCacheReferences mov eax, [esp] call near ptr gc_followRoots mov eax, [esp] call near ptr gc_followStack mov eax, [esp] call near ptr gc_rescueEphemerons
  • 12. Optimization: Linked send GenerationalGC>>#collect self initLocals; ... purgeRoots; followCodeCacheReferences; followRoots; followStack; ... call near ptr gc_GenerationalGC__purgeRoots mov eax, [esp] call near ptr gc_GenerationalGC__followCodeCacheReferences mov eax, [esp] call near ptr gc_GenerationalGC__followRoots mov eax, [esp] call near ptr gc_VMGarbageCollector__followStack mov eax, [esp] call near ptr gc_VMGarbageCollector__rescueEphemerons
  • 13. _primitives (under primitives) SmalltalkBytecode subclass: #ExtensionBytecode assembleUnrotate assembler rotate: 8 assembleIsSmallInteger | integer nonInteger | integer := assembler testAndJumpIfInteger. nonInteger := assembler loadConstant: false oop; shortJump. assembler jumpDestinationFor: integer; loadConstant: true oop; jumpDestinationFor: nonInteger
  • 14. Optimization: Inlining _primitives MarkAndCompactGC>>#setNewPositions: space .... [ headerBits := reference _basicAt: 1. reference _basicAt: 1 put: newPosition _toObject. nextReference := headerBits _unrotate. nextReference _isSmallInteger] whileFalse: [reference := nextReference]. ... mov eax, [ecx+4] call near ptr gc_unrotate mov [ebp-18], eax mov eax, [ebp-18] call near ptr gc_isSmallInteger
  • 15. Optimization: Inlining _primitives MarkAndCompactGC>>#setNewPositions: space .... [ headerBits := reference _basicAt: 1. reference _basicAt: 1 put: newPosition _toObject. nextReference := headerBits _unrotate. nextReference _isSmallInteger] whileFalse: [reference := nextReference]. ... mov eax, [ecx+4] rol eax, 8 ; assembler rotate: 8. mov [ebp-18h], eax mov eax, [ebp-18h] test al, 1 jnz short integer ; assembler testAndJumpIfInteger. mov eax, offset false ; assembler loadConstant: false oop; jmp notInteger ; shortJump. mov eax, offset true ; assembler loadConstant: true oop.
  • 16. Optimization: Inlining _primitives SendSelectorBytecode subclass: #UnderPrimitiveSendBytecode assemble selector := methodNativizer compiledMethod selectorAt: literalNumber. ^self mustInline ifTrue: [self inlineUnderPrimitive] ifFalse: [super assemble] inlineUnderPrimitive ^(ExtensionBytecode for: selector using: assembler) assemble ExtensionBytecode >> #assembleUnrotate assembler rotate: 8
  • 17. Optimization: replaced primitives VMArray at: index ^contents at: index + 1 add: object | position | position := self nextFree. position >= contents size ifTrue: [self grow]. self nextFree: position + 1; at: position put: object at: index ^contents _basicAt: index + 1 add: object | position | position := self nextFree. position >= contents _size ifTrue: [self grow]. self nextFree: position + 1; at: position put: object
  • 18. Instrumenting the GC Stats (simple) examples: Max graph depth Coefficient of Stability Object size histogram
  • 19. Instrumenting the GC “simple” example MarkAndCompactGC >> #compact: space self objectsFrom: space base to: space nextFree do: [:object | object _hasBeenSeenInSpace ifTrue: [| moved size | size := object _byteSize // 4 + 1. size > 1024 ifTrue: [size := 1025]. stats at: size put: (stats at: size) + 1. moved := auxSpace shallowCopy: object. moved _beUnseenInSpace]]
  • 20. Instrumenting the GC “simple” example MarkAndCompactGC >> #currentStats: iWantAnyArray ^Current stats: iWantAnyArray MarkAndCompactGC >> #stats: iWantAnyArray | answer | self loadSpaces. answer := oldSpace shallowCopy: stats contents. answer _basicAt: 0 put: (iWantAnyArray _basicAt: 0). answer _beUnseenInSpace. self saveSpaces. ^answer
  • 21. Instrumenting the GC stats how to Object subclass: #StatisticsHarvester instanceVariableNames: 'contents' Object subclass: #StatisticsAnalyzer instanceVariableNames: 'harvester'
  • 22. Instrumenting the GC stats how to VMBuilder>>#buildAndInstallMarkAndCompact ... statisticsSpace := GCSpace externalNew: 1024 * 1024 * 4. gc statisticsOn: statisticsSpace. StatisticsHarvester currentContents: gc statisticsContents. ... statisticsSpace: shared between the GC and the image
  • 23. Instrumenting the GC stats how to Object subclass: #VMGarbageCollector initialize ... statistics := VMArray new. harvester := StatisticsHarvester new
  • 24. Instrumenting the GC stats how to Object subclass: #VMGarbageCollector statisticsOn: space statistics on: space; emptyReserving: 1000. harvester on: statistics. ...
  • 25. Instrumenting the GC stats how to LiteralNativizer class instanceVariableNames: ' ClassesToFreeze' initializeClassesToFreeze ClassesToFreeze := (OrderedCollection new: 10) add: VMGarbageCollector; add: VMArray; add: GCSpace; add: GCSpaceInfo; add: ExternalAddress; add: SLLInfo; add: ResidueObject; add: SpaceStatisticsHarvester; asArray
  • 26. Instrumenting the GC stats how to LiteralNativizer class instanceVariableNames: ' ClassesToFreeze' initializeClassesToFreeze ClassesToFreeze := (OrderedCollection new: 10) add: VMGarbageCollector; add: VMArray; add: GCSpace; add: GCSpaceInfo; add: ExternalAddress; add: SLLInfo; add: ResidueObject; add: SpaceStatisticsHarvester; asArray
  • 27. Instrumenting the GC stability stats Stable First moved object Compacted stability"%" := firstMoved offset / oldSpace size A high stability coefficient implies a high level of stability in the oldSpace. The converse is not necessarily true
  • 28. Instrumenting the GC stability stats VMGarbageCollector subclass: #MarkAndCompactGC compact: space self objectsFrom: space base to: space nextFree do: [:object | object _hasBeenSeenInSpace ifTrue: [| moved | moved := auxSpace shallowCopy: object. moved == object ifTrue: [ harvester firstMoved: object]. moved _beUnseenInSpace]]
  • 29. Instrumenting the GC stability stats VMGarbageCollector subclass: #MarkAndCompactGC compact: space self objectsFrom: space base to: space nextFree do: [:object | object _hasBeenSeenInSpace ifTrue: [| moved | moved := auxSpace shallowCopy: object. moved == object ifTrue: [ harvester firstMoved: object]. moved _beUnseenInSpace]]
  • 30. Instrumenting the GC stability stats VMGarbageCollector subclass: #MarkAndCompactGC decommitSlack oldSpace decommitSlack. harvester oldSpace: oldSpace
  • 31. Instrumenting the GC stability stats VMGarbageCollector subclass: #MarkAndCompactGC decommitSlack oldSpace decommitSlack. harvester oldSpace: oldSpace
  • 32. Instrumenting the GC stability stats Object subclass: #StatisticsHarvester oldSpace: space contents at: 1 put: space base; at: 2 put: space nextFree
  • 33. Instrumenting the GC graph depth stats VMGarbageCollector subclass: #MarkAndCompactGC follow: root count: size startingAt: base [ ... harvester graphDepth: stack size. stack isEmpty] whileFalse: [ limit := stack pop. index := stack pop. objects := stack pop]
  • 34. Instrumenting the GC graph depth stats VMGarbageCollector subclass: #MarkAndCompactGC follow: root count: size startingAt: base [ ... stack isEmpty] whileFalse: [ harvester graphDepth: stack size. limit := stack pop. index := stack pop. objects := stack pop]
  • 35. Instrumenting the GC graph depth stats Object subclass: #StatisticsHarvester graphDepth: depth maxGraphDepth < depth ifTrue: [ maxGraphDepth := depth. contents at: 4 put: maxGraphDepth]
  • 36. Instrumenting the GC 1.2 1 stability 0.8 0.6 0.4 0.2 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 5100 5050 stack depth 5000 4950 4900 4850 4800 4750 4700 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  • 37. Alternate Scavenging algorithms Z (leaf first?) scavenger 15% faster Uses lots of memory Queue based Breadth-first scavenging Mark and compact Generational Cheney's algorithm Only for generational Uses semi-spaces to maintain queue
  • 38. Alternate Scavenging algorithms MarkAndCompactGC subclass: #ZMarkAndCompactGC instanceVariableNames: '' MarkAndCompactGC subclass: #QueuedMarkAndCompactGC InstanceVariableNames: ' queue ' GenerationalGC subclass: #QueuedGenerationalGC InstanceVariableNames: ' queue ' GenerationalGC subclass: #CheneyGC instanceVariableNames: ' toBase oldBase '
  • 39. Alternate Scavenging algorithms tests MarkAndcompactGCTest subclass: #ZMarkAndCompactGCTest gcClass ^ZMarkAndCompactGC MarkAndcompactGCTest subclass: #QueuedMarkAndCompactGCTest gcClass ^QueuedMarkAndCompactGC GenerationalGCTest subclass: #QueuedGenerationalGCTest gcClass ^QueuedGenerationalGC GenerationalGCTest subclass: #CheneyGCTest gcClass ^QueuedGenerationalGC
  • 40. Depth-first GenerationalGC>>#follow: root count: size startingAt: base ... object _isProxy ifTrue: [objects _basicAt: index put: object _proxee] ifFalse: [| moved | stack push: limit; push: objects; push: index. moved := self moveToOldOrTo: object. objects _basicAt: index put: moved. self rememberIfWeak: moved. index := -1. limit := index + (self sizeToFollow: moved). objects := moved]]]. stack isEmpty] whileFalse: [ index := stack pop. objects := stack pop. limit := stack pop]
  • 41. Z (leaf-first?) QueuedGenerationalGC>>#follow: root count: size startingAt: base ... object _isProxy ifTrue: [objects _basicAt: index put: object _proxee] ifFalse: [| moved | moved := self moveToOldOrTo: object. objects _basicAt: index put: moved. self rememberIfWeak: moved. stack push: moved ]]]. stack isEmpty] whileFalse: [ index := -1. objects := stack pop. limit := index + (self sizeToFollow: objects)]
  • 42. Breadth-first QueuedGenerationalGC>>#follow: root count: size startingAt: base ... object _isProxy ifTrue: [objects _basicAt: index put: object _proxee] ifFalse: [| moved | moved := self moveToOldOrTo: object. objects _basicAt: index put: moved. self rememberIfWeak: moved. queue push: moved ]]]. queue isEmpty] whileFalse: [ index := -1. objects := queue popFirst. limit := index + (self sizeToFollow: objects)]
  • 43. Cheney CheneyGC>>#follow: root count: size startingAt: base ... object _isProxy ifTrue: [objects _basicAt: index put: object _proxee] ifFalse: [| moved | moved := self moveToOldOrTo: object. objects _basicAt: index put: moved. ]]]. Cheney, C. J. 1970. A nonrecursive list compacting algorithm. Communications of the ACM. 13, 11, 677-678.
  • 44. Cheney remb from to old set . . . . .
  • 45. Cheney remb from to old set . . . . .
  • 46. Cheney remb from to old set . . . . . "Two three fingers
  • 47. Cheney remb from to old set . . . . .
  • 48. Cheney followRoots super followRoots. self followAll followStack super followStack. self followAll rescueEphemeron: ephemeron super rescueEphemeron: ephemeron. self followAll
  • 49. Cheney GenerationalGC subclass: #CheneyGC instanceVariableNames: ' toBase oldBase ' followAll [toBase < toSpace nextFree or: [oldBase < oldSpace nextFree]] whileTrue: [ toBase := self followAllFrom: toSpace using: toBase. oldBase := self followAllFrom: oldSpace using: oldBase] "Two three fingers scavenging”
  • 50. Cheney GenerationalGC subclass: #CheneyGC instanceVariableNames: ' toBase oldBase ' loadSpaces super loadSpaces. toSpace reset. toBase := toSpace base. oldBase := oldSpace nextFree
  • 51. Cheney followAllFrom: space using: scanBase | base | base := scanBase. [base < space nextFree] whileTrue: [| object | object := (base + 8) _toObject. object _isExtended ifTrue: [ base := object _basicSize * 4 + base. object := base _toObject] ifFalse: [base := base + 8]. base := base + object _byteSize. self follow: object]. ^base
  • 52. What now? .exe / .dll generation JIT Message dispatching Object format Memory management Object creation / copy GC Become Primitives FFI Processes Callbacks Publish paper JIT + Generational + MarkAndCompact
  • 53. [Audience hasQuestions] whileTrue: [ self answer: Audience nextQuestion]. Audience do: [:you | self thank: you]. self returnTo: Audience