385 lines
9.3 KiB
Smalltalk
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
|
|
]
|