PetitCommonMark/software/petitcompiler/PPCProfilingContext.class.st

385 lines
9.3 KiB
Smalltalk

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 [
<gtInspectorPresentationOrder: 30>
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 [
<gtInspectorPresentationOrder: 40>
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 [
<gtInspectorPresentationOrder: 30>
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 [
<gtInspectorPresentationOrder: 34>
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 [
<gtInspectorPresentationOrder: 35>
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
]