Class { #name : 'PPProfilingContext', #superclass : 'PPContext', #instVars : [ 'invocations', 'totalSize', 'positions', 'parsers', 'events', 'fEvents', 'fPositions', 'fParsers', 'colors', 'lastStreamIndex' ], #category : 'PetitCompiler-Context' } { #category : 'converting' } PPProfilingContext >> asEventMorph [ ^ self asEventMorph: events asIdentitySet asArray ] { #category : 'converting' } PPProfilingContext >> asEventMorph: eventArray [ | width height canvas morph | fPositions := OrderedCollection new. fEvents := OrderedCollection new. fParsers := 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). fParsers addLast: (self parsers 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' } PPProfilingContext >> asFrequencyTable [ | bag total result | bag := parsers 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' } PPProfilingContext >> asReportTable [ ^ { #'backtrack per character' -> (self restoreCount / (self totalSize + 1.0)). #'total stream size' -> self streamSize. #'remember count' -> self rememberCount. #'restore count' -> self restoreCount. } ] { #category : 'converting' } PPProfilingContext >> colorForEvent: event [ | eventSet | colors isNil ifTrue: [ eventSet := events asIdentitySet asArray. colors := RTMultiLinearColorForIdentity new objects: eventSet. ]. ^ colors rtValue: event " event == #islandInvoke ifTrue: [ ^ Color purple lighter ]. event == #islandMemoized ifTrue: [ ^ Color red lighter ]. event == #islandMemoHit ifTrue: [ ^ Color green darker ]. event == #waterToken ifTrue: [ ^ Color blue ]. event == #remember ifTrue: [ ^ Color green ]. event == #restore ifTrue: [ ^ Color red ]. ^ Color yellow." ] { #category : 'reporting' } PPProfilingContext >> countFor: event [ ^ (events asBag select: [ :e | e == event ]) size ] { #category : 'private' } PPProfilingContext >> event: value [ positions addLast: self position. parsers addLast: self parser. events addLast: value. ] { #category : 'accessing' } PPProfilingContext >> events [ ^ events ] { #category : 'gt' } PPProfilingContext >> eventsIn: composite [ composite morph title: 'Parsing Events'; display: [:result :sample :context :parser | | morph | morph := ScrollPane new. morph color: Color white. morph scroller addMorph: self asEventMorph. morph ] ] { #category : 'gt' } PPProfilingContext >> 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' } PPProfilingContext >> initialize [ super initialize. events := OrderedCollection new. positions := OrderedCollection new. parsers := OrderedCollection new. colors := nil. totalSize := 0. ] { #category : 'gt' } PPProfilingContext >> 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' } PPProfilingContext >> islandInvoke [ self event: #islandInvoke ] { #category : 'events' } PPProfilingContext >> islandMemoHit [ self event: #islandMemoHit ] { #category : 'events' } PPProfilingContext >> islandMemoized [ self event: #islandMemoized ] { #category : 'converting' } PPProfilingContext >> 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: (fParsers at: location y). ] ] { #category : 'events' } PPProfilingContext >> next [ self event: #step. ^ super next ] { #category : 'events' } PPProfilingContext >> next: number [ self event: #step. ^ super next: number ] { #category : 'private' } PPProfilingContext >> parser [ ^ (thisContext findContextSuchThat: [ :ctxt | ctxt receiver isKindOf: PPParser ]) ifNil: [ nil ] ifNotNil: [ :aContext | aContext receiver ]. ] { #category : 'accessing' } PPProfilingContext >> parsers [ ^ parsers ] { #category : 'accessing' } PPProfilingContext >> positions [ ^ positions ] { #category : 'events' } PPProfilingContext >> remember [ self event: #remember. ^ super remember ] { #category : 'reporting' } PPProfilingContext >> rememberCount [ ^ (events asBag select: [ :e | e == #remember ]) size ] { #category : 'initialization' } PPProfilingContext >> reset [ super reset ] { #category : 'events' } PPProfilingContext >> restore: whatever [ self event: #restore. ^ super restore: whatever ] { #category : 'reporting' } PPProfilingContext >> restoreCount [ ^ (events asBag select: [ :e | e == #restore ]) size ] { #category : 'accessing' } PPProfilingContext >> stream: aStream [ totalSize := totalSize + aStream size. lastStreamIndex := events size. ^ super stream: aStream ] { #category : 'accessing' } PPProfilingContext >> streamSize [ ^ stream size ] { #category : 'gt' } PPProfilingContext >> tallyIn: composite [ composite table title: 'Tally'; column: 'Parser' evaluated: [ :each | each first displayName ]; column: 'Count' evaluated: [ :each | each second printString ]; column: 'Percentage (%)' evaluated: [ :each | each third printString ]; display: [ self asFrequencyTable ]; noSelection; showOnly: 50 ] { #category : 'accessing' } PPProfilingContext >> totalSize [ ^ totalSize ] { #category : 'events' } PPProfilingContext >> waterToken [ self event: #waterToken ]