ion Functions absG g:Ffh (g0); f (g0); r(g0)ijg0 v gg absProc :f g absId :f g absT t:t absZ z:if (z > ` 1) then !z else z absP p: :absG(p( )) absE e: :absG(e( )) absU u: :absG(u( )) absC h ; ei:habsProc( ); absE(e)i absL h ; g; zi:habsId( );?[absG(g)=Owner( )]; absZ(z)i absV v:8<: habsL(v);?Ĉ ;?V̂ i if v 2 L; h?L̂; absC(v);?V̂ i if v 2 C; h?L̂;?Ĉ; absV (v)i if v 2 V: absF hp1; p2i:habsP (p1); absP (p2)i absB b: hẑ; yi:FfabsV (b(z; y))jabs(z) v ẑg absA hb; fi:habsB(b); absF (f)i absS s: : :FfabsA(s( ; g))jabsG(g) v f gg Partial Orders
̂ v̂
̂0 i
̂
̂0 ̂ v ^ Proc ̂0 i ̂ ̂0 ̂ vÎd ̂0 i ̂ ̂0 t̂ vT̂ t̂0 i t̂ =?T̂ or t̂0 = >T̂ ẑ vẐ ẑ0 i ẑ =?Ẑ or ẑ0 = >Ẑ p̂ vP̂ p̂0 i p̂( ) v̂ p̂0( ) 8 2 Proc ê vÊ ê0 i ê( ) v̂ ê0( ) 8 2 Proc û vÛ û0 i û( ) v̂ û0( ) 8 2 Proc ĥ; êi vĈ ĥ0; ê0i i ̂ vÎd ̂0 ^ ê vÊ ê0 ĥ; û; ẑi vL̂ ĥ0; û0; ẑ0i i ̂ vÎd ̂0 ^ û vÛ û0 ^ ẑ vẐ ẑ0 hl̂; ĉ; ẑi vV̂ hl̂0; ĉ0; ẑ0i i l̂ vL̂ l̂0 ^ ĉ vĈ ĉ0 ^ ẑ vẐ ẑ0 hp̂1; p̂2i vF̂ hp̂01; p̂02i i p̂1 vP̂ p̂01 ^ p̂2 vP̂ p̂02 b̂ vB̂ b̂0 i b̂(ẑ; y) vV̂ b̂0(ẑ; y) 8ẑ 2 Ẑ ; 8y 2 Y hb̂; f̂i v hb̂0; f̂ 0i i b̂ vB̂ b̂0 ^ f̂ vF̂ f̂ 0 ŝ vŜ ŝ0 i ŝ( ; ) v ŝ0( ; ) 8 2 Îd ; 8 2 21 LUB Operations ̂ t̂
̂0 ̂ [
̂0 ̂ t ^ Proc ̂0 ̂ [ ̂0 ̂ tÎd ̂0 ̂ [ ̂0 t̂ tT̂ t̂0 if t̂ =?T̂ then t̂0 else >T̂ ẑ tẐ ẑ0 if ẑ =?Ẑ then ẑ0 else >Ẑ p̂ tP̂ p̂0 :p̂( ) t̂ p̂0( ) ê tÊ ê0 :ê( ) t̂ ê0( ) û tÛ û0 :û( ) t̂ û0( ) ĥ; êi tĈ ĥ0; ê0i ĥ tÎd ̂0; ê tÊ ê0i ĥ; û; ẑi tL̂ ĥ0; û0; ẑ0i ĥ tÎd ̂0; ûtÛ û0; ẑ tẐ ẑ0i hl̂; ĉ; ẑi tV̂ hl̂0; ĉ0; ẑ0i hl̂ tL̂ l̂0; ĉ tĈ ĉ0; ẑ tẐ ẑ0i hp̂1; p̂2i tF̂ hp̂01; p̂02i hp̂1 tP̂ p̂01; p̂2 tP̂ p̂02i b̂ tB̂ b̂0 ẑ: y:b̂(ẑ; y) tV̂ b̂0(ẑ; y) hb̂; f̂ i t hb̂0; f̂ 0i hb̂ tB̂ b̂0; f̂ tF̂ f̂ 0i ŝ tŜ ŝ0 : :ŝ( ; ) t ŝ0( ; ) Abstract Domain Meanings An abstract \object" in the context of the abstract domains is a pair of an identi er and its abstract instance (2 Id ̂). r = f0; 1; : : :; r 1; !rg? Recursive call frequency. Flat domain. Count the number of times that a function is called recursively, not the count of recursive call depth. For example, for a procedure's movement string ddduuddddu, the count is 2 since recursive calls to the procedure occurred twice (recursion depths are 3 (ddd) and 4 (dddd)). Let r : G! r be such function that returns the recursive call frequency given a procedure movement string. f = f0; 1; : : :; f 1; !fg? Flat call frequency. Flat domain. Count the number of times that a function is called and returned without nested calls. For example, for a procedure's movement string ddddududu, the count is 2 ( dudu). Let f : G ! f be such function that returns the at call frequency given a procedure movement string. = f ; d; dd+g? Call counter state mode. Indicates the current state of a procedure movement string. For example, procedure strings ending with single activation: ud =) d procedure strings ending with multiple consecutive activations: dd =) dd+ procedure strings ending with deactivation: u =) = f r Smashed product. Each element is a representative of a set of procedure movement strings. The set of all procedure movement strings, whose cardinality is in nite, is projected into this nite set . Each 22 procedure movement string is uniquely mapped to an element of . For example, ddd =) hdd+; 0; 0i consecutive calls dddu =) h ; 0; 1i count the recursive call dddud =) hd; 0; 1i a single call follows dddudu =) h ; 1; 1i count the at call dddududdd =) hdd+; 1; 1i consecutive calls follows In general, for a procedure movement string, its corresponding is determined by the nite state machine (see Figure 5). d dd+ u d d u , f++ ++ , r d u Transition arc is labeled with token and operation, if any. e f r ++ ++ : increment flat call frequency : increment recursive call frequency Figure 5: Finite state machine to transform a procedure string to an element in . T̂ = f?; ^ true; ^ false;>g Abstract boolean domain. Flat. Ẑ = f?; 0; : : :; ` 1; !z;>g Abstract integer domain. Flat. P̂ = Proc ! ̂ An abstract call counter is a map from a procedure to the abstract number of calls to the procedure. This is the abstract clock associated with each object. This records the elapsed time after an object creation and a time when the object is accessed. Ê = Proc ! ̂ An abstract environment is a map from a procedure to the abstract number of calls to the procedure. An instance of an identi er is determined by looking up its owner's entry of the current environment. Û = Proc ! ̂ An abstract instance of an abstract location. 23 Ĉ = ^ Proc Ê An abstract closure is an abstract procedure index and an abstract environment. An abstract procedure index is a set of procedure indices. L̂ = Îd Û Ẑ An abstract location is a product of an abstract identi er, an abstract instance, and an abstract o set. Note that the abstract instance is a map from a procedure index to an abstract number of calls to the procedure. When a location is created, its owner's current call counter is used for the instance of the location. V̂ = L̂ Ĉ Ẑ An abstract value is a product of an abstract location, an abstract closure, and an abstract integer. F̂ = (P̂ P̂ ) An abstract lifetime record's rst component records the elapsed time after the creation of an object and the second component records a time when the object is accessed. B̂ = (Ẑ Y )! V̂ An abstract block is a map from an abstract o set and a size to an abstract value.  = B̂ F̂ An abstract store image consists of an abstract block and lifetime record. Ŝ = Id ! !  An abstract store ŝ is represented as a member of Id ! ! Â: It is used for the atomic function domain of Id̂Â. Note that ̂ (respectively Id ) is an atomic lattice with its atoms being (respectively the set of identi ers of an input program). Rep(x) = fxi j x = Fni=1 xi ^ xi is irreducible g ŝ[k̂= ; ] = ŝ[k̂ k ŝ( ; )== ; ]; if #1 = dd _ #2 = !f _ #3 6= 0; ŝ[k̂ k ŝ( ; )= ; ]; otherwise. ŝ[k̂= / ;
̂] = ŝ[k̂ k ŝ( ; (
̂i) )== ; (
̂i) ]
̂i2Rep(
̂); if
̂ is reducible; ŝ[k̂= ; (
̂) ]; if
̂ is irreducible. ŝ ( ;
̂) = F
̂i2Rep(
̂) ŝ( ; (
̂i) ): Note that the functions (= ,= /, ( ) ) are all monotonic if k̂ is monotonic. A
̂ instantiates an identi er in terms of the abstract call counter of the identi er's owner. Object lifetime is recorded in the abstract store. In the store, an object (2 Id ̂) is associated with a pair of abstract call counters hp̂1; p̂2i, where p̂1 is the elapsed time after the creation of the object and p̂2 is a time when the object is accessed. Whenever an abstract procedural movement occurs, p̂1s of all the objects of the store are incremented (the auxiliary function ^ MoveStore does the job). Whenever an object is accessed, corresponding p̂1 is recorded. (The auxiliary function ^ Stamp does the job.) 24 Abstract Auxiliary Functions Owner : Id ! Proc Owner( ) = ; if 2 ParamIds( ) [ LocalIds( ); ?; otherwise. ^ Instance : Id ! (Proc ! ̂)! ̂ ^ Instance( ; x̂) = x̂(Owner( )) ^ Stamp : F̂ ! F̂ ^ Stamp(f̂ ) = (f̂#1)2: When an object is accessed, the current value of the corresponding p̂1 is recorded in p̂2. ^ Stamp does the job. ^ MoveP : P̂ ! Proc ! fd; ug ! P̂ ^ MoveP (p̂; ; x) = p̂[p̂( ) ̂ x= ] When a procedure is called or returned, the elapsed time of the objects in the store is incremented. ^ MoveP is involved in the job. ̂ =
̂: x:f x j 2
̂g d u h ; f; ri hd; f; ri h ; f; ri hd; f; ri hdd+; f; ri h ; f 1; ri hdd+ ; f; ri hdd+; f; ri h ; f; r 1i ^ MoveStore : Ŝ ! Proc ! fd; ug ! Ŝ. ^ MoveStore(ŝ; ; x) = : :h ŝ( ; )#1; h ^ MoveP (ŝ( ; )#2#1; ; x); ŝ( ; )#2#2ii: When an abstract procedural movement occurs, the elapsed times of all the objects in the store is incremented. ^ MoveSigma does the job. ^ Read : B̂ ! Ẑ ! Z ! B̂ ^ Read (b̂; ẑ; k) = let k̂ = absZ(k) k̂0 = absZ(k0) Sc [ = fhẑ0; k0i 2 Ẑ Y j ^ true v (ẑ ẑ04 ẑ k̂ ẑ0 k̂0)g ĥ : Ẑ Y ! Ẑ Y = hẑ0; k0i:hẑ0 ẑ; k0i in (b̂jSc [jẐ Y ) ĥ As another de nition (for f 2 A ! B, defdom(f) is the subset of A over which f 's value is not ?B) ^ Read (b̂; ẑ; k) = let k̂ = absZ(k) k̂0 = absZ(k0) Is = defdom(b̂) Is0 = fhẑ0; k0i 2 Isj ^ true v (ẑ ẑ04 ẑ k̂ ẑ0 k̂0)g in thẑ0;k0i2Is 0?B̂[b̂(ẑ0; k0)=hẑ0 ẑ; k0i]: 25Auxiliary Functions Owner : Id ! Proc Owner( ) = ; if 2 ParamIds( ) [ LocalIds( ); ?; otherwise. ^ Instance : Id ! (Proc ! ̂)! ̂ ^ Instance( ; x̂) = x̂(Owner( )) ^ Stamp : F̂ ! F̂ ^ Stamp(f̂ ) = (f̂#1)2: When an object is accessed, the current value of the corresponding p̂1 is recorded in p̂2. ^ Stamp does the job. ^ MoveP : P̂ ! Proc ! fd; ug ! P̂ ^ MoveP (p̂; ; x) = p̂[p̂( ) ̂ x= ] When a procedure is called or returned, the elapsed time of the objects in the store is incremented. ^ MoveP is involved in the job. ̂ =
̂: x:f x j 2
̂g d u h ; f; ri hd; f; ri h ; f; ri hd; f; ri hdd+; f; ri h ; f 1; ri hdd+ ; f; ri hdd+; f; ri h ; f; r 1i ^ MoveStore : Ŝ ! Proc ! fd; ug ! Ŝ. ^ MoveStore(ŝ; ; x) = : :h ŝ( ; )#1; h ^ MoveP (ŝ( ; )#2#1; ; x); ŝ( ; )#2#2ii: When an abstract procedural movement occurs, the elapsed times of all the objects in the store is incremented. ^ MoveSigma does the job. ^ Read : B̂ ! Ẑ ! Z ! B̂ ^ Read (b̂; ẑ; k) = let k̂ = absZ(k) k̂0 = absZ(k0) Sc [ = fhẑ0; k0i 2 Ẑ Y j ^ true v (ẑ ẑ04 ẑ k̂ ẑ0 k̂0)g ĥ : Ẑ Y ! Ẑ Y = hẑ0; k0i:hẑ0 ẑ; k0i in (b̂jSc [jẐ Y ) ĥ As another de nition (for f 2 A ! B, defdom(f) is the subset of A over which f 's value is not ?B) ^ Read (b̂; ẑ; k) = let k̂ = absZ(k) k̂0 = absZ(k0) Is = defdom(b̂) Is0 = fhẑ0; k0i 2 Isj ^ true v (ẑ ẑ04 ẑ k̂ ẑ0 k̂0)g in thẑ0;k0i2Is 0?B̂[b̂(ẑ0; k0)=hẑ0 ẑ; k0i]: 25 ^ Write : B̂ ! B̂ ! Ẑ ! Z ! B̂ ^ Write(b̂d; b̂s; ẑ; k) = let k̂ = absZ(k) k̂0 = absZ(k0) Sc [ = fhẑ0; k0i 2 Ẑ Y j ^ true v (ẑ ẑ04 ẑ k̂ ẑ0 k̂0)g portion that might be overwritten Sc \ = fhẑ0; k0i 2 Ẑ Y j(ẑ ẑ04 ẑ k̂ ẑ0 k̂0) v ^ trueg overwriting portion So \ = fhẑ0; k0i 2 Ẑ Y j(ẑ ẑ0 k̂04 ẑ0 ẑ k̂) v ^ trueg portion that will be overwritten ĥ : Ẑ Y ! Ẑ Y = hẑ0; k0i:hẑ0 ẑ; k0i in (b̂d t ((b̂s ĥ)jSc [ jẐ Y )) ((b̂s ĥ)jSc \ jSo \) As another de nition (for f 2 A ! B, defdom(f) is the subset of A over which f 's value is not ?B) ^ Write(b̂d; b̂s; ẑ; k) = let k̂ = absZ(k) k̂0 = absZ(k0) ^ bsh = thẑ0;k0i2defdo
[1]
Frank Jackson,et al.
Tenuring policies for generation-based storage reclamation
,
1988,
OOPSLA 1988.
[2]
Geoffrey Livingston Burn,et al.
Abstract interpretation and the parallel evaluation of functional languages
,
1987
.
[3]
Patrick Cousot,et al.
Systematic design of program analysis frameworks
,
1979,
POPL.
[4]
Joseph E. Stoy,et al.
Denotational Semantics: The Scott-Strachey Approach to Programming Language Theory
,
1981
.
[5]
Chris Hankin,et al.
Abstract Interpretation of Declarative Languages
,
1987
.
[6]
David M. Ungar,et al.
Generation Scavenging: A non-disruptive high performance storage reclamation algorithm
,
1984,
SDE 1.
[7]
Zahira Ammarguellat,et al.
A Control-Flow Normalization Algorithm and Its Complexity
,
1992,
IEEE Trans. Software Eng..
[8]
Williams Ludwell Harrison,et al.
The interprocedural analysis and automatic parallelization of Scheme programs
,
1990,
LISP Symb. Comput..