Class { #name : 'PPCProfilingContext', #superclass : 'PPCContext', #instVars : [ 'totalSize', 'selectors', 'positions', 'events', 'colors', 'fPositions', 'fEvents', 'lastStreamIndex', 'fSelectors' ], #category : 'PetitCompiler-Context' } { #category : 'converting' } PPCProfilingContext >> asEventMorph [ ^ self asEventMorph: events asIdentitySet asArray ] { #category : 'converting' } PPCProfilingContext >> asEventMorph: eventArray [ | width height canvas morph | fPositions := OrderedCollection new. fEvents := OrderedCollection new. fSelectors := OrderedCollection new. "for the last stream only" ((lastStreamIndex + 1) to: events size) do: [ :index | | e | e := events at: index. (eventArray includes: e) ifTrue: [ fPositions addLast: (self positions at: index). fSelectors addLast: (self selectors at: index). fEvents addLast: e. ] ]. width := self stream size + 1 min: 4096. height := fPositions size min: 32768. canvas := FormCanvas extent: width @ height. self contents keysAndValuesDo: [ :index :char | char isSeparator ifFalse: [ canvas line: index @ 1 to: index @ height color: Color paleYellow lighter ] ]. 1 to: height do: [ :index | canvas form colorAt: (fPositions at: index) @ index put: (self colorForEvent: (fEvents at: index)) ]. morph := canvas form asMorph. morph on: #mouseMove send: #mouseDown:with: to: self. ^ morph ] { #category : 'converting' } PPCProfilingContext >> asFrequencyTable [ | bag total result | bag := selectors asBag. result := OrderedCollection new. bag isEmpty ifTrue: [ ^ result ]. total := 100.0 / bag size. bag sortedCounts do: [ :each | result addLast: (Array with: each value with: each key with: total * each key) ]. ^ result ] { #category : 'converting' } PPCProfilingContext >> asFrequencyTableForEvent: event [ | bag total result filtered | filtered := OrderedCollection new. events with: selectors do: [ :e :selector | event == e ifTrue: [ filtered add: selector ] ]. bag := filtered asBag. result := OrderedCollection new. bag isEmpty ifTrue: [ ^ result ]. total := 100.0 / bag size. bag sortedCounts do: [ :each | result addLast: (Array with: each value with: each key with: total * each key) ]. ^ result ] { #category : 'converting' } PPCProfilingContext >> asReportTable [ ^{ #'lwBacktrack per character' -> (self lwRestoreCount / (totalSize + 1.0)). #'backtrack per character' -> (self restoreCount / (totalSize + 1.0)). #'total stream size' -> totalSize . #'lwRemember count' -> self lwRememberCount. #'lwRestore count' -> self lwRestoreCount. #'remember count' -> self rememberCount. #'restore count' -> self restoreCount. #'token read count' -> self tokenReadCount. #'islands invoked' -> (self countFor: #islandInvoke). #'islands memoized' -> (self countFor: #islandMemoized). #'islands memo hits' -> (self countFor: #islandMemoHit). } ] { #category : 'converting' } PPCProfilingContext >> colorForEvent: event [ | eventSet | colors isNil ifTrue: [ eventSet := events asIdentitySet asArray. colors := RTMultiLinearColorForIdentity new objects: eventSet. ]. ^ colors rtValue: event ] { #category : 'reporting' } PPCProfilingContext >> countFor: event [ ^ (events select: [ :e | e == event ]) size ] { #category : 'private' } PPCProfilingContext >> event: value [ positions addLast: self position. selectors addLast: self selector. events addLast: value. ] { #category : 'accessing' } PPCProfilingContext >> events [ ^ events ] { #category : 'gt' } PPCProfilingContext >> eventsIn: composite [ composite morph title: 'Parsing Events'; display: [:result :sample :stream :parser | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: self asEventMorph. morph ] ] { #category : 'gt' } PPCProfilingContext >> gtReport: composite [ composite table title: 'Report'; column: 'Info' evaluated: [ :each | each key printString ]; column: 'Value' evaluated: [ :each | each value printString ]; display: [:context | context asReportTable ]. ] { #category : 'initialization' } PPCProfilingContext >> initialize [ super initialize. self reset. ] { #category : 'reporting' } PPCProfilingContext >> invocationCount [ ^ self countFor: #methodInvoked ] { #category : 'accessing' } PPCProfilingContext >> invokedMethods [ | methods | methods := OrderedCollection new. events withIndexDo: [ :event :index | (event == #methodInvoked) ifTrue: [ methods add: (selectors at: index) ] ]. ^ methods ] { #category : 'gt' } PPCProfilingContext >> islandEventsIn: composite [ composite morph title: 'Island Events'; display: [:result :sample :context :parser | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: (self asEventMorph: #(#islandInvoke #islandMemoHit #islandMemoized #waterToken)). morph ] ] { #category : 'events' } PPCProfilingContext >> islandInvoke [ self event: #islandInvoke ] { #category : 'events' } PPCProfilingContext >> islandMemoHit [ self event: #islandMemoHit ] { #category : 'events' } PPCProfilingContext >> islandMemoized [ self event: #islandMemoized ] { #category : 'events' } PPCProfilingContext >> lwRemember [ self event: #lwRemember. ^ super lwRemember ] { #category : 'reporting' } PPCProfilingContext >> lwRememberCount [ ^ (events asBag select: [ :e | e == #lwRemember ]) size ] { #category : 'events' } PPCProfilingContext >> lwRestore: whatever [ self event: #lwRestore. ^ super lwRestore: whatever. ] { #category : 'reporting' } PPCProfilingContext >> lwRestoreCount [ ^ (events asBag select: [ :e | e == #lwRestore ]) size ] { #category : 'events' } PPCProfilingContext >> methodFinished: selector [ "Nothing to do for now" self event: #methodFinished. ] { #category : 'events' } PPCProfilingContext >> methodInvoked: selector [ self event: #methodInvoked ] { #category : 'converting' } PPCProfilingContext >> mouseDown: anEvent with: aMorph [ | location event | location := anEvent position. (location y < fEvents size and: [ location y > 0 ]) ifTrue: [ event := fEvents at: location y. Transcript cr; show: event; show: ': '; show: (fSelectors at: location y). ] ] { #category : 'events' } PPCProfilingContext >> next [ self event: #step. ^ super next ] { #category : 'events' } PPCProfilingContext >> next: number [ self event: #step. ^ super next: number ] { #category : 'accessing' } PPCProfilingContext >> position: value [ self assert: value isInteger. super position: value ] { #category : 'accessing' } PPCProfilingContext >> positions [ ^ positions ] { #category : 'events' } PPCProfilingContext >> remember [ self event: #remember. ^ super remember ] { #category : 'reporting' } PPCProfilingContext >> rememberCount [ ^ (events asBag select: [ :e | e == #remember ]) size ] { #category : 'gt' } PPCProfilingContext >> rememberTallyIn: composite [ composite table title: 'Remember Tally'; column: 'Selector/Parser' evaluated: [ :each | each first printString ]; column: 'Count' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [ self asFrequencyTableForEvent: #remember ]; noSelection; showOnly: 50 ] { #category : 'initialization' } PPCProfilingContext >> reset [ super reset. events := OrderedCollection new. positions := OrderedCollection new. selectors := OrderedCollection new. colors := nil. totalSize := 0. ] { #category : 'events' } PPCProfilingContext >> restore: whatever [ self event: #restore. ^ super restore: whatever ] { #category : 'reporting' } PPCProfilingContext >> restoreCount [ ^ (events asBag select: [ :e | e == #restore ]) size ] { #category : 'private' } PPCProfilingContext >> selector [ self flag: 'JK: this method needs review...'. ^ (thisContext findContextSuchThat: [ :ctxt | (ctxt receiver isKindOf: PPParser) or: [ ctxt receiver isKindOf: PPCDistinctScanner ] ]) ifNil: [ nil ] ifNotNil: [ :aContext | ((aContext receiver isKindOf: PPCompiledParser) or: [aContext receiver isKindOf: PPCDistinctScanner]) ifTrue: [ aContext selector ] ifFalse: [ aContext receiver ] ]. ] { #category : 'accessing' } PPCProfilingContext >> selectors [ ^ selectors ] { #category : 'accessing' } PPCProfilingContext >> stream: aStream [ totalSize := totalSize + aStream size. lastStreamIndex := events size. ^ super stream: aStream ] { #category : 'gt' } PPCProfilingContext >> tallyIn: composite [ composite table title: 'Global Tally'; column: 'Selector/Parser' evaluated: [ :each | each first printString ]; column: 'Count' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [ self asFrequencyTable ]; noSelection; showOnly: 50 ] { #category : 'events' } PPCProfilingContext >> tokenRead: tokenName [ self event: #tokenRead ] { #category : 'reporting' } PPCProfilingContext >> tokenReadCount [ ^ self countFor: #tokenRead ] { #category : 'accessing' } PPCProfilingContext >> totalSize [ ^ totalSize ] { #category : 'events' } PPCProfilingContext >> waterToken [ self event: #waterToken ]