Load tools.profiler.sampling from bootstrap/tools instead.
"tools.disassembler"
"tools.dispatch"
"tools.memory"
- "tools.profiler.counting"
+ "tools.profiler.sampling"
"tools.test"
"tools.time"
"tools.threads"
{ $heading "Performance" }
{ $subsections
"timing"
- "tools.profiler.counting"
+ "tools.profiler.sampling"
"tools.memory"
"tools.threads"
"tools.destructors"
"tools.dispatch"
"tools.errors"
"tools.memory"
- "tools.profiler.counting"
+ "tools.profiler.sampling"
"tools.test"
"tools.threads"
"tools.time"
combinators.short-circuit locals locals.backend locals.types
combinators.private stack-checker.values generic.single
generic.single.private alien.libraries tools.dispatch.private
-macros
+macros tools.profiler.sampling.private
stack-checker.alien
stack-checker.state
stack-checker.errors
stack-checker.recursive-state
stack-checker.row-polymorphism ;
QUALIFIED-WITH: generic.single.private gsp
-QUALIFIED-WITH: tools.profiler.counting.private counting
-QUALIFIED-WITH: tools.profiler.sampling.private sampling
IN: stack-checker.known-words
: infer-special ( word -- )
\ modify-code-heap { array object object } { } define-primitive
\ nano-count { } { integer } define-primitive \ nano-count make-flushable
\ optimized? { word } { object } define-primitive
-\ counting:profiling { object } { } define-primitive
-\ sampling:profiling { object } { } define-primitive
-\ sampling:(get-samples) { } { object } define-primitive
-\ sampling:(clear-samples) { } { } define-primitive
+\ profiling { object } { } define-primitive
+\ (get-samples) { } { object } define-primitive
+\ (clear-samples) { } { } define-primitive
\ quot-compiled? { quotation } { object } define-primitive
\ quotation-code { quotation } { integer integer } define-primitive \ quotation-code make-flushable
\ reset-dispatch-stats { } { } define-primitive
HELP: add-timing
{ $values { "word" word } }
{ $description "Adds timing code to a word, which records its total running time, including that of words it calls, on every invocation." }
-{ $see-also "timing" "tools.profiler.counting" } ;
+{ $see-also "timing" "tools.profiler.sampling" } ;
HELP: reset-word-timing
{ $description "Resets the word timing table." } ;
+++ /dev/null
-Slava Pestov
+++ /dev/null
-USING: tools.profiler.counting.private tools.time tools.crossref
-help.markup help.syntax quotations io strings words definitions ;
-IN: tools.profiler.counting
-
-ARTICLE: "profiler-limitations" "Profiler limitations"
-"Certain optimizations performed by the compiler can inhibit accurate call counting:"
-{ $list
- "Calls to open-coded intrinsics are not counted. Certain words are open-coded as inline machine code, and in some cases optimized out altogether; this includes stack shuffling operations, conditionals, and many object allocation operations."
- { "Calls to " { $link POSTPONE: inline } " words are not counted." }
- { "Calls to methods which were inlined as a result of type inference are not counted." }
- "Tail-recursive loops will only count the initial invocation of the word, not every tail call."
-} ;
-
-ARTICLE: "tools.profiler.counting" "Call-counting profiler"
-"The " { $vocab-link "tools.profiler.counting" } " vocabulary implements a simple call counting profiler."
-$nl
-"Quotations can be passed to a combinator which calls them with the profiler enabled:"
-{ $subsections profile }
-"After a quotation has been profiled, call counts can be presented in various ways:"
-{ $subsections
- profile.
- vocab-profile.
- usage-profile.
- vocabs-profile.
- method-profile.
- "profiler-limitations"
-}
-{ $see-also "ui.tools.profiler" "tools.annotations" "timing" } ;
-
-ABOUT: "tools.profiler.counting"
-
-HELP: counters
-{ $values { "words" "a sequence of words" } { "alist" "an association list mapping words to integers" } }
-{ $description "Outputs an association list of word call counts." } ;
-
-HELP: counters.
-{ $values { "assoc" "an association list mapping words to integers" } }
-{ $description "Prints an association list of call counts to " { $link output-stream } "." } ;
-
-HELP: profile
-{ $values { "quot" quotation } }
-{ $description "Calls the quotation while collecting word call counts, which can then be displayed using " { $link profile. } " or related words." } ;
-
-HELP: profile.
-{ $description "Prints a table of call counts from the most recent invocation of " { $link profile } "." } ;
-
-HELP: vocab-profile.
-{ $values { "vocab" string } }
-{ $description "Prints a table of call counts from the most recent invocation of " { $link profile } ", for words in the " { $snippet "vocab" } " vocabulary only." }
-{ $examples { $code "\"math\" vocab-profile." } } ;
-
-HELP: usage-profile.
-{ $values { "word" word } }
-{ $description "Prints a table of call counts from the most recent invocation of " { $link profile } ", for words which directly call " { $snippet "word" } " only." }
-{ $notes "This word obtains the list of static usages with the " { $link smart-usage } " word, and is not aware of dynamic call history. Consider the following scenario. A word " { $snippet "X" } " can execute word " { $snippet "Y" } " in a conditional branch, and " { $snippet "X" } " is executed many times during the profiling run, but this particular branch executing " { $snippet "Y" } " is never taken. However, some other word does execute " { $snippet "Y" } " multiple times. Then " { $snippet "\\ Y usage-profile." } " will list a number of calls to " { $snippet "X" } ", even though " { $snippet "Y" } " was never executed " { $emphasis "from" } " " { $snippet "X" } "." }
-{ $examples { $code "\\ + usage-profile." } } ;
-
-HELP: vocabs-profile.
-{ $description "Print a table of cumilative call counts for each vocabulary. Vocabularies whose words were not called are supressed from the output." } ;
-
-HELP: method-profile.
-{ $description "Print a table of cumilative call counts for each method. Methods which were not called are supressed from the output." } ;
-
-HELP: profiling
-{ $values { "?" "a boolean" } }
-{ $description "Internal primitive to switch on call counting. This word should not be used; instead use " { $link profile } "." } ;
-
-{ time profile } related-words
+++ /dev/null
-USING: accessors tools.profiler.counting tools.test kernel memory math
-threads alien alien.c-types tools.profiler.counting.private sequences
-compiler.test compiler.units words arrays ;
-IN: tools.profiler.counting.tests
-
-[ t ] [
- \ length counter>>
- 10 [ { } length drop ] times
- \ length counter>> =
-] unit-test
-
-[ ] [ [ 3 [ gc ] times ] profile ] unit-test
-
-[ ] [ [ 1000000 sleep ] profile ] unit-test
-
-[ ] [ profile. ] unit-test
-
-[ ] [ vocabs-profile. ] unit-test
-
-[ ] [ "kernel.private" vocab-profile. ] unit-test
-
-[ ] [ \ + usage-profile. ] unit-test
-
-: callback-test ( -- callback ) void { } cdecl [ ] alien-callback ;
-
-: indirect-test ( callback -- ) void { } cdecl alien-indirect ;
-
-: foobar ( -- ) ;
-
-[
- [ ] [ callback-test indirect-test ] unit-test
- foobar
-] profile
-
-[ 1 ] [ \ foobar counter>> ] unit-test
-
-: fooblah ( -- ) { } [ ] like call( -- ) ;
-
-: foobaz ( -- ) fooblah fooblah ;
-
-[ foobaz ] profile
-
-[ 1 ] [ \ foobaz counter>> ] unit-test
-
-[ 2 ] [ \ fooblah counter>> ] unit-test
-
-: recompile-while-profiling-test ( -- ) ;
-
-[ ] [
- [
- 333 [ recompile-while-profiling-test ] times
- { recompile-while-profiling-test } compile
- 333 [ recompile-while-profiling-test ] times
- ] profile
-] unit-test
-
-[ 666 ] [ \ recompile-while-profiling-test counter>> ] unit-test
-
-[ ] [ [ [ ] compile-call ] profile ] unit-test
-
-[ [ gensym execute ] profile ] [ undefined? ] must-fail-with
-
-: crash-bug-1 ( -- x ) "hi" <uninterned-word> ;
-: crash-bug-2 ( -- ) 100000 [ crash-bug-1 drop ] times ;
-
-[ ] [ [ crash-bug-2 ] profile ] unit-test
-
-[ 1 ] [
- [
- [ [ ] ( -- ) define-temp ] with-compilation-unit
- dup execute( -- )
- ] profile
- counter>>
-] unit-test
-
-! unwind_native_frames() would fail if profiling was enabled
-! because the jit-profiling stub would clobber a parameter register
-! on x86-64
-[ [ -10 f <array> ] profile ] must-fail
+++ /dev/null
-! Copyright (C) 2007, 2010 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors words sequences math prettyprint kernel arrays
-io io.styles namespaces assocs kernel.private strings
-combinators sorting math.parser vocabs definitions
-tools.profiler.counting.private tools.crossref continuations generic
-compiler.units compiler.crossref sets classes fry ;
-FROM: sets => members ;
-IN: tools.profiler.counting
-
-: profile ( quot -- )
- [ t profiling call ] [ f profiling ] [ ] cleanup ; inline
-
-: filter-counts ( alist -- alist' )
- [ second 0 > ] filter ;
-
-: map-counters ( obj quot -- alist )
- { } map>assoc filter-counts ; inline
-
-: counters ( words -- alist )
- [ dup counter>> ] map-counters ;
-
-: cumulative-counters ( obj quot -- alist )
- '[ dup @ [ counter>> ] map-sum ] map-counters ; inline
-
-: vocab-counters ( -- alist )
- vocabs [ words [ predicate? not ] filter ] cumulative-counters ;
-
-: generic-counters ( -- alist )
- all-words [ subwords ] cumulative-counters ;
-
-: methods-on ( class -- methods )
- dup implementors [ lookup-method ] with map ;
-
-: class-counters ( -- alist )
- classes [ methods-on ] cumulative-counters ;
-
-: method-counters ( -- alist )
- all-words [ subwords ] map concat counters ;
-
-: profiler-usage ( word -- words )
- [ smart-usage [ word? ] filter ]
- [ generic-call-sites-of keys ]
- [ effect-dependencies-of keys ]
- tri 3append members ;
-
-: usage-counters ( word -- alist )
- profiler-usage counters ;
-
-: counters. ( assoc -- )
- sort-values simple-table. ;
-
-: profile. ( -- )
- "Call counts for all words:" print
- all-words counters counters. ;
-
-: vocab-profile. ( vocab -- )
- "Call counts for words in the " write
- dup dup lookup-vocab write-object
- " vocabulary:" print
- words counters counters. ;
-
-: usage-profile. ( word -- )
- "Call counts for words which call " write
- dup pprint
- ":" print
- usage-counters counters. ;
-
-: vocabs-profile. ( -- )
- "Call counts for all vocabularies:" print
- vocab-counters counters. ;
-
-: generic-profile. ( -- )
- "Call counts for methods on generic words:" print
- generic-counters counters. ;
-
-: class-profile. ( -- )
- "Call counts for methods on classes:" print
- class-counters counters. ;
-
-: method-profile. ( -- )
- "Call counts for all methods:" print
- method-counters counters. ;
+++ /dev/null
-Call counting profiler
"A lower-level word puts timings on the stack, instead of printing:"
{ $subsections benchmark }
"You can also read the system clock directly; see " { $link "system" } "."
-{ $see-also "tools.profiler.counting" "tools.annotations" "calendar" } ;
+{ $see-also "tools.profiler.sampling" "tools.annotations" "calendar" } ;
ABOUT: "timing"
USING: help.tips help.markup help.syntax ui.operations
-tools.walker tools.time tools.profiler.counting ui.tools.operations ;
+tools.walker tools.time ui.tools.operations ;
TIP: "Press " { $operation com-stack-effect } " to print the stack effect of the code in the input field without executing it (" { $link "inference" } ")." ;
USING: continuations definitions generic help.topics threads
stack-checker summary io.pathnames io.styles kernel namespaces
parser prettyprint quotations tools.crossref tools.annotations
-editors tools.profiler.counting tools.test tools.time tools.walker vocabs
+editors tools.test tools.time tools.walker vocabs
vocabs.loader words sequences classes compiler.errors
compiler.units accessors vocabs.parser macros.expander ui
ui.tools.browser ui.tools.listener ui.tools.listener.completion
-ui.tools.profiler ui.tools.inspector ui.tools.traceback
+ui.tools.inspector ui.tools.traceback
ui.commands ui.gadgets.editors ui.gestures ui.operations
ui.tools.deploy models help.tips source-files.errors destructors
libc libc.private ;
{ +listener+ t }
} define-operation
-[ quotation? ] \ com-profile H{
- { +keyboard+ T{ key-down f { C+ } "o" } }
- { +listener+ t }
-} define-operation
-
: com-expand-macros ( quot -- ) expand-macros . ;
[ quotation? ] \ com-expand-macros H{
+++ /dev/null
-Slava Pestov
+++ /dev/null
-IN: ui.tools.profiler
-USING: help.markup help.syntax ui.operations ui.commands help.tips ;
-
-ARTICLE: "ui.tools.profiler" "UI profiler tool"
-"The " { $vocab-link "ui.tools.profiler" } " vocabulary implements a graphical tool for viewing profiling results (see " { $link "tools.profiler.counting" } ")."
-$nl
-"To use the profiler, enter a piece of code in the listener input area and press " { $operation com-profile } "."
-$nl
-"Clicking on a vocabulary in the vocabulary list narrows down the word list to only include words from that vocabulary. The sorting options control the order of elements in the vocabulary and word lists. The search fields narrow down the list to only include words or vocabularies whose names contain a substring."
-$nl
-"Consult " { $link "tools.profiler.counting" } " for details about the profiler itself." ;
-
-TIP: "Press " { $operation com-profile } " to run the code in the input field with profiling enabled (" { $link "ui.tools.profiler" } ")." ;
-
-ABOUT: "ui.tools.profiler"
+++ /dev/null
-USING: ui.tools.profiler tools.test ;
-
-
+++ /dev/null
-! Copyright (C) 2007, 2009 Slava Pestov.
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs combinators.short-circuit
-combinators.smart definitions.icons fry kernel locals
-math.order models models.search models.sort present see
-sequences tools.profiler.counting ui.baseline-alignment ui.commands
-ui.gadgets ui.gadgets.borders ui.gadgets.buttons
-ui.gadgets.labeled ui.gadgets.labels ui.gadgets.packs
-ui.gadgets.search-tables ui.gadgets.status-bar
-ui.gadgets.tabbed ui.gadgets.tables ui.gadgets.tracks
-ui.gestures ui.images ui.operations ui.tools.browser
-ui.tools.common vocabs words ;
-FROM: models.arrow => <arrow> ;
-FROM: models.arrow.smart => <smart-arrow> ;
-FROM: models.product => <product> ;
-IN: ui.tools.profiler
-
-TUPLE: profiler-gadget < tool
-sort
-vocabs vocab
-words
-methods
-generic class ;
-
-SINGLETONS: word-renderer vocab-renderer ;
-UNION: profiler-renderer word-renderer vocab-renderer ;
-
-<PRIVATE
-
-: with-datastack* ( seq quot -- seq' )
- '[ _ input<sequence ] output>array ; inline
-
-PRIVATE>
-
-! Value is a { word count } pair
-M: profiler-renderer row-columns
- drop
- [
- [
- [ [ definition-icon <image-name> ] [ present ] bi ]
- [ present ]
- bi*
- ] with-datastack*
- ] [ { "" "All" "" } ] if* ;
-
-M: profiler-renderer prototype-row
- drop \ = definition-icon <image-name> "" "" 3array ;
-
-M: profiler-renderer row-value
- drop dup [ first ] when ;
-
-M: profiler-renderer column-alignment drop { 0 0 1 } ;
-M: profiler-renderer filled-column drop 1 ;
-
-M: word-renderer column-titles drop { "" "Word" "Count" } ;
-M: vocab-renderer column-titles drop { "" "Vocabulary" "Count" } ;
-
-SINGLETON: method-renderer
-
-M: method-renderer column-alignment drop { 0 0 1 } ;
-M: method-renderer filled-column drop 1 ;
-
-! Value is a { method count } pair
-M: method-renderer row-columns
- drop [
- [ [ definition-icon <image-name> ] [ synopsis ] bi ]
- [ present ]
- bi*
- ] with-datastack* ;
-
-M: method-renderer row-value drop first ;
-
-M: method-renderer column-titles drop { "" "Method" "Count" } ;
-
-: <profiler-model> ( values profiler -- model )
- [ [ filter-counts ] <arrow> ] [ sort>> ] bi* <sort> ;
-
-: <words-model> ( profiler -- model )
- [
- [ words>> ] [ vocab>> ] bi
- [
- [
- [ first vocabulary>> ]
- [ vocab-name ]
- bi* =
- ] when*
- ] <search>
- ] keep <profiler-model> ;
-
-: <profiler-table> ( model renderer -- table )
- [ dup [ first present ] when ] <search-table>
- [ invoke-primary-operation ] >>action ;
-
-: <profiler-filter-model> ( counts profiler -- model' )
- [ <model> ] dip <profiler-model> [ f prefix ] <arrow> ;
-
-: <vocabs-model> ( profiler -- model )
- [ vocab-counters [ [ lookup-vocab ] dip ] assoc-map ] dip
- <profiler-filter-model> ;
-
-: <generic-model> ( profiler -- model )
- [ generic-counters ] dip <profiler-filter-model> ;
-
-: <class-model> ( profiler -- model )
- [ class-counters ] dip <profiler-filter-model> ;
-
-: method-matches? ( method generic class -- ? )
- [ first ] 2dip
- {
- [ drop dup [ subwords member-eq? ] [ 2drop t ] if ]
- [ nip dup [ swap "method-class" word-prop = ] [ 2drop t ] if ]
- } 3&& ;
-
-: <methods-model> ( profiler -- model )
- [
- [ method-counters <model> ] dip
- [ generic>> ] [ class>> ] bi
- [ '[ _ _ method-matches? ] filter ] <smart-arrow>
- ] keep <profiler-model> ;
-
-: sort-by-name ( obj1 obj2 -- <=> )
- [ first name>> ] compare ;
-
-: sort-by-call-count ( obj1 obj2 -- <=> )
- [ second ] compare invert-comparison ;
-
-: sort-options ( -- alist )
- {
- { [ sort-by-name ] "by name" }
- { [ sort-by-call-count ] "by call count" }
- } ;
-
-: <sort-options> ( model -- gadget )
- <shelf>
- +baseline+ >>align
- { 5 5 } >>gap
- "Sort by:" <label> add-gadget
- swap sort-options <radio-buttons> horizontal >>orientation add-gadget ;
-
-: <profiler-tool-bar> ( profiler -- gadget )
- <shelf>
- 1/2 >>align
- { 5 5 } >>gap
- swap
- [ <toolbar> add-gadget ]
- [ sort>> <sort-options> add-gadget ] bi ;
-
-:: <words-tab> ( profiler -- gadget )
- horizontal <track>
- { 3 3 } >>gap
- profiler vocabs>> vocab-renderer <profiler-table>
- profiler vocab>> >>selection
- 10 >>min-rows
- 10 >>max-rows
- "Vocabularies" <labeled-gadget>
- 1/2 track-add
- profiler <words-model> word-renderer <profiler-table>
- 10 >>min-rows
- 10 >>max-rows
- "Words" <labeled-gadget>
- 1/2 track-add ;
-
-:: <methods-tab> ( profiler -- gadget )
- vertical <track>
- { 3 3 } >>gap
- horizontal <track>
- { 3 3 } >>gap
- profiler <generic-model> word-renderer <profiler-table>
- profiler generic>> >>selection
- "Generic words" <labeled-gadget>
- 1/2 track-add
- profiler <class-model> word-renderer <profiler-table>
- profiler class>> >>selection
- "Classes" <labeled-gadget>
- 1/2 track-add
- 1/2 track-add
- profiler methods>> method-renderer <profiler-table>
- 5 >>min-rows
- 5 >>max-rows
- 40 >>min-cols
- "Methods" <labeled-gadget>
- 1/2 track-add ;
-
-: <selection-model> ( -- model ) { f 0 } <model> ;
-
-: <profiler-gadget> ( -- profiler )
- vertical profiler-gadget new-track
- { 5 5 } >>gap
- [ sort-by-name ] <model> >>sort
- all-words counters <model> >>words
- <selection-model> >>vocab
- dup <vocabs-model> >>vocabs
- <selection-model> >>generic
- <selection-model> >>class
- dup <methods-model> >>methods
- dup <profiler-tool-bar> { 3 3 } <filled-border> f track-add
- <tabbed-gadget>
- over <words-tab> "Words" add-tab
- over <methods-tab> "Methods" add-tab
- 1 track-add ;
-
-: profiler-help ( -- ) "ui.tools.profiler" com-browse ;
-
-\ profiler-help H{ { +nullary+ t } } define-command
-
-profiler-gadget "toolbar" f {
- { T{ key-down f f "F1" } profiler-help }
-} define-command-map
-
-: profiler-window ( -- )
- <profiler-gadget> "Profiling results" open-status-window ;
-
-: com-profile ( quot -- ) profile profiler-window ; inline
-
-MAIN: profiler-window
+++ /dev/null
-Graphical call profiler
USING: editors help.markup help.syntax summary inspector io io.styles
-listener parser prettyprint tools.profiler.counting tools.walker ui.commands
+listener parser prettyprint tools.walker ui.commands
ui.gadgets.panes ui.gadgets.presentations ui.operations
-ui.tools.operations ui.tools.profiler ui.tools.common vocabs see
+ui.tools.operations ui.tools.common vocabs see
help.tips ;
IN: ui.tools
"ui-browser"
"ui-inspector"
"ui.tools.error-list"
- "ui.tools.profiler"
"ui-walker"
"ui.tools.deploy"
}