Cleaning up and debugging corss-referencing

db4
Slava Pestov 2008-06-06 20:47:09 -05:00
parent 460ce213af
commit 014d2ea31c
14 changed files with 106 additions and 40 deletions

View File

@ -35,7 +35,7 @@ IN: compiler
[ swap save-effect ] [ swap save-effect ]
[ compiled-unxref ] [ compiled-unxref ]
[ [
dup compiled-crossref? dup crossref?
[ dependencies get compiled-xref ] [ drop ] if [ dependencies get compiled-xref ] [ drop ] if
] tri ; ] tri ;

View File

@ -66,7 +66,7 @@ GENERIC: definitions-changed ( assoc obj -- )
: compile ( words -- ) : compile ( words -- )
recompile-hook get call recompile-hook get call
dup [ drop compiled-crossref? ] assoc-contains? dup [ drop crossref? ] assoc-contains?
modify-code-heap ; modify-code-heap ;
SYMBOL: outdated-tuples SYMBOL: outdated-tuples
@ -82,7 +82,7 @@ SYMBOL: update-tuples-hook
: finish-compilation-unit ( -- ) : finish-compilation-unit ( -- )
call-recompile-hook call-recompile-hook
call-update-tuples-hook call-update-tuples-hook
dup [ drop compiled-crossref? ] assoc-contains? modify-code-heap dup [ drop crossref? ] assoc-contains? modify-code-heap
; ;
: with-nested-compilation-unit ( quot -- ) : with-nested-compilation-unit ( quot -- )

View File

@ -47,7 +47,17 @@ M: object uses drop f ;
: xref ( defspec -- ) dup uses crossref get add-vertex ; : xref ( defspec -- ) dup uses crossref get add-vertex ;
: usage ( defspec -- seq ) \ f or crossref get at keys ; : usage ( defspec -- seq ) crossref get at keys ;
GENERIC: irrelevant? ( defspec -- ? )
M: object irrelevant? drop f ;
GENERIC: smart-usage ( defspec -- seq )
M: f smart-usage drop \ f smart-usage ;
M: object smart-usage usage [ irrelevant? not ] filter ;
: unxref ( defspec -- ) : unxref ( defspec -- )
dup uses crossref get remove-vertex ; dup uses crossref get remove-vertex ;

View File

@ -117,6 +117,9 @@ M: method-spec definition
M: method-spec forget* M: method-spec forget*
first2 method forget* ; first2 method forget* ;
M: method-spec smart-usage
second smart-usage ;
M: method-body definer M: method-body definer
drop \ M: \ ; ; drop \ M: \ ; ;
@ -134,6 +137,9 @@ M: method-body forget*
[ t "forgotten" set-word-prop ] bi [ t "forgotten" set-word-prop ] bi
] if ; ] if ;
M: method-body smart-usage
"method-generic" word-prop smart-usage ;
: implementors* ( classes -- words ) : implementors* ( classes -- words )
all-words [ all-words [
"methods" word-prop keys "methods" word-prop keys

View File

@ -4,7 +4,7 @@ USING: kernel classes.tuple.private hashtables assocs sorting
accessors combinators sequences slots.private math.parser words accessors combinators sequences slots.private math.parser words
effects namespaces generic generic.standard.engines effects namespaces generic generic.standard.engines
classes.algebra math math.private kernel.private classes.algebra math math.private kernel.private
quotations arrays ; quotations arrays definitions ;
IN: generic.standard.engines.tuple IN: generic.standard.engines.tuple
TUPLE: echelon-dispatch-engine n methods ; TUPLE: echelon-dispatch-engine n methods ;
@ -64,8 +64,9 @@ M: engine-word stack-effect
[ extra-values ] [ stack-effect ] bi [ extra-values ] [ stack-effect ] bi
dup [ clone [ length + ] change-in ] [ 2drop f ] if ; dup [ clone [ length + ] change-in ] [ 2drop f ] if ;
M: engine-word compiled-crossref? M: engine-word crossref? drop t ;
drop t ;
M: engine-word irrelevant? drop t ;
: remember-engine ( word -- ) : remember-engine ( word -- )
generic get "engines" word-prop push ; generic get "engines" word-prop push ;

View File

@ -3,7 +3,8 @@ USING: tools.test math math.functions math.constants
generic.standard strings sequences arrays kernel accessors generic.standard strings sequences arrays kernel accessors
words float-arrays byte-arrays bit-arrays parser namespaces words float-arrays byte-arrays bit-arrays parser namespaces
quotations inference vectors growable hashtables sbufs quotations inference vectors growable hashtables sbufs
prettyprint byte-vectors bit-vectors float-vectors ; prettyprint byte-vectors bit-vectors float-vectors definitions
generic sets graphs assocs ;
GENERIC: lo-tag-test GENERIC: lo-tag-test
@ -287,3 +288,24 @@ M: sbuf no-stack-effect-decl ;
[ ] [ \ no-stack-effect-decl see ] unit-test [ ] [ \ no-stack-effect-decl see ] unit-test
[ ] [ \ no-stack-effect-decl word-def . ] unit-test [ ] [ \ no-stack-effect-decl word-def . ] unit-test
! Cross-referencing with generic words
TUPLE: xref-tuple-1 ;
TUPLE: xref-tuple-2 < xref-tuple-1 ;
: (xref-test) drop ;
GENERIC: xref-test ( obj -- )
M: xref-tuple-1 xref-test (xref-test) ;
M: xref-tuple-2 xref-test (xref-test) ;
[ t ] [
\ xref-test
\ xref-tuple-1 \ xref-test method [ usage unique ] closure key?
] unit-test
[ t ] [
\ xref-test
\ xref-tuple-2 \ xref-test method [ usage unique ] closure key?
] unit-test

View File

@ -4,7 +4,7 @@ USING: inference.dataflow inference.state arrays generic io
io.streams.string kernel math namespaces parser prettyprint io.streams.string kernel math namespaces parser prettyprint
sequences strings vectors words quotations effects classes sequences strings vectors words quotations effects classes
continuations debugger assocs combinators compiler.errors continuations debugger assocs combinators compiler.errors
generic.standard.engines.tuple accessors math.order ; generic.standard.engines.tuple accessors math.order definitions ;
IN: inference.backend IN: inference.backend
: recursive-label ( word -- label/f ) : recursive-label ( word -- label/f )
@ -21,6 +21,28 @@ M: engine-word inline?
M: word inline? M: word inline?
"inline" word-prop ; "inline" word-prop ;
SYMBOL: visited
: reset-on-redefine { "inferred-effect" "no-effect" } ; inline
: (redefined) ( word -- )
dup visited get key? [ drop ] [
[ reset-on-redefine reset-props ]
[ dup visited get set-at ]
[
crossref get at keys
[ word? ] filter
[
[ reset-on-redefine [ word-prop ] with contains? ]
[ inline? ]
bi or
] filter
[ (redefined) ] each
] tri
] if ;
M: word redefined H{ } clone visited [ (redefined) ] with-variable ;
: local-recursive-state ( -- assoc ) : local-recursive-state ( -- assoc )
recursive-state get dup keys recursive-state get dup keys
[ dup word? [ inline? ] when not ] find drop [ dup word? [ inline? ] when not ] find drop

View File

@ -549,10 +549,34 @@ ERROR: custom-error ;
{ 1 0 } [ [ ] map-children ] must-infer-as { 1 0 } [ [ ] map-children ] must-infer-as
! Corner case ! Corner case
! [ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail [ [ [ f dup ] [ dup ] [ ] unfold ] infer ] must-fail
! [ [ [ f dup ] [ ] [ ] while ] infer ] must-fail [ [ [ f dup ] [ ] [ ] while ] infer ] must-fail
! : erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline : erg's-inference-bug ( -- ) f dup [ erg's-inference-bug ] when ; inline
! [ [ erg's-inference-bug ] infer ] must-fail [ [ erg's-inference-bug ] infer ] must-fail
: inference-invalidation-a ;
: inference-invalidation-b [ inference-invalidation-a ] dip call ; inline
: inference-invalidation-c [ + ] inference-invalidation-b ;
[ 7 ] [ 4 3 inference-invalidation-c ] unit-test
{ 2 1 } [ inference-invalidation-c ] must-infer-as
[ ] [ "IN: inference.tests : inference-invalidation-a 1 2 ;" eval ] unit-test
[ 3 ] [ inference-invalidation-c ] unit-test
{ 0 1 } [ inference-invalidation-c ] must-infer-as
GENERIC: inference-invalidation-d ( obj -- )
M: object inference-invalidation-d inference-invalidation-c 2drop ;
\ inference-invalidation-d must-infer
[ ] [ "IN: inference.tests : inference-invalidation-a ;" eval ] unit-test
[ [ inference-invalidation-d ] infer ] must-fail

View File

@ -102,7 +102,7 @@ SYMBOL: compiled-crossref
compiled-crossref global [ H{ } assoc-like ] change-at compiled-crossref global [ H{ } assoc-like ] change-at
: compiled-xref ( word dependencies -- ) : compiled-xref ( word dependencies -- )
[ drop compiled-crossref? ] assoc-filter [ drop crossref? ] assoc-filter
2dup "compiled-uses" set-word-prop 2dup "compiled-uses" set-word-prop
compiled-crossref get add-vertex* ; compiled-crossref get add-vertex* ;
@ -125,28 +125,9 @@ SYMBOL: +called+
compiled-usage [ nip +inlined+ eq? ] assoc-filter update compiled-usage [ nip +inlined+ eq? ] assoc-filter update
] with each keys ; ] with each keys ;
<PRIVATE GENERIC: redefined ( word -- )
SYMBOL: visited M: object redefined drop ;
: reset-on-redefine { "inferred-effect" "no-effect" } ; inline
: (redefined) ( word -- )
dup visited get key? [ drop ] [
[ reset-on-redefine reset-props ]
[ dup visited get set-at ]
[
crossref get at keys
[ word? ] filter
[ reset-on-redefine [ word-prop ] with contains? ] filter
[ (redefined) ] each
] tri
] if ;
PRIVATE>
: redefined ( word -- )
H{ } clone visited [ (redefined) ] with-variable ;
: define ( word def -- ) : define ( word def -- )
[ ] like [ ] like

View File

@ -53,7 +53,7 @@ M: object find-parse-error
: fix ( word -- ) : fix ( word -- )
[ "Fixing " write pprint " and all usages..." print nl ] [ "Fixing " write pprint " and all usages..." print nl ]
[ [ usage ] keep prefix ] bi [ [ smart-usage ] keep prefix ] bi
[ [
[ "Editing " write . ] [ "Editing " write . ]
[ [

View File

@ -7,7 +7,7 @@ sorting hashtables vocabs parser source-files ;
IN: tools.crossref IN: tools.crossref
: usage. ( word -- ) : usage. ( word -- )
usage sorted-definitions. ; smart-usage sorted-definitions. ;
: words-matching ( str -- seq ) : words-matching ( str -- seq )
all-words [ dup word-name ] { } map>assoc completions ; all-words [ dup word-name ] { } map>assoc completions ;

View File

@ -44,7 +44,7 @@ HELP: vocab-profile.
HELP: usage-profile. HELP: usage-profile.
{ $values { "word" word } } { $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." } { $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 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" } "." } { $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." } } ; { $examples { $code "\\ + usage-profile." } } ;
HELP: vocabs-profile. HELP: vocabs-profile.

View File

@ -58,7 +58,7 @@ M: method-body (profile.)
"Call counts for words which call " write "Call counts for words which call " write
dup pprint dup pprint
":" print ":" print
usage [ word? ] filter counters counters. ; smart-usage [ word? ] filter counters counters. ;
: vocabs-profile. ( -- ) : vocabs-profile. ( -- )
"Call counts for all vocabularies:" print "Call counts for all vocabularies:" print

View File

@ -94,7 +94,7 @@ M: live-search pref-dim* drop { 400 200 } ;
"Words in " rot vocab-name append show-titled-popup ; "Words in " rot vocab-name append show-titled-popup ;
: show-word-usage ( workspace word -- ) : show-word-usage ( workspace word -- )
"" over usage f <definition-search> "" over smart-usage f <definition-search>
"Words and methods using " rot word-name append "Words and methods using " rot word-name append
show-titled-popup ; show-titled-popup ;