1: \documentclass[english,numreferences]{kluwer}
2: %\usepackage{wrapfig}
3: \usepackage{babel}
4: %\usepackage{rotating}
5: %\usepackage{amssymb}
6: \usepackage{amsmath}
7: %\usepackage{eepic}
8: \usepackage{latexsym}
9: %\usepackage{stmaryrd}
10: %\usepackage{showkeys}
11: \usepackage{epsfig}
12: %\usepackage{draftcopy}
13: \usepackage{theorem}
14: \usepackage{ifthen}
15:
16: \newboolean{WITHAPPENDIX}
17: \setboolean{WITHAPPENDIX}{true}
18: %\setboolean{WITHAPPENDIX}{false}
19:
20: \newboolean{PROOFSONLY}
21: \setboolean{PROOFSONLY}{true}
22: %\setboolean{PROOFSONLY}{false}
23:
24: \ifthenelse{\boolean{PROOFSONLY}}{
25: \newcommand*{\ifcorr}[1]{\emph{See journal version of this paper.}}}{%%
26: \newcommand*{\ifcorr}[1]{#1}}
27: \ifthenelse{\boolean{PROOFSONLY}}{
28: \newcommand*{\ifcorrx}[1]{}}{%%
29: \newcommand*{\ifcorrx}[1]{#1}}
30:
31: \newcommand{\lfp}{\mathsf{lfp}}
32: \newcommand{\fp}{\mathsf{fp}}
33: %\DeclareMathOperator{\diver}{\mathsf{div}}
34: %\DeclareMathOperator{\last}{\mathsf{lst}}
35: %\DeclareMathOperator{\first}{\mathsf{fst}}
36: %\DeclareMathOperator{\append}{:\!:}
37: \newcommand{\lub}{\mathsf{lub}} %\DeclareMathOperator{\type}{\mathsf{type}}
38:
39: \renewcommand{\emptyset}{\mathord{\varnothing}}
40:
41:
42: \newcommand*{\sseq}{\subseteq}
43: \newcommand*{\sseqf}{\mathrel{\subseteq_\mathrm{f}}}
44: \newcommand*{\sslt}{\subset}
45: \newcommand*{\Sseq}{\supseteq}
46: \newcommand*{\Ssgt}{\supset}
47: \newcommand{\Nsseq}{\nsubseteq}
48: \newcommand{\Nsslt}{\not\subset}
49:
50: %\newcommand*{\wpc}{\mathop{\wp_\mathrm{c}}\nolimits}
51: \newcommand*{\sep}{\mathop{\star}\nolimits}
52: \newcommand*{\Out}{{\mathtt{out}}}
53: \newcommand*{\this}{{\mathtt{this}}}
54: \newcommand*{\wrt}{\textit{w.r.t.\ }}
55: \newcommand*{\ie}{\textit{i.e., }}
56: \newcommand*{\integer}{\mathord{\mathit{int}}}
57: \newcommand*{\Type}{\mathord{\mathit{Type}}}
58: \newcommand*{\Vars}{\mathord{\mathit{Vars}}}
59: \newcommand*{\Id}{\mathord{\mathit{Id}}}
60: \newcommand*{\nil}{\mathord{\mathit{null}}}
61: \newcommand*{\Typing}{\mathord{\mathit{TypEnv}}}
62: \newcommand*{\Fields}{\mathord{\mathit{Fields}}}
63: \newcommand*{\Methods}{\mathord{\mathit{Methods}}}
64: \newcommand*{\Pars}{\mathord{\mathit{Pars}}}
65: \newcommand*{\Frame}{\mathord{\mathit{Frame}}}
66: \newcommand*{\Obj}{\mathord{\mathit{Obj}}}
67: \newcommand*{\Memory}{\mathord{\mathit{Memory}}}
68: \newcommand*{\Loc}{\mathord{\mathit{Loc}}}
69: \newcommand*{\Value}{\mathord{\mathit{Value}}}
70: \newcommand*{\rs}{\mathord{\mathit{res}}}
71: \newcommand*{\inp}{\mathord{\mathit{in}}}
72: \newcommand*{\out}{\mathord{\mathit{out}}}
73: \newcommand*{\ps}{{\mathit{ps}}}
74: \newcommand*{\er}{{\mathcal{ER}}}
75: \newcommand*{\e}{{\mathcal{E}}}
76: \newcommand*{\ee}{e}
77:
78: \newcommand{\proofoperation}[1]{\newline\underline{$\mathsf{{#1}}$}}
79: \newcommand{\myproof}[3]{\begin{pf*}{Proof of {#1} \ref{#2} at page \pageref{#2}}{#3}\end{pf*}}
80: \newcommand{\myproofbis}[1]{\begin{pf}{#1}\hspace*{\fill} $\Box$\end{pf}}
81: %\newcommand{\myproof}[3]{\fbox{\textbf{Proof}\textit{ of {#1} \ref{#2} at page \pageref{#2}}}\newline\mbox{}\\$\circ$\ {#3}$\qed$\newline}
82: %\newcommand{\myproofbis}[1]{\begin{proof}{#1}\end{proof}}
83: %\newcommand{\aid}[2]{{\mathit{#1}\sep\mathord{#2}}}
84: \newcommand{\eref}[1]{(\ref{#1})}
85: \newcommand{\elabel}[1]{\label{i#1}}
86: \newcommand{\pair}[2]{{\langle{#1},\,{#2}\rangle}}
87: \newcommand{\aid}[2]{{\langle\mathit{#1},\mathord{#2}\rangle}}
88: \newcommand{\rstrict}[1]{{\llcorner{#1}\lrcorner}}
89: \newcommand{\aenv}[1]{\underline{{#1}}}
90: \newcommand{\eps}{\epsilon}
91: \newcommand{\inter}[3]{\mathcal{{#1}}_{{#2}}[\![{#3}]\!]}
92: \newcommand{\Seq}{\mathsf{seq}}
93: \newcommand{\nat}{\mathbb{N}}
94: \newcommand{\integers}{\mathbb{Z}}
95: \newcommand{\decl}[3]{\mathtt{let}\ {#1}\!:\!{#2}\ \mathtt{in}\ {#3}}
96: \newcommand{\ite}[3]{\mathtt{if}\ {#1}\ \mathtt{then}\ {#2}\ \mathtt{else}\ {#3}}
97: \newcommand{\return}[1]{\mathtt{return}\ {#1}}
98: \newcommand{\macro}[1]{\mathtt{macro}\ {#1}}
99: \newcommand{\while}[2]{\mathtt{while}\ {#1}\ \mathtt{do}\ {#2}}
100: \newcommand{\nilc}[1]{\mathtt{nil}\ {#1}}
101: \newcommand{\call}[1]{\mathtt{call}({#1})}
102: %\newcommand{\dup}[3]{\mathtt{dup}_{{{#1}}\leftarrow{{#2}}}({#3})}
103: \newcommand{\remove}[2]{\mathtt{remove}_{{#1}}({#2})}
104: \newcommand{\watchpoint}[1]{\mathtt{watchpoint}({#1})}
105: \newcommand{\new}[1]{\mathtt{new}\ {#1}}
106: %\newcommand{\watchpoint}[1]{\mathtt{watchpoint}({#1})}
107: \newcommand{\domain}{\mathsf{dom}}
108: \newcommand{\codom}{\mathsf{rng}}
109: \newcommand{\init}{\Im}
110: %\newcommand{\text}[1]{{\mbox{#1}}}
111: \newenvironment{romanenumerate}{\renewcommand{\labelenumi}{\roman{enumi})}%
112: \begin{enumerate}}{\end{enumerate}%
113: \renewcommand{\labelenumi}{\arabic{enumi}.}}
114:
115: %% Summaries for theorem-like environments
116: \newcommand{\summary}[2]{\textrm{\textbf{\textup{#1}}} \textit{#2}}
117:
118: %\theoremstyle{plain}
119: \newtheorem{theorem}{Theorem}
120: \newtheorem{proposition}[theorem]{Proposition}
121: \newtheorem{lemma}[theorem]{Lemma}
122: \newtheorem{corollary}[theorem]{Corollary}
123: %\theoremstyle{remark}
124: \newtheorem{remark}[theorem]{Remark}
125: %\theoremstyle{definition}
126: \newtheorem{definition}[theorem]{Definition}
127: \theoremstyle{plain}
128: \theoremheaderfont{\scshape}
129: {\theorembodyfont{\rmfamily} \newtheorem{example}[theorem]{Example}}
130: %\markboth{}{}
131:
132: \begin{document}
133: \begin{article}
134: \begin{opening}
135:
136: \ifthenelse{\boolean{PROOFSONLY}}{%%
137: \title{Deriving Escape Analysis by Abstract Interpretation: Proofs of results}
138: }{
139: \title{Deriving Escape Analysis by Abstract Interpretation}
140: }
141:
142: \author{Patricia M.\ \surname{Hill}\email{hill@comp.leeds.ac.uk}}
143: \institute{University of Leeds, United Kingdom}
144: \author{Fausto \surname{Spoto}\email{fausto.spoto@univr.it}}
145: \institute{Universit\`a di Verona, Italy}
146: %\begin{ao}
147: %Dipartimento di Informatica\\
148: %Universit\`a di Verona\\
149: %Strada le Grazie, 15\\
150: %37134 Verona, Italy
151: %\end{ao}
152: %
153: \begin{abstract}
154: Escape analysis of object-oriented languages
155: approximates the set of objects which do not \emph{escape}
156: from a given context. If we take a method as context,
157: the non-escaping objects can be allocated on its activation stack;
158: if we take a thread,
159: Java synchronisation locks on such objects are not needed.
160: In this paper, we formalise a basic escape domain $\e$
161: as an abstract interpretation of concrete states, which we then refine
162: into an abstract domain $\er$ which is more concrete than $\e$ and, hence,
163: leads to a more precise escape analysis than $\e$.
164: We provide optimality results for both $\e$ and $\er$, in the form of
165: Galois insertions from the concrete to the abstract domains and of
166: optimal abstract operations. The Galois insertion property is obtained
167: by restricting the abstract domains to those elements which do not contain
168: \emph{garbage}, by using an abstract garbage collector.
169: Our implementation of $\er$ is hence an implementation
170: of a formally correct escape analyser, able to
171: detect the stack allocatable creation points of Java (bytecode)
172: applications.
173: \ifthenelse{\boolean{PROOFSONLY}}{%%
174:
175: This report contains the proofs of results of a paper with the same
176: title and authors and to be published in the Journal
177: \emph{Higher-Order Symbolic Computation}.
178: }{%%\ifthenelse{\boolean{PROOFSONLY}}{
179: }
180: \end{abstract}
181:
182: \keywords{Abstract Interpretation, Denotational Semantics, Garbage Collection}
183:
184: %\category{F.3.1}{Logics and Meanings of Programs}{Specifying and Verifying and Reasoning about Programs}[Mechanical verification]
185: %\category{F.3.2}{Logics and Meanings of Programs}{Semantics of Programming Languages}[Program analysis]
186: %\category{D.3.3}{Programming Languages}{Language Constructs and Features}[Dynamic storage management]
187:
188: %\terms{languages, theory}
189:
190: %\keywords{Semantics, static analysis, abstract interpretation, garbage collection}
191:
192: %\maketitle
193: \end{opening}
194: %
195: \section{Introduction}\label{sec:introduction}
196: %
197: Escape analysis identifies, at compile-time, some
198: run-time data structures which do not \emph{escape}
199: from a given context,
200: in the sense that they are not reachable anymore from that context.
201: It has been studied for functional~\cite{ParkG92,Deutsch97,Blanchet98}
202: as well as for object-oriented
203: languages~\cite{RuggieriM88,Agrawal99,BogdaH99,WhaleyR99,GayS00,Ruf00,StreckenbachS00,RountevMR01,SalcianuR01,VivienR01,Blanchet03,ChoiGSSM03,WhaleyL04}.
204: It allows one to stack allocate dynamically created
205: data structures which would
206: normally be heap allocated. This is possible if these data structures
207: do not \emph{escape} from the method which created them.
208: Stack allocation reduces
209: garbage collection overhead at run-time \wrt heap allocation, since
210: stack allocated data structures are automatically deallocated when methods
211: terminate.
212: If, moreover, such data structures
213: do not occur in a loop and their size is statically determined,
214: they can be preallocated on the activation stack, which further
215: improves the efficiency of the code.
216: In the case of Java, which uses a mutual exclusion lock
217: for each object in order to synchronise accesses from different
218: threads of execution, escape analysis allows one also
219: to remove unnecessary synchronisations,
220: thereby making run-time accesses faster.
221: By removing the space for the mutual exclusion lock
222: associated with some of the objects,
223: escape analysis can also help with space constraints.
224: To this purpose, the analysis must
225: prove that an object is accessed by at most one thread.
226: This is possible if the object does not \emph{escape} its creating thread.
227:
228: \ifcorrx{%
229: Consider for instance our running example in Figure~\ref{fig:program}.
230: This program defines geometric figures \texttt{Square} and
231: \texttt{Circle} that can be rotated.
232: The class \texttt{Scan} has two methods, \texttt{scan} and
233: \texttt{rotate}. The method \texttt{scan} calls \texttt{rotate} on
234: each figure of a sequence \texttt{n} of figures passed as a parameter,
235: as well as on a new \texttt{Square} and a new \texttt{Circle}.
236: %
237: %% The method \texttt{scan} of the class \texttt{Scan} is used to call a method
238: %% \texttt{rotate} on each figure of a sequence \texttt{n} of figures
239: %% passed as a parameter, as well as to a new \texttt{Square} and a new
240: %% \texttt{Circle}.
241: %This method also creates two new figures and links
242: %these to the given sequence \texttt{n}.
243: Each \texttt{new} statement is a creation point and has been decorated
244: with a label, such as $\pi_1$ or $\pi_2$. We often abuse notation
245: and call the label a creation point itself. Hence, we can say
246: that the creation points $\pi_2$ and $\pi_3$ can be stack allocated since
247: they create objects which are not reachable once the method
248: \texttt{scan} terminates.
249: On the contrary,
250: the creation point $\pi_4$ cannot be allocated in the activation stack of
251: the method \texttt{rotate}, since the \texttt{Angle} it creates is
252: actually stored inside the field \texttt{rotation} of the \texttt{Square}
253: object created at $\pi_2$, which is still reachable when
254: \texttt{rotate} terminates. However, if we created \texttt{Circle}s rather than
255: \texttt{Square}s at $\pi_2$, and
256: if we assumed that the \texttt{scan} method
257: is passed a list of \texttt{Circle}s as parameter, then
258: the creation point $\pi_4$ could be stack
259: allocated, since the virtual call \texttt{f.rot(a)} would always lead
260: to the method \texttt{rot} inside \texttt{Circle}, which does not store
261: its parameter in any field. The creation point $\pi_1$ cannot be stack
262: allocated since it creates objects that are stored in the \texttt{rotation}
263: field, and hence are still reachable when the method completes.
264: Note that we assume here that an object escapes from a method if it is
265: still \emph{reachable} when the method terminates.
266: Others~\cite{Ruf00,SalcianuR01,WhaleyL04} require that
267: that object is actually \emph{used} after the method terminates.
268: Our assumption is more conservative and hence leads to less precise analyses.
269: However, it lets us analyse libraries, whose calling contexts are not known
270: at analysis time,
271: so that it is undetermined whether an object is actually used after a library
272: method terminates or not.
273: }
274: %
275: \subsection{Contributions of Our Work}\label{subsec:work}
276: %
277: This paper presents two escape analyses for Java programs. The goal
278: of both analyses is to detect objects that do not escape (\ie are
279: unreachable from outside) a certain scope. This information can later
280: be used to stack-allocate captured (\ie non-escaping) objects.
281:
282: Both analyses use the object allocation site model: all objects
283: allocated at a given program point (possibly in a loop) are
284: modelled by the same creation point. The first analysis, based
285: on the abstract domain $\e$,
286: expresses the information we need for our stack allocation. Namely,
287: for each program point, it provides
288: an over-approximation of the set of creation points
289: that escape because they are transitively reachable from a set
290: of escapability roots (\ie variables
291: including parameters, static fields, method
292: result). The domain $\e$
293: does not keep track of other information such as the creation points
294: pointed to by each individual variable or field.
295: %
296: \ifthenelse{\boolean{PROOFSONLY}}{
297: \addtocounter{figure}{1}
298: }{%%
299: \begin{figure}[ht]
300: {\small
301: $\begin{array}{l}
302: \mathtt{class\ Angle\ \{}\\
303: \mathtt{\ \ int\ degree;}\qquad\mathtt{int\ acute()\ \{\ return\ this.degree\ <\ 90;\ \}}\\
304: \mathtt{\}}\\
305: \mathtt{class\ Figure\ \{}\\
306: \mathtt{\ \ Figure\ next;}\\
307: \mathtt{\ \ void\ def()\ \{\}}\qquad\mathtt{void\ rot(Angle\ a)\ \{\}}
308: \qquad\mathtt{void\ draw()\ \{\}}\\
309: \mathtt{\}}\\
310: \mathtt{class\ Square\ extends\ Figure\ \{}\\
311: \mathtt{\ \ int\ side,\ x,\ y;}\qquad\mathtt{Angle\ rotation;}\\
312: \mathtt{\ \ void\ def()\ \{}\\
313: \mathtt{\ \ \ \ this.side\ =\ 1;\ this.x\ =\ this.y\ =\ 0;}\\
314: \mathtt{\ \ \ \ this.rotation\ =\ new\ Angle();}\qquad\{\pi_1\}\\
315: \mathtt{\ \ \ \ this.rotation.degree\ =\ 0;}\\
316: \mathtt{\ \ \}}\\
317: \mathtt{\ \ void\ rot(Angle\ a)\ \{\ this.rotation\ =\ a;\ \}}\\
318: \mathtt{\ \ void\ draw()\ \{\ ...\ use\ this.rotation\ here\ ...\ \}}\\
319: \mathtt{\}}\\
320: \mathtt{class\ Circle\ extends\ Figure\ \{}\\
321: \mathtt{\ \ int\ radius,\ x,\ y;}\\
322: \mathtt{\ \ void\ def()\ \{}\\
323: \mathtt{\ \ \ \ this.radius\ =\ 1;\ this.x\ =\ this.y\ =\ 0;}\qquad\{w_0\}\\
324: \mathtt{\ \ \}}\\
325: \mathtt{\ \ void\ draw()\ \{\ ...\ \}}\\
326: \mathtt{\}}\\
327: \mathtt{class\ Scan\ \{}\\
328: \mathtt{\ \ void\ scan(Figure\ n)\ \{}\\
329: \mathtt{\ \ \ \ Figure\ f\ =\ new\ Square();}\qquad\{\pi_2\}\\
330: \mathtt{\ \ \ \ f.next\ =\ f;}\qquad\{w_1\}\\
331: \mathtt{\ \ \ \ f.def();\ rotate(f);}\\
332: \mathtt{\ \ \ \ f\ =\ new\ Circle();}\qquad\{\pi_3\}\\
333: \mathtt{\ \ \ \ f.def();}\qquad\{w_2\}\\
334: \mathtt{\ \ \ \ f.next\ =\ n;}\\
335: \mathtt{\ \ \ \ while\ (f\ !=\ null)\ \{\ rotate(f);\ f\ =\ f.next;\ \}}\\
336: \mathtt{\ \ \}}\\
337: \mathtt{\ \ void\ rotate(Figure\ f)\ \{}\\
338: \mathtt{\ \ \ \ Angle\ a\ =\ new\ Angle();}\qquad\{\pi_4\}\\
339: \mathtt{\ \ \ \ f.rot(a);\ a.degree\ =\ 0;}\\
340: \mathtt{\ \ \ \ while\ (a.degree\ <\ 360)\ \{\ a.degree+\!\!+;\ f.draw();\ \}}\\
341: \mathtt{\ \ \}}\\
342: \mathtt{\}}
343: \end{array}$
344: %\begin{center}
345: %$\begin{array}{ll}
346: %\mathtt{class\ figure:} & \mathtt{class\ angle:}\\
347: %\text{field }\mathtt{next:figure} & \text{field }\mathtt{degree}:\integer\\
348: %\text{method }\mathtt{def():void}\text{ is empty}\hspace*{4ex} &
349: %\text{method }\mathtt{acute()}:\integer\text{ is}\\
350: %\text{method }\mathtt{rot(a:angle):void}\text{ is empty} &
351: %\ \ \mathtt{out:=this.degree<90;}\\
352: %\text{method }\mathtt{draw():void}\text{ is empty} & \\
353: %\mbox{} & \mathtt{class\ scan:}\\
354: %\mathtt{class\ square\ extends\ figure:} &
355: %\text{method }\mathtt{scan(n:figure):void}\text{ is}\\
356: %\text{fields }\mathtt{side},\mathtt{x},\mathtt{y}:\integer &
357: %\ \ \mathtt{f:figure;}\\
358: %\text{field }\mathtt{rotation:angle} &
359: %\ \ \mathtt{f:=new\ square;}\ \quad\{\pi_2\}\\
360: %\text{method }\mathtt{def():void}\text{ is} &
361: %\ \ \mathtt{f.next:=f;}\ \quad\quad\quad\{w_1\}\\
362: %\ \ \mathtt{this.side:=1;} &
363: %\ \ \mathtt{f.def();}\\
364: %\ \ \mathtt{this.x,this.y:=0;} &
365: %\ \ \mathtt{rotate(f);}\\
366: %\ \ \mathtt{this.rotation:=new\ angle;}\quad\{\pi_1\} &
367: %\ \ \mathtt{f:=new\ circle;}\ \quad\{\pi_3\}\\
368: %\ \ \mathtt{this.rotation.degree=0;} &
369: %\ \ \mathtt{f.def();}\qquad\qquad\quad\ \!\{w_2\}\\
370: %\text{method }\mathtt{rot(a:angle):void}\text{ is} &
371: %\ \ \mathtt{f.next:=n;}\\
372: %\ \ \mathtt{this.rotation:=a;} &
373: %\ \ \mathtt{while(f)}\\
374: %\text{method }\mathtt{draw():void}\text{ is} &
375: %\ \ \ \ \mathtt{rotate(f);}\quad\ \qquad\{w_3\}\\
376: %\ \ \text{\% use \texttt{this.rotation} here}\hspace*{2ex} &
377: %\ \ \ \ \mathtt{f:=f.next}\\
378: %\mbox{} & \text{method }\mathtt{rotate(f:figure):void}\text{ is}\\
379: %\mathtt{class\ circle\ extends\ figure:} & \ \ \mathtt{a:angle;}\\
380: %\text{fields }\mathtt{radius},\mathtt{x},\mathtt{y}:\integer &
381: %\ \ \mathtt{a:=new\ angle;}\qquad\{\pi_4\}\\
382: %\text{method }\mathtt{def():void}\text{ is} &
383: %\ \ \mathtt{f.rot(a);}\\
384: %\ \ \mathtt{this.radius:=1;} &
385: %\ \ \mathtt{a.degree:=0;}\\
386: %\ \ \mathtt{this.x,this.y:=0;}\qquad\quad\ \qquad\{w_0\} &
387: %\ \ \mathtt{while\ (a.degree<360)}\\
388: %\text{method }\mathtt{draw():void}\text{ is} &
389: %\ \ \ \ \mathtt{a.degree:=a.degree+1;}\\
390: %\ \ \text{\% put something here...} &
391: %\ \ \ \ \mathtt{f.draw();}
392: %\end{array}$
393: %\end{center}
394: }
395: \caption{Running example.}\label{fig:program}
396: \end{figure}
397: }%%\ifthenelse{\boolean{PROOFSONLY}{
398:
399: Although $\e$ is the property neede for stack allocation,
400: a static analysis based on $\e$
401: is not sufficiently precise as it does not relate the
402: creation points with the variables and fields that point to them. We
403: therefore consider a refinement $\er$ of $\e$ that preserves this
404: information and also includes $\e$ so that $\er$ contains just the
405: minimum information needed for stack allocation.
406:
407: %% As the abstract operations over
408: %% $\e$ are too imprecise, a second analysis, $\er$, is used instead. It is
409: %% a refinement of $\e$ that keeps track of the nodes pointed to by
410: %% individual variables and fields. We prove that $\er$ includes $\e$,
411: %% so that also $\er$ expresses the minimum information we need for
412: %% stack allocation.
413:
414: Both analyses are developed in the abstract interpretation
415: framework~\cite{CousotC77,CousotC92},
416: and we present proofs that the associated transfer functions
417: are optimal with respect to the abstractions that are used by each
418: analysis \ie they make the best possible use of the abstract information
419: expressed by the abstract domains.
420:
421: To increase the precision of the two analyses and to
422: get a Galois insertion, rather than a Galois connection, both
423: analyses use local variable scoping and type information.
424: Hence, the abstract domains contain no spurious element.
425: We achieve this goal through \emph{abstract garbage collectors}
426: which remove some elements from the abstract domains
427: whenever they reflect unreachable (and hence, for our analysis, irrelevant)
428: portions of the run-time heap,
429: as also~\cite{ChoiGSSM03} does, although~\cite{ChoiGSSM03} does not relate this
430: to the Galois insertion property.
431: %
432: Namely, the abstract domains are exactly the set of fixpoints of
433: their respective abstract garbage collectors and, hence, do not contain
434: spurious elements.
435:
436: The contribution of this paper is a clean construction of an escape
437: analysis through abstract interpretation thus obtaining formal and
438: detailed proofs of correctness as well as optimality.
439: Optimality states that the abstract domains are related to the
440: concrete domain by a Galois \emph{insertion}, rather than just a
441: \emph{connection} and in the use of optimal abstract operations.
442: %Moreover, it states that the abstract operations
443: %collectors both improve the precision and efficiency of
444: %the analyses and provide an elegant proof of
445: %the Galois insertion property.
446: %
447: Precision and efficiency of the analysis are not the main
448: issues here, although we are pleased to see that our implementation
449: scales to relatively large applications and
450: compares well with some already existing and more precise escape
451: analyses (Section~\ref{sec:implementation}).
452: %
453: %From a technical point of view,
454: %we achieve our goal through the definition of a basic abstract domain
455: %$\e$ which we then formally refine to the abstract domain
456: %$\er$ that we have actually implemented.
457: %
458: \subsection{The Basic Domain $\e$}\label{subsec:e}
459: %
460: Our work starts by defining a basic abstract domain $\e$ for escape analysis.
461: Its definition is guided by the observation that a creation point $\pi$
462: occurring
463: in a method $m$ can be stack allocated if the objects it creates are not
464: reachable at the end of $m$ from a set of
465: variables $E$ which includes $m$'s return value, the fields of the
466: objects bound to its formal parameters at call-time
467: (including the implicit $\this$ parameter)
468: and any exceptions thrown by $m$.
469: %
470: Note that we consider the
471: fields of the objects bound to the formal parameters at call-time
472: since they are aliases of the actual arguments, and hence still
473: reachable when the method returns.
474: %
475: For a language, such as Java, which allows static fields, $E$ also
476: includes the static fields.
477: Variables with integer type are not included in $E$ since no object
478: can be reached from an integer.
479: Moreover, local variables are also not included in $E$ since local variables
480: accessible inside a
481: method $m$ will disappear once $m$ terminates.
482: The basic abstract domain $\e$ is hence defined
483: as the collection of all sets of creation points. Each method
484: is decorated with an element of $\e$, which contains precisely the
485: creation points of the objects reachable from the variables in $E$
486: at the end of the method.
487: %
488: \begin{example}\label{ex:example_E}
489: \ifcorr{%
490: Consider for instance the method $\mathtt{scan}$ in Figure~\ref{fig:program}.
491: We assume that $\nil$
492: is passed to $\mathtt{scan}$ as a parameter, and that
493: its $\mathtt{this}$ object has been created at an external creation point
494: $\overline{\pi}$.
495: We have $\e=\wp(\{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\})$ and
496: $E=\{\mathtt{n}\}$
497: (the implicit parameter $\this$ has type $\mathtt{Scan}$ and hence no fields,
498: so that there is no need to consider it in $E$).
499: Then $\mathtt{scan}$ is decorated with $\emptyset$ since no
500: object can be reached at the end of $\mathtt{scan}$
501: from the variables in $E=\{\mathtt{n}\}$. Consequently, the creation points
502: $\pi_2$ and $\pi_3$ can be stack allocated since they do not belong
503: to $\emptyset$.
504: %
505: Note that, if $\mathtt{n}$ had been modified inside
506: the method $\mathtt{scan}$ then we would have used
507: $E=\{\mathtt{n}'\}$, where $\mathtt{n}'$ is a
508: \emph{shadow copy} of $\mathtt{n}$ which holds its \emph{initial} value
509: (we will see this technique in Example~\ref{ex:abstract_operations_er2}).
510: \qed
511: }
512: \end{example}
513:
514: We still have to specify how this decoration is computed for
515: each method. We use abstract interpretation to propagate an input
516: set of creation points through the statements of each method, until its end
517: is reached. This is accomplished by defining a \emph{transfer function}
518: for every statement of the program which, in terms of abstract interpretation,
519: is called an \emph{abstract operation}
520: %% PAT 1501: some rewording
521: (see Section~\ref{sec:edomain} and Figure~\ref{fig:operations_e}).
522: The element of $\e$ resulting
523: at the end of each method is then \emph{restricted} to the appropriate set $E$
524: for that method
525: through an abstract operation called $\mathsf{restrict}$.
526: By applying the theory of abstract interpretation, we know that this restriction
527: is a conservative approximation of the actual decoration we need at the end of
528: each method.
529:
530: \begin{example}\label{ex:e_imprecise}
531: \ifcorr{%
532: Consider again Example~\ref{ex:example_E}
533: and the method $\mathtt{scan}$.
534: In Figure~\ref{fig:e_imprecise}
535: we propagate the set $\{\overline{\pi}\}$ through $\mathtt{scan}$'s statements
536: by following the
537: translation of high-level statements into the \emph{bytecodes}
538: as specified in Figure~\ref{fig:operations_e}.
539: %(a more detailed description of part of this execution is presented
540: %in Example~\ref{ex:abstract_operations_e}).
541: %
542: }
543: \ifthenelse{\boolean{PROOFSONLY}}{
544: \addtocounter{figure}{1}
545: }{
546: \begin{figure}
547: \[\begin{array}{l}
548: \mathtt{void}\ \mathtt{scan}(\mathtt{Figure}\ \mathtt{n})\ \{\\
549: \{\overline{\pi}\}\\
550: \ \ \mathtt{Figure\ f\ =\ new\ Square();}\ \quad\{\pi_2\}\\
551: \{\overline{\pi},\pi_2\}\\
552: \ \ \mathtt{f.next\ =\ f;}\ \quad\{w_1\}\\
553: \{\overline{\pi},\pi_2\}\\
554: \ \ \mathtt{f.def();}\\
555: \{\overline{\pi},\pi_1,\pi_2\}\\
556: \ \ \mathtt{rotate(f);}\\
557: \{\overline{\pi},\pi_1,\pi_2,\pi_4\}\\
558: \ \ \mathtt{f\ =\ new\ Circle();}\ \quad\{\pi_3\}\\
559: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
560: \ \ \mathtt{f.def();}\\
561: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
562: \ \ \mathtt{f.next\ =\ n;}\\
563: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
564: \ \ \mathtt{while(f\ !=\ null)\ \{}\\
565: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
566: \ \ \ \ \mathtt{rotate(f);}\\
567: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
568: \ \ \ \ \mathtt{f\ =\ f.next;}\\
569: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
570: \ \ \mathtt{\}}\\
571: \mathtt{\}}
572: \end{array}\]
573: \caption{The propagation of $\{\overline{\pi}\}$ through the method $\mathtt{scan}$ of the program in Figure~\ref{fig:program}.}
574: \label{fig:e_imprecise}
575: \end{figure}
576: }
577: \ifcorrx{%
578: %
579: The restriction of the set $\{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}$ to
580: $E=\{\mathtt{n}\}$
581: is $\{\pi_1,\pi_2,\pi_3,\pi_4\}$
582: (objects of class $\mathtt{Scan}$ created at $\overline{\pi}$ are
583: incompatible with the type of $\mathtt{n}$), which is a very
584: imprecise approximation of the desired result \ie $\emptyset$.
585: \qed
586: }
587: \end{example}
588:
589: \ifthenelse{\boolean{PROOFSONLY}}{
590: \addtocounter{figure}{1}
591: }{
592: \begin{figure}[t]
593: \[\begin{array}{l}
594: \{\text{only $\mathtt{this}$ of type $\mathtt{Scan}$ is in scope here}\}\\
595: \mathtt{\{}\\
596: \ \ \ \mathtt{Figure\ f\ =\ new\ Square();}\quad\qquad\{\pi_s\}\\
597: \ \ \ \{p_1\!\}\\
598: \ \ \ \mathtt{f.def();}\qquad\{\text{this creates an object at $\pi_1$ (Figure
599: ~\ref{fig:program})}\}\\
600: \ \ \ \{p_2\!\}\\
601: \mathtt{\}}\\
602: \{p_3\!\}
603: \end{array}\]
604: \caption{A program fragment where the set of variables in scope grows
605: and shrinks.}\label{fig:abstract_garbage_collector}
606: \end{figure}
607: }
608:
609: The problem here is that although the abstract domain $\e$
610: expresses the kind of
611: decoration we need for stack allocation, $\e$ has very poor
612: computational properties. In terms of abstract interpretation, it
613: induces very imprecise
614: abstract operations and, just as in the case of the basic domain
615: $\mathcal{G}$ for \emph{groundness analysis} of logic
616: programs~\cite{JS87}, it needs refining~\cite{GiacobazziR97,Scozzari00}.
617:
618: \ifcorrx{%
619: Nevertheless, it must be observed that the abstract domain
620: $\e$ already contains some non-trivial information.
621: For instance, since $\overline{\pi}$ is a creation point
622: for objects of class $\mathtt{Scan}$
623: and $\pi_2$ is a creation point for objects of class
624: $\mathtt{Square}$, then the first $\mathtt{f.def()}$ virtual call
625: occurring in the method $\mathtt{scan}$ can only lead to
626: the method $\mathtt{def}$ inside $\mathtt{Square}$.
627: Hence we say that
628: \emph{our escape information contains information
629: on the run-time late-binding mechanism}, which can be exploited
630: to improve the precision of the analysis by refining the
631: call-graph.
632: This is what actually happens in Example~\ref{ex:e_imprecise}.
633: Note also that
634: the local scope may temporarily introduce new variables so that
635: at the end of the scope,
636: any creation points that can \emph{only} be reached from these variables
637: can be safely removed from the approximation. In
638: Figure~\ref{fig:abstract_garbage_collector}, the approximation computed at
639: $p_2$ is $\{\overline{\pi},\pi_s,\pi_1\}$, where $\overline{\pi}$
640: is the creation point of $\mathtt{this}$, but the approximation computed at
641: $p_3$ is $\{\overline{\pi}\}$, which is smaller.
642: For this reason, we say that
643: \emph{our escape information uses the static type information} to improve
644: the precision of the analysis.
645: That is, the possible approximations from $\e$ in a given program point,
646: are constrained by the (finite) set of
647: variables and their types that are in scope.
648: %Note that this \emph{static type information} is
649: %independent of the choice of analyser as it is
650: %available before the analysis takes place.
651: }
652:
653: We formalise the fact that the approximation in $\e$ can shrink,
654: by means of an \emph{abstract garbage collector}
655: (Definition~\ref{def:delta})
656: \ie a garbage collector that works over sets of creation points
657: instead of concrete objects. When a variable's scope is
658: closed, the abstract garbage collector
659: removes from the approximation of the next statement all
660: creation points which can \emph{only} be reached \emph{from that variable}.
661: The name of abstract garbage collector is justified by the fact that
662: this conservatively maintains in the approximation the creation points of the
663: objects which \emph{might} be reachable in the concrete state, thus
664: modeling in the abstract domain a behaviour similar to that of a concrete
665: garbage collector. It must be noted, however, that our abstract garbage
666: collector only considers reachability from the variables in scope in the
667: current method, while
668: a concrete garbage collector would consider reachability from all variables
669: in the current activation stack.
670:
671: \ifcorrx{%
672: The abstract garbage collector is of no use in
673: the propagation of $\bar{\pi}$ shown in Figure~\ref{fig:e_imprecise}
674: since, for instance,
675: after the creation point $\pi_3$, it is not possible to conclude
676: that the object $o$ created at $\pi_2$, and hence also those created at
677: $\pi_1$ and $\pi_4$ and stored in $o$'s $\mathtt{rotation}$ field,
678: are not reachable anymore.
679: This is because $\e$
680: does not distinguish between the
681: objects reachable from variables
682: \texttt{f} and \texttt{n}. Before $\pi_3$, the object $o$ created at
683: $\pi_2$ can be reached from \texttt{f} only,
684: but $\pi_3$ overwrites \texttt{f} so it cannot
685: be reached anymore. Because $\e$ does not make a distinction
686: between objects reachable from \texttt{f} and \texttt{n},
687: it cannot infer this, because
688: it considers that $o$ could be reachable from \texttt{n}.
689: The only safe choice is to
690: be conservative and assume that it cannot be garbage collected.
691: }
692: %Any escape property at program point $p_2$ must include both
693: %$\pi_s$ and $\pi_1$ since they are the creation points of objects
694: %bound to $\mathtt{f}$ and $\mathtt{f.rotation}$, respectively.
695: %However, the escape property at program point $p_3$ does not need to include
696: %$\pi_s$ and $\pi_1$ since only $\mathtt{this}$
697: %of type $\mathtt{scan}$ is in the scope at $p_3$.
698: %At $\pi_s$ and $\pi_1$ no objects of
699: %classes that are compatible with $\mathtt{scan}$ are created,
700: %so that
701: %the set of creation points of the objects reachable from the variables in scope
702: %will shrink
703: %when passing from program point $p_2$ to program point $p_3$
704: %in Figure~\ref{fig:abstract_garbage_collector}.
705: %Therefore, from an implementation point of view,
706: %an \emph{abstract garbage collector}
707: %(\ie a garbage collector that works
708: %over sets of creation points instead of concrete objects)
709: %could be applied here.
710:
711: %In an object-oriented language, a virtual call can lead at run-time to
712: %many targets. A good approximation of the set of such targets improves the
713: %precision of the analysis~\cite{TipP00}.
714: %Consider, for instance, Figure~\ref{fig:abstract_garbage_collector}. There are
715: %three possible targets for the $\mathtt{f.def()}$ method call, which
716: %are selected on the basis of the class of the object bound to
717: %$\mathtt{f}$; they are the methods identified by $\mathtt{def}$ in
718: %classes $\mathtt{figure}$, $\mathtt{square}$ and $\mathtt{circle}$ in
719: %Figure~\ref{fig:program}. However, the escape property at program
720: %point $p_1$ contains enough information to conclude that the only
721: %possible target of that method call is the method $\mathtt{def}$ of
722: %the class $\mathtt{square}$. This is because no creation points for
723: %the objects $\mathtt{circle}$ and $\mathtt{figure}$ belong to the
724: %escape property at $p_1$.
725:
726: %Previous work on escape analysis for object-oriented languages has always
727: %defined the analysis from its applications (stack allocation, synchronisation
728: %removal) and has neglected to provide an exact definition of the
729: %\emph{escape property} \ie of the abstract property of the states of
730: %the computation which is the result of an escape analysis.
731: %As a consequence, other escape analyses are difficult to compare
732: %\wrt precision, since a formal definition of the reference property%(the escape property) is missing.
733: %On the other hand, the previous two observations show that we can construct
734: %examples where a static analysis based on $\e$ is more precise than any other
735: %escape analysis defined so far. In particular, we have shown that,
736: %for the program fragment in Figure~\ref{fig:abstract_garbage_collector},
737: %with domain $\e$, we can conclude that, at program point $p_3$, the creation
738: %point $\pi_s$ does not belong to the escape property and that all the
739: %creation points inside the methods $\mathtt{def}$ of $\mathtt{circle}$ or
740: %$\mathtt{figure}$ (if any) do not belong to the escape property in $p_2$,
741: %since those methods cannot be the target of the method call $\mathtt{f.def()}$.
742: %By contrast, other escape analyses have assumed that $\mathtt{f.def()}$
743: %could select any one of these targets and it is well-known from considerations
744: %related to class analysis~\cite{TipP00} that this assumption will result in
745: %a precision loss.
746: %Note that we are not claiming that $\e$ should be
747: %used instead of the other domains already developed for escape analysis;
748: %the importance of $\e$ is mainly theoretical, as a reference for comparing
749: %the precision of other escape analyses and as the starting point
750: %for the definition of more precise escape analyses. However,
751: %it is reasonable to assume that \emph{any domain for escape analysis
752: %includes $\e$}. This well-foundedness requirement is traditional in
753: %abstract interpretation, since it means that the escape analysis
754: %is \emph{at least} as precise as the property it wants to capture.
755:
756: %For instance, every abstract domain for
757: %groundness analysis of logic programs includes the \emph{groundness property}
758: %$\mathcal{G}$~\cite{JS87,ArmstrongMSS98}.
759: %But the above two considerations mean that no escape
760: %analysis defined so far includes $\e$ (\ie is at least as precise as $\e$).
761: %This justifies, \emph{a posteriori}, our quest for
762: %a formal definition of $\e$, from which other domains for escape
763: %analysis can be derived by refinement and have at least the precision of $\e$.
764: %
765: \subsection{The Refinement $\er$}\label{subsec:er}
766: %
767: The abstract domain $\e$ represents the information we need for
768: stack allocation, but it does not
769: include any other related information that may improve
770: the precision of the abstract operations,
771: such as explicit information
772: about the creation points of the objects bound to
773: \emph{a given} variable or field.
774: However, the ability to reason on a per variable basis is essential for
775: the precision of a static analysis of imperative languages, where assignment
776: to a given variable or field is the basic computational mechanism.
777: So we \emph{refine} $\e$ into a new abstract domain $\er$ which
778: splits the sets of creation points in $\e$ into
779: subsets, one for each variable or field.
780: We show that $\er$ strictly contains $\e$, justifying the name
781: of \emph{refinement}.
782:
783: We perform a static analysis based on $\er$ exactly as for $\e$
784: but using the abstract operations for the domain $\er$
785: given in Section~\ref{sec:erdomain} (see Figure~\ref{fig:operations_er}).
786: %
787: \begin{example}\label{ex:er_precision}
788: \ifcorr{%
789: Consider again the method $\mathtt{scan}$ in Figure~\ref{fig:program}.
790: We start the analysis from the element $[\mathtt{this}\mapsto
791: \{\overline{\pi}\}]\sep[]$ of $\er$ which expresses the fact that the variable
792: $\mathtt{this}$ is initially bound to an object created at the
793: external creation point $\overline{\pi}$ and all other variables and
794: fields are initially bound to $\nil$ (if they have class type)
795: or to an integer (otherwise).
796: The operator $\sep$ is a pair-separator; its component
797: $[\mathtt{this}\mapsto\{\overline{\pi}\}]$ is the approximation for
798: the variables in scope and
799: its component $[]$ is the approximation for the fields.
800: The information is then propagated, as shown
801: in Figure~\ref{fig:er_precision}.
802: %(a more detailed description of part of this execution is presented
803: %in Example~\ref{ex:abstract_operations_er}).
804: Then, just as for the domain $\e$, at the end of the method the result
805: $[\mathtt{this}\mapsto\{\overline{\pi}\}]\sep[]$ is restricted
806: to $E=\{\mathtt{n}\}$ and we get
807: $[]\sep[]$, which leads to $\emptyset$ which is a
808: much more precise approximation
809: than the set $\{\pi_1,\pi_2,\pi_3,\pi_4\}$
810: obtained in Example~\ref{ex:e_imprecise} with $\e$.
811: }
812: %
813: \ifthenelse{\boolean{PROOFSONLY}}{
814: \addtocounter{figure}{1}
815: }{
816: \begin{figure}
817: \[\begin{array}{l}
818: \mathtt{void\ scan(Figure\ n)\ \{}\\
819:
820: [\mathtt{this}\mapsto\{\overline{\pi}\}]\sep[]\\
821: \ \ \mathtt{Figure\ f\ =\ new\ Square();}\ \quad\{\pi_2\}\\
822:
823: [\mathtt{f}\mapsto\{\pi_2\},\mathtt{this}\mapsto\{\overline{\pi}\}]\sep[]\\
824: \ \ \mathtt{f.next\ =\ f;}\\
825:
826: [\mathtt{f}\mapsto\{\pi_2\},\mathtt{this}\mapsto\{\overline{\pi}\}]
827: \sep[\mathtt{next}\mapsto\{\pi_2\}]\\
828: \ \ \mathtt{f.def();}\\
829:
830: [\mathtt{f}\mapsto\{\pi_2\},\mathtt{this}\mapsto\{\overline{\pi}\}]
831: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1\}}]\\
832: \ \ \mathtt{rotate(f);}\\
833:
834: [\mathtt{f}\mapsto\{\pi_2\},\mathtt{this}\mapsto\{\overline{\pi}\}]
835: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1,\pi_4\}}]\\
836: \ \ \mathtt{f\ =\ new\ Circle();}\ \quad\{\pi_3\}\\
837:
838: [\mathtt{f}\mapsto\{\pi_3\},\mathtt{this}\mapsto\{\overline{\pi}\}]
839: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1,\pi_4\}}]\\
840: \ \ \mathtt{f.def();}\\
841:
842: [\mathtt{f}\mapsto\{\pi_3\},\mathtt{this}\mapsto\{\overline{\pi}\}]
843: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1,\pi_4\}}]\\
844: \ \ \mathtt{f.next\ =\ n;}\\
845:
846: [\mathtt{f}\mapsto\{\pi_3\},\mathtt{this}\mapsto\{\overline{\pi}\}]
847: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1,\pi_4\}}]\\
848: \ \ \mathtt{while(f\ !=\ null)\ \{}\\
849:
850: [\mathtt{f}\mapsto\{\pi_2,\pi_3\},\mathtt{this}\mapsto\{\overline{\pi}\}]
851: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1,\pi_4\}}]\\
852: \ \ \ \ \mathtt{rotate(f);}\\
853:
854: [\mathtt{f}\mapsto\{\pi_2,\pi_3\},\mathtt{this}\mapsto\{\overline{\pi}\}]
855: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation\mapsto\{\pi_1,\pi_4\}}]\\
856: \ \ \ \ \mathtt{f\ =\ f.next;}\\
857:
858: \ \ \mathtt{\}}\\
859:
860: [\mathtt{this}\mapsto\{\overline{\pi}\}]\sep[]\\
861:
862: \mathtt{\}}
863: \end{array}\]
864: \caption{The propagation of $[\mathtt{this}\mapsto\{\overline{\pi}\}]\sep[]$ through the method $\mathtt{scan}$ of the program in Figure~\ref{fig:program}.}
865: \label{fig:er_precision}
866: \end{figure}
867: }
868:
869: \ifcorrx{%
870: Note that at the end of the method
871: (when $\mathtt{f}$ and $\mathtt{n}$ go out of scope),
872: the approximation of the fields $\mathtt{next}$ and
873: $\mathtt{rotation}$ are reset to $\emptyset$.
874: The justification for this is that, at this point, it is no longer
875: possible to reach the $\mathtt{Square}$ object created at $\pi_2$
876: whose field $\mathtt{rotation}$ contained objects created at
877: $\pi_1$ or $\pi_4$, nor is it
878: possible to reach the $\mathtt{Circle}$ object created at
879: $\pi_3$ whose $\mathtt{next}$ field might have contained something
880: created at $\pi_2$. This is an example of the application
881: of our abstract garbage collector for $\er$ (Definition~\ref{def:xi}).
882: \qed
883: }
884: \end{example}
885:
886: The domain $\er$ can hence be seen as the specification of a new escape
887: analysis, which includes $\e$ as its foundational kernel.
888: Example~\ref{ex:er_precision} shows that the abstract domain
889: $\er$ is actually more precise than $\e$.
890: Our implementation of $\er$ (Section~\ref{sec:implementation}) shows that
891: it can actually be
892: used to obtain non-trivial escape analysis information for Java bytecode.
893: %Our implementation of $\er$
894: %confirms that it is indeed more precise than $\e$.
895:
896: %Figure~\ref{fig:analyses} gives a pictorial representation of the relationship
897: %between $\e$, $\er$ and the other escape analyses defined so far.
898: %It can be seen
899: %that only $\er$ includes $\e$, while the other escape analyses are
900: %elliptical \wrt the same property $\e$ they want to capture.
901: %
902: %\begin{figure}[t]
903: %\begin{center}
904: %\setlength{\unitlength}{1mm}
905: %\begin{picture}(-100,20)(50,-10)
906: %\linethickness{0.4pt}
907: %\put(0,0){\circle{12}}
908: %\put(-1,-1){$\e$}
909: %\put(5,5){\ellipse{30}{20}}
910: %\put(10,5){other}
911: %\put(-5,0){\ellipse{30}{20}}
912: %\put(-15,-1){$\er$}
913: %\end{picture}
914: %\epsfig{file=analyses.eps, width=4cm, height=3cm}
915: %\end{center}
916: %\caption{The relationship of the escape analyses \wrt precision.}
917: % \label{fig:analyses}
918: %\end{figure}
919: %
920: \subsection{Structure of the Paper}\label{subsec:structure}
921: %
922: After a brief summary of our notation and terminology
923: in Section~\ref{sec:preliminaries}, we pass
924: in Section~\ref{sec:framework} to recall the framework
925: of~\cite{SpotoJ03} on which the analysis is based.
926: Then, in Section~\ref{sec:edomain}, we formalise our basic domain $\e$
927: and provide suitable abstract operations for its analysis.
928: We show that the analysis induced by $\e$ is very imprecise.
929: Hence, in Section~\ref{sec:erdomain} we refine the domain $\e$ into the
930: more precise domain $\er$ for escape analysis.
931: In Section~\ref{sec:implementation},
932: we discuss our prototype implementation and experimental results.
933: Section~\ref{sec:discussion} discusses related work.
934: Section~\ref{sec:conclusion} concludes the main part of the paper.
935: \ifthenelse{\boolean{WITHAPPENDIX}}{%%
936: } %%\ifthenelse{\boolean{WITHAPPENDIX}}{%%
937: {Proofs not inlined in this paper are available in~\cite{corr-version}.
938: } %%\ifthenelse{\boolean{WITHAPPENDIX}}{%%
939:
940: Preliminary, partial versions of this paper appeared in~\cite{HillS02b}
941: and~\cite{HillS02}.
942: The current paper is a seamless
943: fusion of these papers, with the proofs of the theoretical results and
944: with a description and evaluation of the implementation of the escape analysis
945: over the domain $\er$.
946: %
947: \section{Preliminaries}\label{sec:preliminaries}
948: %
949: A total (partial) function $f$ is denoted by $\mapsto$ ($\to$).
950: The \emph{domain} (\emph{range}) of $f$ is $\domain(f)$ ($\codom(f)$).
951: We denote by $[v_1\!\mapsto\!t_1,\ldots,v_n\!\mapsto\!t_n]$ the function $f$
952: where $\domain(f) = \{v_1,\ldots,v_n\}$ and $f(v_i)=t_i$ for
953: $i=1,\ldots,n$.
954: Its \emph{update} is $f[w_1\mapsto d_1,\ldots,w_m\mapsto d_m]$,
955: where the domain may be enlarged.
956: By $f|_s$ ($f|_{-s}$) we denote the
957: \emph{restriction} of $f$ to $s\subseteq\domain(f)$
958: (to $\domain(f)\setminus s$).
959: If $f$ and $g$ are functions,
960: we denote by $fg$ the composition of $f$ and $g$,
961: such that $fg(x)=f(g(x))$.
962: If $f(x)=x$ then $x$ is a \emph{fixpoint} of $f$.
963: The set of fixpoints of $f$ is denoted by $\fp(f)$.
964:
965: A \emph{pair} of elements is written $a\sep b$.
966: A definition of a pair $S$ such as
967: $S=a\sep b$, with $a$ and $b$ meta-variables,
968: silently defines the pair selectors $s.a$ and $s.b$ for $s\in S$.
969: The cardinality of a set $S$ is denoted by $\# S$.
970: The \emph{disjoint union} of two sets $S, T$ is denoted by $S + T$.
971: To simplify expressions, particulary when the set is used as a subscript,
972: we sometimes write a singleton set $\{x\}$ as $x$.
973: %% like $l$ in $=_l$ in the definition of $\mathsf{put\_field}$
974: %% (Figure~\ref{fig:concrete_states}).
975: If $S$ is a set and $\le$ is a partial relation over $S$, we say that $S$
976: is a \emph{partial ordering} if it is reflexive ($s\le s$ for every
977: $s\in S$), transitive ($s_1\le s_2$ and $s_2\le s_3$ entail
978: $s_1\le s_2$ for every $s_1,s_2,s_3\in S$) and
979: anti-symmetric ($s_1\le s_2$ and $s_2\le s_1$ entail
980: $s_1=s_2$ for every $s_1,s_2\in S$).
981: If $S$ is a set and $\le$ a partial ordering on $S$, then
982: the pair $S\sep\le$ is a \emph{poset}.
983:
984: A \emph{complete lattice} is a poset $\mathit{C}\sep\mathord\le$
985: where \emph{least upper bounds}
986: (lub) and \emph{greatest lower bounds} (glb) always exist. Let
987: $\mathit{C}\sep\mathord\le$ and $\mathit{A}\sep\mathord\preceq$ be posets and
988: $f:\mathit{C}\mapsto\mathit{A}$. We say that $f$ is \emph{monotonic}
989: if $c_1\le c_2$ entails $f(c_1)\preceq f(c_2)$. It is
990: \emph{(co-)additive} if it preserves lub's (glb's).
991: Let $f:\mathit{A}\mapsto\mathit{A}$.
992: The map $f$ is \emph{reductive} (respectively, \emph{extensive}) if
993: $f(a)\preceq a$ (respectively, $a\preceq f(a)$) for any $a\in\mathit{A}$.
994: It is \emph{idempotent} if $f(f(a))=f(a)$ for any $a\in\mathit{A}$.
995: It is a \emph{lower closure operator}
996: (\emph{lco}) if it is \emph{monotonic}, \emph{reductive}
997: and \emph{idempotent}.
998:
999: We recall now the basics of abstract
1000: interpretation~\cite{CousotC77,CousotC92}.
1001: Let $\mathit{C}\sep\mathord\le$ and
1002: $\mathit{A}\sep\mathord\preceq$ be two posets (the concrete and
1003: the abstract domain). A \emph{Galois connection}
1004: is a pair of monotonic maps $\alpha:\mathit{C}\mapsto\mathit{A}$ and
1005: $\gamma:\mathit{A}\mapsto\mathit{C}$ such that
1006: $\gamma\alpha$ is extensive and $\alpha\gamma$ is reductive. It is a
1007: \emph{Galois insertion} when $\alpha\gamma$ is the identity map \ie
1008: when the abstract domain does not contain \emph{useless} elements.
1009: If $C$ and $A$ are complete lattices and $\alpha$ is strict and
1010: additive, then $\alpha$ is the
1011: abstraction map of a Galois connection.
1012: If, moreover, $\alpha$ is onto or $\gamma$ is one-to-one, then
1013: $\alpha$ is the abstraction map of a Galois insertion.
1014: In a Galois connection, $\gamma$ can be defined in terms of $\alpha$ as
1015: $\gamma(a)=\cup\{c\mid \alpha(c)\preceq a\}$, where $\cup$ is the
1016: least upper bound operation over the concrete domain $C$.
1017: Hence, it is enough to provide $\alpha$ to define a Galois connection.
1018: %
1019: An abstract operator $\hat{f}:\mathit{A}^n\mapsto\mathit{A}$ is
1020: \emph{correct} \wrt $f:\mathit{C}^n\rightarrow\mathit{C}$
1021: if $\alpha f\gamma\preceq\hat{f}$. For each operator $f$, there exists
1022: an \emph{optimal} (most precise) correct abstract operator $\hat{f}$ defined
1023: as $\hat{f}=\alpha f\gamma$.
1024: %PAT0704 rewording
1025: This means that $\hat{f}$ does the best it can with the information
1026: expressed by the abstract domain.
1027: %PAT0704 end
1028: The composition of correct operators is correct.
1029: The composition of optimal operators is not necessarily optimal.
1030: %
1031: The \emph{semantics} of a program is the fixpoint of a map
1032: $f:\mathit{C}\mapsto\mathit{C}$, where $\mathit{C}$ is the
1033: \emph{computational domain}. Its
1034: \emph{collecting version}~\cite{CousotC77,CousotC92}
1035: works over \emph{properties} of $\mathit{C}$ \ie over
1036: $\wp(\mathit{C})$ and is the fixpoint of the powerset extension of $f$.
1037: If $f$ is defined through suboperations, their powerset extensions
1038: \emph{and $\cup$} (which merges the semantics of the branches of a conditional)
1039: induce the extension of $f$.
1040: %
1041: \section{The Framework of Analysis}\label{sec:framework}
1042: %
1043: The framework presented here is for a simple typed object-oriented language
1044: where the concrete states and operations are based on~\cite{SpotoJ03}.
1045: It allows us to derive a compositional, denotational semantics,
1046: which can be seen as an
1047: analyser, from a specification of
1048: a domain of abstract states and operations which work over them
1049: (hence called \emph{state transformers}).
1050: Then problems such as scoping, recursion and name clash can be ignored,
1051: since these are already solved by the semantics.
1052: Moreover, this framework relates the precision of the analysis to that
1053: of its abstract domain so that traditional techniques for comparing the
1054: precision of abstract domains can be
1055: applied~\cite{CortesiFW98,CousotC77,CousotC92}.
1056:
1057: The definition of a denotational semantics, in the style
1058: of~\cite{Winskel93}, by using the state transformers
1059: of this section can be found in~\cite{SpotoJ03}. Here we only want
1060: to make clear some points:
1061: %
1062: \begin{itemize}
1063: \item We allow expressions to have side-effects, such as method call
1064: expressions, which is not the case
1065: in~\cite{Winskel93}. As a consequence, the evaluation of an expression
1066: from an initial state yields both a final state \emph{and} the value of
1067: the expression. We use a special variable $\rs$ of the final
1068: state to hold this value;
1069: \item The evaluation from an initial state $\sigma_1$ of a binary operation
1070: such as $e_1+e_2$, where $e_1$ and $e_2$ are
1071: expressions, first evaluates $e_1$ from $\sigma_1$, yielding
1072: an intermediate state $\sigma_2$, and then evaluates
1073: $e_2$ from $\sigma_2$, yielding a state $\sigma_3$.
1074: The value $v_1$ of $\rs$ in $\sigma_2$ is that of $e_1$, and the value
1075: $v_2$ of $\rs$ in $\sigma_3$ is that of $e_2$. We then modify
1076: $\sigma_3$ by storing in $\rs$ the sum $v_1+v_2$. This yields the
1077: final state.
1078: Note that the single variable $\rs$ is enough for this
1079: purpose. The complexity of this mechanism \wrt~a more
1080: standard approach~\cite{Winskel93} is,
1081: again, a consequence of the use of expressions with side-effects;
1082: \item Our denotational semantics deals with method calls through
1083: \emph{interpretations}: an interpretation is the input/output
1084: behaviour of a method, and is used as its denotation whenever
1085: that method is called.
1086: %This yields a fully context-sensitive
1087: %semantics and analysis.
1088: As a nice consequence,
1089: our states contain only a single frame, rather than
1090: an activation stack of frames.
1091: This is standard in denotational semantics and has been used
1092: for years in logic programming~\cite{BossiGLM94}.
1093: \item The computation of the semantics of a program starts from a
1094: bottom interpretation which maps every input state
1095: to an undefined final state and then
1096: updates this interpretation with the denotations of the methods body.
1097: This process is iterated until a fixpoint is reached as is done for
1098: logic programs~\cite{BossiGLM94}.
1099: The same technique can be applied
1100: to compute the abstract semantics of a program, but the computation is
1101: performed over the abstract domain. It is also possible to generate
1102: constraints which relate the abstract approximations at different
1103: program points, and then solve such constraints with a fixpoint engine.
1104: The latter is the technique that we use in
1105: Section~\ref{sec:implementation}.
1106: \end{itemize}
1107:
1108: %Focused means that abstract information is computed just for a given set
1109: %of program points (\emph{watchpoints}) and the complexity of this computation
1110: %is related to the number of watchpoints.
1111: %We use the watchpoints to \emph{bracket} a program method inside two
1112: %watchpoints, that will hence allow us to detect which creation points
1113: %can be stack allocated (Section~\ref{sec:implementation}).
1114: %
1115: \ifthenelse{\boolean{PROOFSONLY}}{
1116: \addtocounter{figure}{1}
1117: }{
1118: \begin{figure}[t]
1119: \begin{center}
1120: {\small
1121: \begin{gather}
1122: \mathcal{K}=\left\{\begin{array}{l}
1123: \mathtt{Angle},\\
1124: \mathtt{Figure},\\
1125: \mathtt{Square},\\
1126: \mathtt{Circle},\\
1127: \mathtt{Scan}
1128: \end{array}\right\}\quad
1129: \mathcal{M}=\left\{\begin{array}{l}
1130: \mathtt{Angle.acute},\\
1131: \mathtt{Figure.def},
1132: \mathtt{Figure.rot},\mathtt{Figure.draw},\\
1133: \mathtt{Square.def},
1134: \mathtt{Square.rot},\mathtt{Square.draw},\\
1135: \mathtt{Circle.def},
1136: \mathtt{Circle.draw},\\
1137: \mathtt{Scan.scan},\mathtt{Scan.rotate}
1138: \end{array}\right\}\notag\\
1139: \mathtt{Square}\le\mathtt{Figure},\quad\mathtt{Circle}\le\mathtt{Figure}
1140: \quad\text{and reflexive cases}\notag\\
1141: \begin{align*}
1142: F(\mathtt{Angle})&=[\mathtt{degree}\mapsto\integer]\qquad
1143: F(\mathtt{Scan})=[]\\
1144: F(\mathtt{Figure})&=[\mathtt{next}\mapsto\mathtt{Figure}]\\
1145: F(\mathtt{Square})&=\left[\begin{array}{l}
1146: \mathtt{side}\mapsto\integer,\mathtt{Square.x}\mapsto\integer,
1147: \mathtt{Square.y}\mapsto\integer,\\
1148: \mathtt{rotation}\mapsto\mathtt{Angle},\mathtt{next}\mapsto\mathtt{Figure}
1149: \end{array}\right]\\
1150: F(\mathtt{Circle})&=\left[\begin{array}{l}
1151: \mathtt{radius}\mapsto\integer,\mathtt{Circle.x}\mapsto\integer,\\
1152: \mathtt{Circle.y}\mapsto\integer,\mathtt{next}\mapsto\mathtt{Figure}
1153: \end{array}\right]
1154: \end{align*}\\
1155: \begin{align*}
1156: M(\mathtt{Angle})&=[\mathtt{acute}\mapsto\mathtt{Angle.acute}]\\
1157: M(\mathtt{Figure})&=\left[\begin{array}{l}
1158: \mathtt{def}\mapsto\mathtt{Figure.def},\mathtt{rot}\mapsto
1159: \mathtt{Figure.rot},\\
1160: \mathtt{draw}\mapsto\mathtt{Figure.draw}
1161: \end{array}\right]\\
1162: M(\mathtt{Square})&=
1163: \left[\begin{array}{l}
1164: \mathtt{def}\mapsto
1165: \mathtt{Square.def},\mathtt{rot}\mapsto
1166: \mathtt{Square.rot},\\
1167: \mathtt{draw}\mapsto\mathtt{Square.draw}
1168: \end{array}\right]\\
1169: M(\mathtt{Circle})&=
1170: \left[\begin{array}{l}
1171: \mathtt{def}\mapsto\mathtt{Circle.def},\mathtt{rot}\mapsto
1172: \mathtt{Figure.rot},\\
1173: \mathtt{draw}\mapsto\mathtt{Circle.draw}
1174: \end{array}\right]\\
1175: M(\mathtt{Scan})&=
1176: [\mathtt{scan}\mapsto\mathtt{Scan.scan},\mathtt{rotate}\mapsto
1177: \mathtt{Scan.rotate}]
1178: \end{align*}\\
1179: \begin{align*}
1180: P(\mathtt{Angle.acute})&=[\Out\mapsto\integer,\mathtt{this}
1181: \mapsto\mathtt{Angle}]\\
1182: P(\mathtt{Figure.rot})&=[\mathtt{a}\mapsto\mathtt{Angle},
1183: \Out\mapsto\integer,\mathtt{this}\mapsto\mathtt{Figure}]\\
1184: P(\mathtt{Scan.rotate})&=[\mathtt{f}\mapsto\mathtt{Figure},
1185: \Out\mapsto\integer,\mathtt{this}\mapsto\mathtt{Scan}]\\
1186: P(\mathtt{Figure.def})&=[\Out\mapsto\integer,\mathtt{this}
1187: \mapsto\mathtt{Figure}]\\
1188: &\text{(the other cases of $P$ are as above)}
1189: \end{align*}
1190: \end{gather}}\normalsize
1191: \end{center}
1192: \caption{The static information of the program in Figure \ref{fig:program}.}
1193: \label{fig:static_information}
1194: \end{figure}
1195: }
1196: %
1197: \subsection{Programs and Creation Points}\label{subsec:creation_points}
1198: %
1199: We recall here the semantical framework of~\cite{SpotoJ03}.
1200: %
1201: \begin{definition}[Type Environment]\label{def:typing}
1202: Each program in the language has a finite set of \emph{identifiers} $\Id$
1203: such that $\Out, \this \in \Id$ and
1204: a finite set of \emph{classes} $\mathcal{K}$ ordered by
1205: a \emph{subclass relation} $\le$ such that
1206: $\mathcal{K}\sep\mathord\le$ is a poset. % and $\mathtt{scan}\in\mathcal{K}$.
1207: Let $\Type = \{\integer\} \uplus \mathcal{K}$ and
1208: $\le$ be extended to $\Type$ by defining $\integer\le\integer$.
1209: Let $\Vars\subseteq\Id$ be a set of \emph{variables} such that
1210: $\{\Out,\this\} \subseteq \Vars$.
1211: A \emph{type environment} for a program is any element of the set
1212: \[
1213: \Typing=\left\{\tau:\Vars\to\Type\left|\begin{array}{l}
1214: \text{if }\this\in\domain(\tau)\text{ then }\tau(\this)
1215: \in\mathcal{K}\end{array}\right.\right\}.
1216: \]
1217: In the following, $\tau$ will implicitly stand for a type environment.
1218: \end{definition}
1219:
1220: A class contains local variables (\emph{fields})
1221: and functions (\emph{methods}). A method has
1222: a set of input/output variables called \emph{parameters}, including
1223: \texttt{out}, which holds the result of the method, and
1224: \texttt{this}, which is the object over which the method has been called
1225: (the \emph{receiver} of the call).
1226: Methods returning $\mathtt{void}$ are represented
1227: as methods returning an $\integer$ of constant value $0$,
1228: implicitly ignored by the caller of the method.
1229:
1230: \begin{example}
1231: \label{ex:type-environment}
1232: \ifcorr{%
1233: Consider the example program given in Figure~\ref{fig:program}.
1234: Here $\Id$ includes, in addition to the identifiers
1235: $\Out$ and $\this$, user-defined identifiers such as
1236: \(
1237: \mathtt{rotation},
1238: \mathtt{def},
1239: \mathtt{x},
1240: \mathtt{y},
1241: \mathtt{rot}
1242: \).
1243: The set of classes is
1244: \[
1245: \mathcal{K} =
1246: \{
1247: \mathtt{Angle},
1248: \mathtt{Figure},
1249: \mathtt{Square},
1250: \mathtt{Circle},
1251: \mathtt{Scan}
1252: \}
1253: \]
1254: where the ordering $\le$ is defined
1255: % by the $\mathtt{extends}$ relation
1256: so that
1257: $\mathtt{Square} \le \mathtt{Figure}$ and
1258: $\mathtt{Circle} \le \mathtt{Figure}$.
1259: Variables for this program include
1260: $\mathtt{x}$, $\mathtt{y}$, $\mathtt{f}$, $\mathtt{n}$ and $\this$.
1261: Variable $\Out$ is used to hold the return value of the methods,
1262: so that the $\mathtt{return}\ e$ statement can be seen as syntactic sugar
1263: for $\Out\ =\ e$ (with no following statements).
1264: %
1265: At points $w_0$ and $w_1$, the type environments are
1266: \begin{align*}
1267: %\label{eq:type-environment-w0}
1268: \tau_{w_0} &=
1269: [\Out\mapsto\integer,
1270: \mathtt{this}\mapsto\mathtt{Circle}]
1271: \\
1272: %\label{eq:type-environment-w1}
1273: \tau_{w_1} &=
1274: [\mathtt{f}\mapsto\mathtt{Figure},
1275: \mathtt{n}\mapsto\mathtt{Figure},
1276: \Out\mapsto\integer,\this\mapsto\mathtt{Scan}].
1277: \end{align*}
1278: \qed
1279: }
1280: \end{example}
1281:
1282: $\Fields$ is a set of maps which bind each class to the type
1283: environment of its fields.
1284: The variable $\this$ cannot be a field.
1285: $\Methods$ is a set of maps which bind each class to a map from identifiers to
1286: methods. $\Pars$ is a set of maps which bind each method
1287: to the type environment of its parameters (its signature).
1288: %
1289: \begin{definition}[Field, Method, Parameter]\label{def:static_information}
1290: Let $\mathcal{M}$ be a finite set of \emph{methods}. We define
1291: %
1292: \begin{align*}
1293: \Fields&=\{F:\mathcal{K}\mapsto\Typing\mid\this\not\in\domain(F(\kappa))
1294: \text{ for every }\kappa\in\mathcal{K}\}\\
1295: \Methods&=\mathcal{K}\mapsto(\Id\to\mathcal{M})\\
1296: \Pars&=\{P:\mathcal{M}\mapsto\Typing\mid
1297: \{\Out,\this\}\subseteq\domain(P(\nu))
1298: \text{ for }\nu\in\mathcal{M}\}.
1299: \end{align*}
1300: \end{definition}
1301:
1302: The \emph{static information} of a program is used by
1303: the static analyser.
1304: %
1305: \begin{definition}[Static Information]\label{def:program}
1306: The \emph{static information} of a program consists of a poset
1307: $\mathcal{K}\sep\le$, a set of methods $\mathcal{M}$ and maps
1308: $F\in\Fields$, $M\in\Methods$ and $P\in\Pars$.
1309: \end{definition}
1310:
1311: Fields in different classes but with the same name can be disambiguated
1312: by using their \emph{fully qualified name} such as in
1313: the Java Virtual Machine~\cite{LindholmY99}. For instance, we write
1314: $\mathtt{Circle.x}$ for the field $\mathtt{x}$ of the class $\mathtt{Circle}$.
1315:
1316: \begin{example}
1317: \ifcorr{%
1318: The static information of the program in Figure~\ref{fig:program}
1319: is shown in Figure~\ref{fig:static_information}.
1320: Note that the result of the method $\mathtt{Angle.acute}$
1321: in Figure~\ref{fig:program}
1322: becomes the type of $\Out$ in $P(\mathtt{Angle.acute})$
1323: in Figure~\ref{fig:static_information}.
1324: \qed
1325: }
1326: \end{example}
1327:
1328: The only points in the program where
1329: new objects can be created are the $\mathtt{new}$ statements.
1330: We require that each of these statements
1331: is identified by a unique label called its \emph{creation point}.
1332: %
1333: \begin{definition}[Creation Point]\label{def:creation_points}
1334: Let $\Pi$ be a finite set of labels called \emph{creation points}.
1335: A map $k:\Pi\mapsto\mathcal{K}$ relates every creation point $\pi\in\Pi$ with
1336: the class $k(\pi)$ of the objects it creates.
1337: \end{definition}
1338: %
1339: \begin{example}\label{ex:k-map}
1340: \ifcorr{%
1341: Consider again the program
1342: in Figure~\ref{fig:program}. In that program
1343: $\{\overline{\pi}, \pi_1, \pi_2, \pi_3, \pi_4\}$
1344: is the set of creation points, where we assume that $\overline{\pi}$
1345: decorates an external creation point for $\mathtt{Scan}$
1346: (not shown in the figure). Then
1347: \[
1348: k = [\overline{\pi} \mapsto \mathtt{Scan},
1349: \pi_1 \mapsto \mathtt{Angle},
1350: \pi_2 \mapsto \mathtt{Square},
1351: \pi_3 \mapsto \mathtt{Circle},
1352: \pi_4 \mapsto \mathtt{Angle}
1353: ].
1354: \]
1355: \qed
1356: }
1357: \end{example}
1358:
1359: \subsection{Concrete States}\label{subsec:concrete_states}
1360: %
1361: To represent the concrete state of a computation at a
1362: particular program point we need
1363: to refer to the concrete values that may be assigned to the variables.
1364: Apart from the integers and $\nil$, these values need to include
1365: \emph{locations} which are the addresses of the memory cells
1366: used at that point.
1367: %
1368: Then the concrete state of the computation
1369: consists of a map that assigns type consistent values to variables
1370: (\emph{frame}) and
1371: a map from locations to objects (\emph{memory})
1372: where an \emph{object} is characterised by its creation point
1373: and the frame of its fields.
1374: Hence the notion of object that we use here is more concrete
1375: than that in~\cite{SpotoJ03}, which relates a \emph{class} rather
1376: than a \emph{creation point} to each object.
1377: A memory can be \emph{updated} by assigning new (type consistent)
1378: values to the variables in its frames.
1379: %
1380: \begin{definition}[Location, Frame, Object, Memory]\label{def:domains2}
1381: Let $\Loc$ be an infinite set of \emph{locations} and $\Value=\integers+\Loc
1382: +\{\nil\}$. We define \emph{frames}, \emph{objects} and
1383: \emph{memories} as
1384: %
1385: \begin{align*}
1386: \Frame_\tau&=\left\{\phi\in\domain(\tau)\mapsto\Value\left|
1387: \begin{array}{l}
1388: \text{for every }v\in\domain(\tau)\\
1389: \tau(v)=\integer\Rightarrow\phi(v)\in\integers\\
1390: \tau(v)\in\mathcal{K}
1391: \Rightarrow\phi(v)\in\{\nil\}\cup\Loc\\
1392: \end{array}
1393: \right.\right\}\\
1394: \Obj&=\{\pi\sep\phi\mid\pi\in\Pi,\ \phi\in\Frame_{F(k(\pi))}\}\\
1395: \Memory&=\{\mu\in\Loc\to\Obj\mid\domain(\mu)\text{ is finite}\}.
1396: \end{align*}
1397: %
1398: Let $\mu_1,\mu_2\in\Memory$ and $L\subseteq\domain(\mu_1)$.
1399: We say that $\mu_2$ is an $L$-\emph{update} of
1400: $\mu_1$, written $\mu_1=_L\mu_2$, if $L\subseteq\domain(\mu_2)$ and
1401: for every $l\in L$ we have $\mu_1(l).\pi=\mu_2(l).\pi$.
1402:
1403: The initial value for a variable of a given type is used when we
1404: add a variable in scope. It is defined as $\init(\integer)=0$,
1405: $\init(\kappa)=\nil$ for $\kappa\in\mathcal{K}$. This function is extended
1406: to type environments (Definition~\ref{def:typing}) as
1407: $\init(\tau)(v)=\init(\tau(v))$ for every $v\in\domain(\tau)$.
1408: \end{definition}
1409: %
1410: %
1411: %\begin{wrapfigure}{r}{6.3cm}
1412: \ifthenelse{\boolean{PROOFSONLY}}{
1413: \addtocounter{figure}{1}
1414: }{
1415: \begin{figure}
1416: \begin{center}
1417: %\vspace*{-7ex}
1418: \includegraphics{file=state.eps, width=8.0cm, height=7.5cm}
1419: %\vspace*{-4ex}
1420: \begin{align*}
1421: k &= [\overline{\pi} \mapsto \mathtt{Scan},
1422: \pi_1 \mapsto \mathtt{Angle},
1423: \pi_2 \mapsto \mathtt{Square},
1424: \pi_3 \mapsto \mathtt{Circle},
1425: \pi_4 \mapsto \mathtt{Angle}
1426: ],\\
1427: \tau_{w_1} &=[\mathtt{f}\mapsto\mathtt{Figure},\mathtt{n}\mapsto
1428: \mathtt{Figure},\Out\mapsto\integer,
1429: \this\mapsto\mathtt{Scan}],\\
1430: \phi_1&=[\mathtt{f}\mapsto l',\mathtt{n}\mapsto\nil,
1431: \mathtt{out}\mapsto 2,\this\mapsto l],\\
1432: o_1&= \overline{\pi} \sep [],\\
1433: o_2&= \pi_2 \sep \left[\begin{array}{l}
1434: \mathtt{next}\mapsto l',\mathtt{rotation}\mapsto\nil,\\
1435: \mathtt{side}\mapsto 4,\mathtt{Square.x}\mapsto 3,
1436: \mathtt{Square.y}\mapsto -5
1437: \end{array}\right],\\
1438: o_3&=\pi_2 \sep \left[\begin{array}{l}
1439: \mathtt{next}\mapsto\nil,\mathtt{rotation}\mapsto l,\\
1440: \mathtt{side}\mapsto 4,\mathtt{Square.x}\mapsto 3,
1441: \mathtt{Square.y}\mapsto -5\\
1442: \end{array}\right],\\
1443: o_4&=\pi_3 \sep [\mathtt{Circle.x}\mapsto 4,
1444: \mathtt{Circle.y}\mapsto 3,\mathtt{next}\mapsto\nil,
1445: \mathtt{radius}\mapsto 3],\\
1446: \mu_1&=[l\mapsto o_1,l'\mapsto o_2,l''\mapsto o_4],\\
1447: \mu_2&=[l\mapsto o_2,l'\mapsto o_1],\\
1448: \mu_3&=[l\mapsto o_2,l'\mapsto o_3],\\
1449: \sigma_1 &= \phi_1 \sep \mu_1.
1450: \end{align*}
1451: \end{center}
1452: \caption{%
1453: The creation point map $k$ and, for program point $w_1$,
1454: the type environment, a frame, objects and memories
1455: for the program in Figure~\ref{fig:program}.%
1456: }
1457: \label{fig:state}
1458: %\vspace*{-5ex}
1459: \end{figure}
1460: %\end{wrapfigure}
1461: %
1462: }
1463: \begin{example}\label{ex:frames}\label{ex:memories}
1464: \ifcorr{%
1465: Consider again the program in Figure~\ref{fig:program}
1466: and its static information in Figure~\ref{fig:static_information}.
1467: The type environment $\tau_{w_1}$,
1468: a frame $\phi_1$, memories $\mu_1, \mu_2, \mu_3$, objects
1469: $o_1, o_2, o_3, o_4$ and a state $\sigma_1$
1470: for this program at program point $w_1$
1471: with locations
1472: $l,l',l''\in\Loc$ are given in Figure~\ref{fig:state}.
1473: %observe that $\phi_1, \mu_1, o_1, o_2, o_4, \sigma_1$ are
1474: %also illustrated in the diagram in Figure~\ref{fig:state}.
1475: %As in Example~\ref{ex:type-environment},
1476: %the type environment at program point $w_1$ is
1477: Let also
1478: \[
1479: \phi_2=[\mathtt{f}\mapsto 2,\mathtt{n}\mapsto l',
1480: \mathtt{out}\mapsto -2,\this\mapsto l].
1481: \]
1482: Then $\Frame_{\tau_{w_1}}$ contains $\phi_1$
1483: but not $\phi_2$ because
1484: $\mathtt{f}$ is bound to $2$ in $\phi_2$ (while it has class
1485: $\mathtt{Figure}$ in $\tau_{w_1}$).
1486: }
1487:
1488: \ifcorrx{%
1489: The object $o_1$ created at
1490: $\overline{\pi}$ has class $k(\overline{\pi})=\mathtt{Scan}$
1491: since $F(\mathtt{Scan})=[]$.
1492: Objects created at $\pi_2$ have class $\mathtt{Square}$ so that
1493: these could be $o_2$ and $o_3$.
1494: Similarly, since $k(\pi_3)=\mathtt{Circle}$,
1495: an object created at $\pi_3$ is $o_4$.
1496: With these objects, $\Memory$ contains the maps $\mu_1, \mu_2, \mu_3$.
1497: With these definitions of $\mu_1$, $\mu_2$ and $\mu_3$, the memory
1498: $\mu_2$ is neither an $l$-update nor an $l'$-update of $\mu_1$ since
1499: $\mu_1(l). \pi = \overline{\pi}$ whereas
1500: $\mu_2(l). \pi = \pi_2$ and also
1501: $\mu_1(l'). \pi = \pi_2$ whereas
1502: $\mu_2(l'). \pi = \overline{\pi}$.
1503: However, as
1504: $\mu_3(l). \pi = \pi_2$ and $\mu_3(l'). \pi = \pi_2$,
1505: we have $\mu_1 =_{l'} \mu_3$ and $\mu_2 =_{l} \mu_3$.
1506: Also, letting $\mu_4 =[l\mapsto o_1,l'\mapsto o_3,l''\mapsto o_4]$,
1507: then we have
1508: $\mu_1 =_{\{l,l',l''\}} \mu_4$.
1509: \qed
1510: }
1511: \end{example}
1512:
1513: Type correctness and conservative garbage collection
1514: guarantee that there are no dangling pointers and that
1515: variables may only be bound to locations which contain objects
1516: allowed by the type environment. This is a sensible constraint for
1517: the memory allocated by strongly-typed languages such as
1518: Java~\cite{ArnoldGH00}.
1519: %
1520: \begin{definition}[Weak Correctness]\label{def:weak_correctness}
1521: Let $\phi\in\Frame_\tau$ and $\mu\in\mathit{Me}\-\mathit{mory}$. We say that
1522: $\phi$ is \emph{weakly $\tau$-correct} \wrt $\mu$ if for every
1523: $v\in\domain(\phi)$ such that $\phi(v)\in\Loc$ we have $\phi(v)\in\domain(\mu)$
1524: and $k((\mu\phi(v)).\pi)\le\tau(v)$.
1525: \end{definition}
1526: %
1527: We strengthen the correctness notion of Definition~\ref{def:weak_correctness}
1528: by requiring that it also holds for the fields of the objects in memory.
1529: %
1530: \begin{definition}[$\tau$-Correctness]\label{def:proptotau}
1531: Let $\phi\in\Frame_\tau$ and $\mu\in\Memory$. We say that
1532: $\phi$ is \emph{$\tau$-correct} \wrt $\mu$ and write $\phi\sep\mu:\tau$, if
1533: \begin{enumerate}
1534: \item $\phi$ is weakly $\tau$-correct \wrt $\mu$ and,
1535: \item for every $o\in\codom(\mu)$, $o.\phi$ is weakly
1536: $F(k(o.\pi))$-correct \wrt $\mu$.
1537: \end{enumerate}
1538: \end{definition}
1539: %
1540: \begin{example}\label{ex:tau_correctness}
1541: \ifcorr{%
1542: Let $\tau_{w_1}$, $\phi_1$, $\mu_1$, $\mu_2$ and $\mu_3$
1543: be as in Figure~\ref{fig:state}.
1544: \begin{itemize}
1545: \item $\phi_1 \sep \mu_1:\tau_{w_1}$.
1546: Condition 1 of Definition~\ref{def:proptotau} holds because
1547: \begin{gather*}
1548: \{v\in\domain(\phi_1)\mid\phi_1(v)\in\Loc\}
1549: = \{ \this,\mathtt{f} \},\\
1550: \{\phi_1(\this), \phi_1(\mathtt{f})\}
1551: = \{l,l'\} \subseteq \domain(\mu_1),\\
1552: k(\mu_1(l).\pi)
1553: = k(o_1.\pi)
1554: = k(\overline{\pi})
1555: = \mathtt{Scan}
1556: = \tau_{w_1}(\this),\\
1557: k(\mu_1(l').\pi)
1558: = k(o_2.\pi)
1559: = k(\pi_2)
1560: = \mathtt{Square}
1561: \le \mathtt{Figure}
1562: = \tau_{w_1}(\mathtt{f}).
1563: \end{gather*}
1564: Condition 2 of Definition~\ref{def:proptotau} holds because
1565: \begin{gather*}
1566: \codom(\mu_1) = \{o_1,o_2,o_4\},\\
1567: \codom(o_1.\phi) =
1568: \codom(o_4.\phi)\cap\Loc = \emptyset,\\
1569: \codom(o_2.\phi)\cap\Loc = \{l'\}
1570: \sseq \domain(\mu_1),\\
1571: k(\mu_1(l').\pi)
1572: = k(o_2.\pi)
1573: = \mathtt{Square}
1574: \le \mathtt{Figure}
1575: = F(o_2.\pi)(\mathtt{next}).
1576: \end{gather*}
1577: %
1578: \item $\phi_1 \sep \mu_2:\tau_{w_1}$ does not hold, since
1579: condition 1 of Definition~\ref{def:proptotau} does not hold. Namely,
1580: $\tau_{w_1}(\this)=\mathtt{Scan}$,
1581: $k((\mu_2\phi_1(\this)).\pi)=k(o_2.\pi)=k(\pi_2)=\mathtt{Square}$ and
1582: $\mathtt{Square}\not\le\mathtt{Scan}$.
1583: %
1584: \item $\phi_1 \sep \mu_3:\tau_{w_1}$ does not hold, since
1585: condition 2 of Definition~\ref{def:proptotau} does not hold. Namely,
1586: $o_3\in\codom(\mu_3)$ and $o_3.\phi$ is not $F(k(o_3.\pi))$-correct
1587: \wrt $\mu_3$, since we have that
1588: $o_3.\phi(\mathtt{rotation})=l$, $\mathtt{Square}\not\le\mathtt{Angle}$
1589: but $k(\mu_3(l).\pi)=k(o_2.\pi)=k(\pi_2)=\mathtt{Square}$ and moreover
1590: $F(k(o_3.\pi))(\mathtt{rotation})
1591: =F(\mathtt{Square})(\mathtt{rotation})=\mathtt{Angle}$.
1592: \end{itemize}
1593: \qed
1594: }
1595: \end{example}
1596:
1597: Definition~\ref{def:concrete_states} defines
1598: the state of the computation as a pair consisting of a frame and a memory.
1599: The variable $\this$ in the domain of the frame
1600: must be bound to an object. In particular, it cannot be $\nil$.
1601: This condition could be relaxed in Definition~\ref{def:concrete_states}.
1602: This would lead to simplifications in
1603: the following sections (such as in Definition~\ref{def:delta}). However,
1604: our condition is consistent with the specification of the Java programming
1605: language~\cite{ArnoldGH00}. Note, however, that there is no such hypothesis
1606: about the local variable number $0$ of the Java Virtual
1607: Machine, which stores the $\mathtt{this}$ object~\cite{LindholmY99}.
1608: %
1609: \begin{definition}[State]\label{def:concrete_states}
1610: If $\tau$ is a type environment associated with a program point,
1611: the set of possible \emph{states} of a computation at that point is
1612: any subset of
1613: \[
1614: \Sigma_\tau=\left\{\phi\sep\mu\left|\begin{array}{l}
1615: \phi\in\Frame_\tau,\ \mu\in\Memory,\ \phi\sep\mu:\tau,\\
1616: \text{if }\this\in\domain(\tau)\text{ then }\phi(\this)
1617: \neq\nil\end{array}\right.\right\}.
1618: \]
1619: \end{definition}
1620: %
1621: \begin{example}\label{ex:states}
1622: \ifcorr{%
1623: Let $\tau_{w_1}$, $\phi_1$, $\mu_1$, $\mu_2$ and $\mu_3$
1624: be as in Figure~\ref{fig:state}.
1625: Then, in Example~\ref{ex:tau_correctness}, we have shown
1626: that $\phi_1\sep\mu_1:\tau_{w_1}$
1627: holds and that $\phi_1\sep\mu_2:\tau_{w_1}$ and $\phi_1\sep\mu_3:\tau_{w_1}$
1628: do not hold.
1629: Thus, at program point $w_1$,
1630: we have $\phi_1\sep\mu_1\in\Sigma_{\tau_{w_1}}$,
1631: $\phi_1\sep\mu_2\not\in\Sigma_{\tau_{w_1}}$
1632: and $\phi_1\sep\mu_3\not\in\Sigma_{\tau_{w_1}}$.
1633: \qed
1634: }
1635: \end{example}
1636: %
1637: The frame of an object $o$ in memory is
1638: itself a state for the instance variables of $o$.
1639: \begin{proposition}\label{prop:recursive}
1640: Let $\phi\sep\mu\in\Sigma_\tau$ and
1641: $o\in\codom(\mu)$. Then $(o.\phi)\sep\mu\in\Sigma_{F(k(o.\pi))}$.
1642: \end{proposition}
1643: \myproofbis{
1644: Since $\phi\sep\mu\in\Sigma_\tau$, from Definition~\ref{def:concrete_states}
1645: we have $\phi\sep\mu:\tau$. From
1646: Definition~\ref{def:proptotau} we know that $o.\phi$ is weakly
1647: $F(k(o.\pi))$-correct \wrt $\mu$ so that
1648: $(o.\phi)\sep\mu:F(k(o.\pi))$. Since $\mathtt{this}\not\in\domain(F(k(o.\pi)))$
1649: (Definition~\ref{def:static_information})
1650: we conclude that $(o.\phi)\sep\mu\in\Sigma_{F(k(o.\pi))}$.}
1651: %
1652: \subsection{The Operations over the Concrete States}
1653: \label{subsec:concrete_operations}
1654: %
1655: \begin{figure}[ht]
1656: {\small
1657: \begin{center}
1658: $\begin{array}{|rl|l|}
1659: \hline
1660: \multicolumn{2}{|c|}{\text{Operation}} &
1661: \multicolumn{1}{c|}{\text{Constraint ($\this\in\domain(\tau)$
1662: always)}}\\
1663: \hline\hline
1664: \mathsf{nop}_\tau&:\Sigma_\tau\mapsto \Sigma_\tau &\\\hline
1665: \mathsf{get\_int}^i_\tau&:\Sigma_\tau\mapsto\Sigma_{\tau[\rs\mapsto
1666: \integer]}
1667: &\rs\not\in\domain(\tau),\ i\in\integers\\\hline
1668: \mathsf{get\_null}^\kappa_\tau&:
1669: \Sigma_\tau\mapsto\Sigma_{\tau[\rs\mapsto\kappa]}
1670: &\rs\not\in\domain(\tau),\ \kappa\in\mathcal{K}\\\hline
1671: \mathsf{get\_var}^v_\tau&:\Sigma_\tau\mapsto \Sigma_{\tau[\rs\mapsto
1672: \tau(v)]}&\rs\not\in\domain(\tau),\ v\in\domain(\tau)\\\hline
1673: \mathsf{get\_field}^f_\tau&:
1674: \Sigma_\tau\to\Sigma_
1675: {\tau[\rs\mapsto i(f)]}&\rs\in\domain(\tau),\ \tau(\rs)
1676: \in\mathcal{K},\\
1677: && i=F\tau(res),\ f\in\domain(i)\\\hline
1678: \mathsf{put\_var}^v_\tau&:\Sigma_\tau\mapsto\Sigma_{\tau|_{-\rs}} &
1679: \rs\in\domain(\tau),\ v\in\domain(\tau),\\
1680: && v\neq\rs,\ \tau(\rs)
1681: \le\tau(v)\\\hline
1682: &&\rs\in\domain(\tau),\ \tau(\rs)\in\mathcal{K}\\
1683: \mathsf{put\_field}^f_{\tau,\tau'}&:\Sigma_\tau\mapsto\Sigma_{\tau'}\to
1684: \Sigma_{\tau|_{-\rs}}&f\in\domain(F\tau(\rs))\\
1685: &&\tau'=\tau[\rs\mapsto t]\text{ with }t\le(F\tau(\rs))(f)\\\hline
1686: \mathsf{=}_\tau,\mathsf{+}_\tau&:\Sigma_\tau\mapsto\Sigma_\tau\mapsto
1687: \Sigma_\tau & \rs\in\domain(\tau),\ \tau(\rs)=\integer\\\hline
1688: \mathsf{is\_null}_\tau&:\Sigma_\tau\mapsto\Sigma_{\tau[\rs\mapsto\integer]}
1689: & \rs\in\domain(\tau),\ \tau(\rs)\in\mathcal{K}\\\hline
1690: &&\rs\in\domain(\tau),\ \tau(\rs)\in\mathcal{K},\\
1691: && \{v_1,
1692: \ldots,v_n\}\subseteq\domain(\tau),\ \nu\in\mathcal{M}\\
1693: \mathsf{call}_\tau^{\nu,v_1,\ldots,v_n}\!\!\!&:
1694: \Sigma_\tau\mapsto\Sigma_{P(\nu)|_{-\Out}} &
1695: \domain(P(\nu))\!\setminus\!\{\Out,\!\this\}\!=\!
1696: \{\iota_1,\ldots,\iota_n\!\}\\
1697: &&\text{(alphabetically ordered)}\\
1698: &&\tau(\rs)\le P(\nu)(\this)\\
1699: && \tau(v_i)\le P(\nu)(\iota_i)\text{ for }i=1,\ldots,n\\\hline
1700: \mathsf{return}_\tau^\nu\!:\Sigma_\tau&\!\!\!\mapsto\Sigma_
1701: {p|_{\Out}}\!\!\!\to\Sigma_{\tau[\rs\mapsto p(\Out)]}
1702: &\rs\in\domain(\tau),\ \nu\in\mathcal{M},\ p=P(\nu)\\\hline
1703: \mathsf{restrict}_\tau^{\mathit{vs}}&:\Sigma_\tau\mapsto
1704: \Sigma_{\tau|_{-\mathit{vs}}}
1705: &\mathit{vs}\subseteq\domain(\tau)\\\hline
1706: \mathsf{expand}_\tau^{v:t}&:\Sigma_\tau\mapsto\Sigma_{\tau[v\mapsto t]}
1707: &v\in\Vars,\ v\not\in\domain(\tau),\ t\in\Type\\\hline
1708: \mathsf{new}_\tau^\pi&:\Sigma_\tau\mapsto\Sigma_{\tau[\rs\mapsto k(\pi)]}
1709: &\rs\not\in\domain(\tau),\ \pi\in\Pi\\\hline
1710: &&\rs\!\in\!\domain(\tau),\ \tau(\rs)\!\in\!\mathcal{K},\\
1711: && m\!\in\!\domain(M\tau(\rs)),\ \nu\!\in\!\mathcal{M}\\
1712: \mathsf{lookup}^{m,\nu}_\tau&:\Sigma_\tau\!\!\to\!
1713: \Sigma_{\tau[\rs\mapsto P(\nu)(\this)]} &
1714: \text{for every suitable $m$, $\sigma$ and $\tau$,}\\
1715: && \text{there is at most one $\nu$}\\
1716: &&\text{such that }
1717: \mathsf{lookup}_\tau^{m,\nu}(\sigma)\text{ is defined}\\\hline
1718: \mathsf{is\_true}_\tau&:\Sigma_\tau\to\Sigma_{\tau|_{-\rs}} &
1719: \rs\in\domain(\tau),\ \tau(\rs)=\integer,\\
1720: \mathsf{is\_false}_\tau&:\Sigma_\tau\to\Sigma_{\tau|_{-\rs}} &
1721: \domain(\mathsf{is\_true}_\tau)\cap
1722: \domain(\mathsf{is\_false}_\tau)=\emptyset\\
1723: &&\domain(\mathsf{is\_true}_\tau)
1724: \cup\domain(\mathsf{is\_false}_\tau)=\Sigma_\tau\\\hline
1725: \end{array}$
1726: \end{center}
1727: }
1728: %
1729: \caption{The signature of the
1730: operations over the states.}\label{fig:signatures}
1731: \end{figure}
1732:
1733: \begin{figure}[t]
1734: {\scriptsize
1735: \begin{gather}
1736: \begin{align*}
1737: \mathsf{nop}_\tau(\phi\sep\mu)&=\phi\sep\mu\\
1738: \mathsf{get\_int}_\tau^i(\phi\sep\mu)&=
1739: \phi[\rs\mapsto i]\sep\mu\\
1740: \mathsf{get\_null}^\kappa_\tau
1741: (\phi\sep\mu)&=\phi[\rs\mapsto\nil]\sep\mu\\
1742: \mathsf{get\_var}_\tau^v
1743: (\phi\sep\mu)&=\phi[\rs\mapsto\phi(v)]\sep\mu\\
1744: \mathsf{restrict}_\tau^{\mathit{vs}}(\phi\sep\mu)&=
1745: \phi|_{-\mathit{vs}}\sep\mu\\ %,\ \mathit{vs}\subseteq\domain(\tau)\\
1746: \mathsf{expand}_\tau^{v:t}(\phi\sep\mu)&=
1747: \phi[v\mapsto\init(t)]\sep\mu\\
1748: \mathsf{put\_var}_\tau^v(\phi\sep\mu)
1749: &=\phi[v\mapsto\phi(\rs)]|_{-\rs}\sep\mu\\
1750: \mathsf{get\_field}_\tau^f(\phi'\sep\mu)&=
1751: \begin{cases}
1752: \phi'[res\mapsto((\mu\phi'(\rs)).\phi)(f)]\sep\mu &
1753: \text{if $\phi'(\rs)\neq \nil$}\\
1754: \text{undefined} & \text{otherwise}
1755: \end{cases}\\
1756: \begin{array}{c}
1757: \mathsf{put\_field}_{\tau,\tau'}^f\\
1758: (\phi_1\sep\mu_1)(\phi_2\sep\mu_2)
1759: \end{array}&=
1760: \begin{cases}
1761: \phi_2|_{-\rs}\sep\mu_2[l\mapsto\mu_2(l).\pi\sep\mu_2(l).
1762: \phi[f\mapsto\phi_2(\rs)]] &\\
1763: \qquad\text{if $l=\phi_1(\rs), l\neq \nil$ and $\mu_1=_l\mu_2$}\\
1764: \text{undefined}\quad\text{otherwise}&
1765: \end{cases}\\
1766: \mathsf{=}_\tau(\phi_1\sep\mu_1)
1767: (\phi_2\sep\mu_2)&=
1768: \begin{cases}
1769: \phi_2[\rs\mapsto 1]\sep\mu_2 & \text{if $\phi_1(\rs)=\phi_2(\rs)$}\\
1770: \phi_2[\rs\mapsto -1]\sep\mu_2 &
1771: \text{if $\phi_1(\rs)\neq \phi_2(\rs)$}
1772: \end{cases}\\
1773: \mathsf{+}_\tau(\phi_1\sep\mu_1)(\phi_2\sep\mu_2)&=
1774: \phi_2[\rs\mapsto\phi_1(\rs)+\phi_2(\rs)]\sep\mu_2\\
1775: \mathsf{is\_null}_\tau(\phi\sep\mu)&=
1776: \begin{cases}
1777: \phi[\rs\mapsto 1]\sep\mu & \text{if $\phi(\rs)=\nil$}\\
1778: \phi[\rs\mapsto -1]\sep\mu & \text{otherwise}
1779: \end{cases}\\
1780: \mathsf{call}_\tau^{\nu,v_1,\ldots,v_n}
1781: (\phi\sep\mu)&=
1782: [\iota_1\mapsto\phi(v_1),\ldots,\iota_n\mapsto\phi(v_n),
1783: \this\mapsto\phi(\rs)]\sep\mu\\
1784: \text{where $\{\iota_1,\ldots,\iota_n\}$}&=\text{$P(\nu)\setminus
1785: \{\Out,\this\}$ (alphabetically ordered)}\\
1786: \begin{array}{c}
1787: \mathsf{return}_\tau^\nu\\
1788: (\phi_1\sep\mu_1)(\phi_2\sep\mu_2)
1789: \end{array}&=
1790: \begin{cases}
1791: \phi_1[\rs\mapsto\phi_2(\Out)]\sep\mu_2\\
1792: \quad \text{if $L = \codom(\phi_1)|_{-\rs}\cap\Loc$ and
1793: $\mu_1=_L \mu_2$}\\
1794: \mbox{}\\
1795: \text{undefined}\quad\text{otherwise}
1796: \end{cases}\\
1797: \mathsf{new}_\tau^\pi(\phi\sep\mu)&=
1798: \phi[\rs\mapsto l]\sep\mu[l\mapsto
1799: \pi\sep\init(F(k(\pi)))],\ l\in\Loc\setminus\domain(\mu)\\
1800: \mathsf{lookup}^{m,\nu}_\tau(\phi\sep\mu)&=\begin{cases}
1801: \phi\sep\mu\\
1802: \quad\text{if $\phi(\rs)\neq \nil$ and
1803: $M(k((\mu\phi(\rs)).\pi))(m)=\nu$}\\
1804: \mbox{}\\
1805: \text{undefined}\quad\text{otherwise}
1806: \end{cases}\\
1807: \mathsf{is\_true}_\tau(\phi\sep\mu)&=\begin{cases}
1808: \phi|_{-\rs}\sep\mu & \text{if $\phi(\rs)\ge 0$}\\
1809: \text{undefined} & \text{otherwise}
1810: \end{cases}\\
1811: \mathsf{is\_false}_\tau(\phi\sep\mu)&=\begin{cases}
1812: \phi|_{-\rs}\sep\mu & \text{ if $\phi(\rs)<0$}\\
1813: \text{undefined} & \text{otherwise.}
1814: \end{cases}
1815: \end{align*}\end{gather}}\normalsize
1816: %
1817: \caption{The operations over concrete states.}\label{fig:concrete_states}
1818: \end{figure}
1819:
1820: Figures~\ref{fig:signatures} and~\ref{fig:concrete_states} show the
1821: signatures and the definitions, respectively, of a set of operations over
1822: the concrete states for a type environment $\tau$.
1823: %These operations can be seen as a simplified set of bytecodes, similar
1824: %to those of the Java Virtual Machine \cite{LindholmY99}.
1825: The variable $\rs$ holds intermediate results, as we said at the beginning of
1826: this section.
1827: %such as the top element of the operand stack of the Java
1828: %Virtual Machine.
1829: We briefly introduce these operations.
1830:
1831: \begin{itemize}
1832: \item
1833: The $\mathsf{nop}$ operation does nothing.
1834: \item
1835: A $\mathsf{get}$ operation loads into $\rs$ a constant,
1836: the value of another variable or the value of the field of an object.
1837: %It can be
1838: %an integer constant ($\mathsf{get\_int}$), the $\nil$ constant
1839: %($\mathsf{get\_null}$), the value of another variable
1840: %($\mathsf{get\_var}^v$) or the value of the field of an object
1841: %($\mathsf{get\_field}^f$).
1842: In the last case ($\mathsf{get\_field}$),
1843: that object is assumed to be stored in $\rs$
1844: \emph{before} the $\mathsf{get}$ operation.
1845: Then $(\mu\phi'(\rs))$ is the object whose field $f$ must be read,
1846: $(\mu\phi'(\rs)).\phi$ are its fields and $(\mu\phi'(\rs)).\phi(f)$ is the
1847: value of the field named $f$.
1848: \item
1849: A $\mathsf{put}$ operation stores in $v$ the value of $\rs$ or
1850: of a field of an object pointed to by $\rs$.
1851: Note that, in the second case,
1852: $\mathsf{put\_field}$ is a binary operation since the
1853: evaluation of $e_1.f=e_2$ from an initial state $\sigma_1$
1854: works by first evaluating $e_1$ from $\sigma_1$, yielding an intermediate
1855: state $\sigma_2$, and then evaluating $e_2$ from $\sigma_2$, yielding a
1856: state $\sigma_3$. The final state is then
1857: $\mathsf{put\_field}(\sigma_2)(\sigma_3)$~\cite{SpotoJ03}, where the
1858: variable $\rs$ of $\sigma_2$ holds the value of $e_1$ and the variable
1859: $\rs$ of $\sigma_3$ holds the value of $e_2$.
1860: The object whose field is modified
1861: must still exist in the memory of $\sigma_3$.
1862: This is expressed by the update relation (Definition~\ref{def:domains2}).
1863: As there is no result, $\rs$ is removed.
1864: Providing two states \ie two frames and
1865: two heaps for $\mathsf{put\_field}$ and, more generally, for
1866: binary operations, may look like an overkill and it might be expected that
1867: a single state and a single frame would be enough. However,
1868: our decision to have two states has been dictated by the intended
1869: use of this semantics
1870: \ie abstract interpretation. By \emph{only} using operations over states,
1871: we have exactly one concrete domain, which can be abstracted into just one
1872: abstract domain. Hybrid operations, working on states and frames,
1873: would only complicate the abstraction.
1874: %
1875: %The $\mathsf{put\_field}^f(\sigma_1)(\sigma_2)$
1876: %operation stores a value $v$ inside the field $f$ of an object $o$.
1877: %The variable $\rs$ of $\sigma_2$ provides $v$, while that of $\sigma_1$
1878: %provides $o$.
1879: \item
1880: For every binary operation such as $=$ and $+$ over values, there is an
1881: operation on states. Note that (in the case of $\mathsf{=}$)
1882: Booleans are implemented by means of
1883: integers (every non-negative integer means true).
1884: We have already explained why we use two states for binary operations.
1885: \item
1886: The operation $\mathsf{is\_null}$ checks that $\rs$ points
1887: to $\nil$.
1888: \item
1889: The operation $\mathsf{call}$ is used before, and the operation
1890: $\mathsf{return}$ is used after, a call to a method $\nu$.
1891: While $\mathsf{call}^\nu$ creates a new state in which $\nu$ can execute,
1892: %Its typing $P(\nu)|_{-\Out}$ describes
1893: %the input parameters ($\Out$ is not among them).
1894: %They are bound by $\mathsf{call}$ to the actual arguments
1895: %$v_1,\ldots,v_n$ passed to the method, while $\this$ is bound to
1896: %the object over which the method is called, pointed by $\rs$.
1897: the operation $\mathsf{return}^\nu$ restores
1898: the state $\sigma$ which was current
1899: before the call to $\nu$, and stores in $\rs$ the result of the call.
1900: As said in (the beginning of) Section~\ref{sec:framework},
1901: the denotation of the method is taken from an \emph{interpretation},
1902: in a denotational fashion~\cite{BossiGLM94}. Hence the execution
1903: from an initial state $\sigma_1$ of
1904: a method call denoted, in the current interpretation,
1905: by $d:\Sigma\to\Sigma$, yields the final state
1906: $\mathsf{return}(\sigma_1)(d(\mathsf{call}(\sigma_1)))$.
1907: Note that $\mathsf{return}$ is a binary operation whose first argument is
1908: the state of the caller at call-time and whose second argument is
1909: the state of the callee at return-time. Its definition in
1910: Figure~\ref{fig:concrete_states} restores the state of the caller but
1911: stores in $\rs$ the return value of the callee. By using
1912: a binary operation we can define our semantics in terms of states
1913: rather than in terms of activation stacks. This is a useful simplification when
1914: passing to abstraction, since states must be abstracted rather than stacks.
1915: %
1916: Note that the update relation (Definition~\ref{def:domains2}) requires that the
1917: variables of the caller have not been changed during the execution of the
1918: method (although the fields of the objects bound to those
1919: variables may be changed).
1920: %copies in the variable $\rs$ of the state $\sigma_1$ before the call
1921: %the result of the method $\nu$, i.e., the variable $\Out$
1922: %in $\sigma_2$. The memory is that at the end of the execution of the
1923: %method body. In this way it passes the return value of the method to the
1924: %calling environment, and side-effects are allowed.
1925: \item
1926: The operation $\mathsf{expand}$ ($\mathsf{restrict}$) adds (removes)
1927: variables.
1928: \item
1929: The operation $\mathsf{new}^\pi$ creates a new object $o$
1930: of creation point $\pi$.
1931: A pointer to $o$ is put in $\rs$. Its fields
1932: are initialised to default values.
1933: \item
1934: The operation $\mathsf{lookup}^{m,\nu}$ checks if, by calling the method
1935: identified by $m$ of the object $o$
1936: pointed to by $\rs$, the method $\nu$ is run.
1937: This depends on the class $k(o.\pi)$ of $o=\mu\phi(\rs)$.
1938: \item
1939: The operation $\mathsf{is\_true}$ ($\mathsf{is\_false}$)
1940: checks if $\rs$ contains true (false).
1941: \end{itemize}
1942: %
1943: \begin{example}\label{ex:concrete_operations}
1944: \ifcorr{%
1945: Consider again the example in Figure~\ref{fig:program}.
1946: Let $\tau = \tau_{w_1}$, $\phi_1$, $\mu_1$ and $\sigma_1 = \phi_1\sep\mu_1$
1947: be as in Figure~\ref{fig:state}
1948: so that, as indicated in Example~\ref{ex:states},
1949: state $\sigma_1$ could be the current state at program point $w_1$.
1950: The computation continues as follows~\cite{SpotoJ03}.
1951: \[
1952: \sigma_2=\mathsf{get\_var}_\tau^\mathtt{f}(\sigma_1) \qquad
1953: \text{read $\mathtt{f}$.}
1954: \]
1955: %
1956: Let $o_1, o_2, o_3, o_4$ be as in Figure~\ref{fig:state}. Then
1957: $\sigma_2=\phi_1 \left[\rs\mapsto \phi_1(f)\right]\sep \mu_1
1958: =\phi_1 \left[\rs\mapsto l'\right]\sep \mu_1
1959: =[
1960: \mathtt{f}\mapsto l',\mathtt{n}\mapsto\nil,
1961: \Out\mapsto 2,\rs\mapsto l',\this\mapsto l]\sep \mu_1$.
1962: %
1963: The $\mathsf{lookup}$ operations determine which is the target
1964: of the first virtual call $\mathtt{f.def()}$ in Figure~\ref{fig:program}.
1965: As a result only one of the following blocks of code is run
1966: depending on which $\mathsf{lookup}$ check is defined.
1967: \[
1968: \left.\begin{array}{rll}
1969: \sigma_3'=&\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
1970: ^{\mathtt{def},\mathtt{Figure.def}}
1971: (\sigma_2) & \text{select $\mathtt{Figure.def}$}\\
1972: \sigma_4'=&\mathsf{call}_{\tau[\rs\mapsto P(\mathtt{Figure.def})
1973: (\this)]}^\mathtt{Figure.def}
1974: (\sigma_3') & \text{initialise the $\mathtt{Figure}$}\\
1975: \sigma_5'=&\text{the final state of $\mathtt{Figure.def}$ from $\sigma_4'$}\\
1976: \sigma_6'=&\mathsf{return}_{\tau[\rs\mapsto P(\mathtt{Figure.def})
1977: (\this)]}^\mathtt{Figure.def}(\sigma_3')(\sigma_5')
1978: & \text{return to the caller}\\
1979: \mbox{}\\
1980: \sigma_3''=&\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
1981: ^{\mathtt{def},\mathtt{Square.def}}
1982: (\sigma_2) & \text{select $\mathtt{Square.def}$}\\
1983: \sigma_4''=&\mathsf{call}_{\tau[\rs\mapsto P(\mathtt{Square.def})
1984: (\this)]}^\mathtt{Square.def}
1985: (\sigma_3'') & \text{initialise the $\mathtt{Square}$}\\
1986: \sigma_5''=&\text{the final state of $\mathtt{Square.def}$
1987: from $\sigma_4''$}\\
1988: \sigma_6''=&\mathsf{return}_{\tau[\rs\mapsto P(\mathtt{Square.def})
1989: (\this)]}^\mathtt{Square.def}(\sigma_3'')(\sigma_5'')
1990: & \text{return to the caller}\\
1991: \mbox{}\\
1992: \sigma_3'''=&\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
1993: ^{\mathtt{def},\mathtt{Circle.def}}
1994: (\sigma_2) & \text{select $\mathtt{Circle.def}$}\\
1995: \sigma_4'''=&\mathsf{call}_{\tau[\rs\mapsto P(\mathtt{Circle.def})
1996: (\this)]}^\mathtt{Circle.def}
1997: (\sigma_3''') & \text{initialise the $\mathtt{Circle}$}\\
1998: \sigma_5'''=&\text{the final state of $\mathtt{Circle.def}$
1999: from $\sigma_4'''$}\\
2000: \sigma_6'''=&\mathsf{return}_{\tau[\rs\mapsto P(\mathtt{Circle.def})
2001: (\this)]}^\mathtt{Circle.def}(\sigma_3''')(\sigma_5''')
2002: & \text{return to the caller.}
2003: \end{array}\right.
2004: \]
2005: %
2006: The states $\sigma_5'$, $\sigma_5''$ and $\sigma_5'''$ are computed
2007: from the current intepretation for the methods.
2008: %
2009: For each $\mathsf{lookup}$ operation, we have
2010: $(\sigma_2.\phi)(\rs)=l'\neq \nil$ and $(\sigma_2.\mu)(l')=o_2$; then the
2011: method of $o_2$ identified by $\mathtt{def}$ is called.
2012: Now $o_2.\pi\!=\!\pi_2$ and $k(\pi_2)\!=\!\mathtt{Square}$. Moreover
2013: $M(\mathtt{Square})(\mathtt{def})=\mathtt{Square.def}$
2014: (Figure~\ref{fig:static_information}).
2015: So the only \emph{defined} $\mathsf{lookup}$
2016: operation is that for $\mathtt{Square.def}$. This means
2017: that $\mathtt{Square.def}$ is called and $\sigma_3''=\sigma_2$,
2018: while $\sigma_3'$ and $\sigma_3'''$ are undefined.
2019: }
2020:
2021: \ifcorrx{%
2022: We obtain $\sigma_4''=[\this\mapsto l']\sep \mu_1$.
2023: Note that the object $o_2$ %created by the $\mathtt{new}$ statement
2024: is now the $\this$ object of this instantiation of the method
2025: $\mathtt{Square.def}$. To compute $\sigma_5''$, we should execute
2026: the operations which implement $\mathtt{Square.def}$, starting from the
2027: state $\sigma_4''$. For simplicity,
2028: we report
2029: only
2030: the final state of this execution which is
2031: \[
2032: \sigma_5''=[\mathtt{out}\mapsto 0]\sep
2033: \underbrace{[l\mapsto o_1,l'\mapsto o_5,l''\mapsto o_4]}_{\mu_5},
2034: \]
2035: where
2036: \begin{align*}
2037: o_5&=\pi_2\sep\left[\begin{array}{l}
2038: \mathtt{next}\mapsto l',\mathtt{side}\mapsto 1,
2039: \mathtt{Square.x}\mapsto 0,\\
2040: \mathtt{Square.y}\mapsto 0,\mathtt{rotation}\mapsto o_6
2041: \end{array}\right],\\
2042: o_6&=\pi_1\sep[\mathtt{degree}\mapsto 0].
2043: \end{align*}
2044: The $\mathsf{return}$ operation returns the control to the caller method.
2045: This means that the frame will be that of the caller, but the return value
2046: of the callee is copied into the $\rs$ variable of the caller. Namely,
2047: \[
2048: \sigma_6''=\left[\begin{array}{l}
2049: \mathtt{f}\mapsto l',\mathtt{n}\mapsto\nil,\\
2050: \Out\mapsto 2,\rs\mapsto 0,\this\mapsto l
2051: \end{array}\right]\sep\mu_5.
2052: \]
2053: %
2054: \qed
2055: }
2056: \end{example}
2057: %
2058: \subsection{The Collecting Semantics}\label{subsec:collecting}
2059: %
2060: The operations of Figure~\ref{fig:concrete_states} can be used to define
2061: the transition function from states to states, or \emph{denotation},
2062: of a piece of code $c$, as shown in
2063: Example~\ref{ex:concrete_operations}.
2064: By use of $\mathsf{call}$ and $\mathsf{return}$,
2065: there is a denotation for each method called in $c$;
2066: thus, by adding $\mathsf{call}$ and $\mathsf{return}$,
2067: we can plug the method's denotation in the calling points inside $c$
2068: (as shown in Subsection~\ref{subsec:concrete_operations} and in
2069: Example~\ref{ex:concrete_operations}).
2070: %% Everything we need is a denotation
2071: %% for each method called in $c$, ready to be plugged in the calling points
2072: %% inside $c$, through the use of $\mathsf{call}$ and $\mathsf{return}$,
2073: %% as shown in Subsection~\ref{subsec:concrete_operations} and in
2074: %% Example~\ref{ex:concrete_operations}.
2075: A function $I$ binding each method $\mathtt{m}$
2076: in a program $P$ to its denotation
2077: $I(\mathtt{m})$ is called an \emph{interpretation} of $P$.
2078: Given an interpretation $I$, we are hence able to define
2079: the denotation $T_P(I)(\mathtt{m})$ of the body of a method $\mathtt{m}$,
2080: so that we are able to transform $I$ into a new interpretation $T_P(I)$.
2081: This leads to the definition of the \emph{denotational semantics} of $P$
2082: as the minimal (\ie less defined) interpretation which is a fixpoint
2083: of $T_P$.
2084: This way of defining the concrete semantics in a denotational way
2085: through interpretations,
2086: is useful for a subsequent abstraction~\cite{CousotC92}.
2087: The technique, which has been extensively used
2088: in the logic programming tradition~\cite{BossiGLM94},
2089: has been adapted in~\cite{SpotoJ03} for object-oriented
2090: imperative programs by adding the mechanism for dynamic dispatch
2091: through the $\mathsf{lookup}$ operation in Figure~\ref{fig:concrete_states}.
2092: Note that the fixpoint of $T_P$ is
2093: not finitely computable in general, but it does exist as a consequence
2094: of Tarski's theorem and it is the limit of the ascending chain of
2095: interpretations $I_0$, $T_P(I_0)$, $T_P(T_P(I_0))$, \ldots,
2096: where, for every method $\mathtt{m}$, the denotation
2097: $I_0(\mathtt{m})$ is always undefined~\cite{Ta55}.
2098:
2099: The concrete semantics described above denotes each method with a map on
2100: states \ie a function from $\Sigma$ to $\Sigma$.
2101: However, abstract interpretation is interested in
2102: \emph{properties} of states; so that each property of interest,
2103: is identified with the set of all the states satisfying that property.
2104: This leads to the definition of a \emph{collecting}
2105: semantics~\cite{CousotC77,CousotC92} \ie
2106: a concrete semantics working over the powerset $\wp(\Sigma)$.
2107: The operations of this collecting semantics are the powerset
2108: extension of the operations in Figure~\ref{fig:concrete_states}.
2109: For instance, $\mathsf{get\_int}_\tau^i$ is extended into
2110: \[
2111: \mathsf{get\_int}_\tau^i(S)=\{\mathsf{get\_int}_\tau^i(\sigma)\mid
2112: \sigma\in S\}
2113: \]
2114: for every $S\in\wp(\Sigma_\tau)$.
2115: Note that dealing with powersets means that the semantics becomes
2116: non-determi\-ni\-stic. For instance, in Example~\ref{ex:concrete_operations}
2117: more than one target of the $\mathtt{f.def()}$ virtual call could
2118: be selected at the same time and more than one of the blocks of code
2119: could be executed. Hence we need a $\cup$ operation over sets
2120: of states which merges different threads of execution at the end of a virtual
2121: call (or, for similar motivations, at the end of a conditional).
2122: The notion of denotation now becomes a map over $\wp(\Sigma_\tau)$.
2123: Interpretations and the transformer on interpretations are defined exactly
2124: as above.
2125: We will assume the result, proved in~\cite{SpotoJ03}, that every abstraction of
2126: $\wp(\Sigma_\tau)$, $\mathord{\cup}$ and of the powerset extension
2127: of the operations in Figure~\ref{fig:concrete_states}
2128: induces an abstraction of the concrete collecting semantics.
2129: This is an application to object-oriented imperative programs of the
2130: \emph{fixpoint transfer} Proposition~27 in~\cite{CousotC92}.
2131: Two such abstractions will be described in Sections~\ref{sec:edomain}
2132: and~\ref{sec:erdomain}.
2133: %
2134: \section{The Basic Domain $\e$}\label{sec:edomain}
2135: %
2136: We define here a basic abstract domain $\e$ as a
2137: property of the concrete states of Definition~\ref{def:concrete_states}.
2138: %Hence it can be defined without any consideration
2139: %about name clashes or multiple instances of the same variable
2140: %during recursion.
2141: Its definition is guided by our goal to
2142: \emph{over}approximate, for every program point $p$,
2143: the set of creation points of objects reachable at $p$
2144: from some variable or field in scope.
2145: Thus an element of the abstract domain $\e$ which decorates a program point $p$
2146: is simply
2147: a set of creation points of objects that may be reached at $p$.
2148: The choice of an \emph{over}approximation
2149: follows from the typical use of the information provided by
2150: an escape analysis. For instance, an object can be stack allocated
2151: if it does not escape the method
2152: which creates it \ie if it does not belong to a superset of the objects
2153: reachable at its end.
2154: Moreover, our goal is to stack allocate specific creation points.
2155: Hence, we are not interested in the identity of the objects but in
2156: their creation points.
2157:
2158: Although, at the end of this section, we will see that $\e$ induces
2159: rather imprecise abstract operations, its definition is important since
2160: $\e$ comprises exactly the information needed to implement our escape
2161: analysis. Even though its abstract operations lose
2162: precision, we still need $\e$ as a basis for
2163: comparison and as a minimum requirement for new, improved domains
2164: for escape analysis. Namely, in Section~\ref{sec:erdomain}
2165: we will define a more precise abstract domain $\er$
2166: for escape analysis, and we will prove
2167: (Proposition~\ref{prop:inclusion}) that it strictly contains $\e$.
2168: This situation is similar to that of the abstract domain $\mathcal{G}$
2169: for groundness analysis of logic programs~\cite{Sondergaard86} which,
2170: although imprecise, expresses the property looked for by the analysis,
2171: and is the basis of all the other abstract domains for groundness
2172: analysis, derived as \emph{refinements} of $\mathcal{G}$~\cite{Scozzari00}.
2173: The definition of more precise abstract
2174: domains as refinements of simpler ones is actually standard methodology
2175: in abstract interpretation nowadays~\cite{GiacobazziR97}.
2176: Another example is strictness analysis of functional programs,
2177: where a first simple domain is subsequently enriched to express more precise
2178: information~\cite{Jensen97}.
2179: A similar idea has also been applied to model-checking, through a
2180: sequence of refinements of a simple abstract domain~\cite{Dams96}.
2181: A \emph{refinement}, in this context, is just an operation that transforms
2182: a simpler domain into a richer one \ie one containing more abstract elements.
2183: There are many standard refinements operations.
2184: One of this is \emph{reduced product}, which allows one to compose
2185: two abstract domains in order to express the composition of the
2186: properties expressed by the two domains, and \emph{disjunctive
2187: completion}, which enriches an abstract domain with the ability
2188: to express disjunctive information about the properties expressed
2189: by the domain~\cite{CousotC79}. Another example is the
2190: \emph{linear refinement} of a domain \wrt another, which expresses
2191: the dependencies of the abstract properties expressed by the two
2192: domains~\cite{GiacobazziS98}.
2193: In Section~\ref{sec:erdomain}
2194: we use a refinement which is significant for imperative programs, where
2195: assignments to program variables are the pervasive operation.
2196: Hence, a variable-based approximation often yields improved precision
2197: \wrt a global approximation of the state, such
2198: as expressed by $\e$.
2199: This same refinement is used, for instance, when passing from
2200: rapid type analysis to a variable-based \emph{class analysis} of
2201: object-oriented imperative programs in~\cite{SpotoJ03}.
2202:
2203: We show an example now that clarifies the idea of \emph{reachability}
2204: for objects
2205: at a program point.
2206: %
2207: \begin{example}\label{ex:escape_analysis}
2208: \ifcorr{%
2209: Consider the program in Figure~\ref{fig:program}
2210: and the type environment $\tau_{w_1}$ for program point $w_1$
2211: given in Figure~\ref{fig:state}.
2212: We show that no objects created at $\pi_4$
2213: will be reachable at program point $w_1$.
2214: The type environment
2215: at $w_1$, which is $\tau_{w_1}$,
2216: shows that we cannot reach any object from $\Out$,
2217: since $\Out$ can only contain integers.
2218: The variable $\this$ has class $\mathtt{Scan}$ which has no fields.
2219: Since in $\pi_4$ we create objects of class $\mathtt{Angle}$,
2220: they cannot be reached from $\this$.
2221: The variables $\mathtt{f}$ and $\mathtt{n}$ have class $\mathtt{Figure}$
2222: whose only field has type $\mathtt{Figure}$ itself.
2223: Reasoning as for $\this$, we could falsely conclude that no object
2224: created at $\pi_4$ can be reached from $\mathtt{f}$ or $\mathtt{n}$.
2225: This conclusion is false
2226: since, as $\mathtt{Square} \le \mathtt{Figure}$, the call
2227: $\mathtt{rotate(f)}$ could result in a call
2228: in the class $\mathtt{Square}$ to the method $\mathtt{f.rot(a)}$
2229: which stores $\mathtt{a}$,
2230: created at $\pi_4$, in the field $\mathtt{rotation}$;
2231: and $\mathtt{rotation}$
2232: is still accessible to other methods such as $\mathtt{f.draw()}$.
2233: \qed
2234: }
2235: \end{example}
2236:
2237: The reasoning in Example~\ref{ex:escape_analysis} leads to
2238: the notion of \emph{reachability} in Definition~\ref{def:reachability}
2239: where we use
2240: the actual fields of the objects instead of those of the declared class
2241: of the variables.
2242: %
2243: \begin{definition}[Reachability]\label{def:reachability}
2244: Let $\sigma=\phi\sep\mu\in\Sigma_\tau$ and
2245: $S\subseteq\Sigma_\tau$. The set of the objects \emph{reachable} in $\sigma$ is
2246: $O_\tau(\sigma)=\cup\{O_\tau^i(\sigma)\mid i\ge 0\}$ where
2247: \begin{align*}
2248: O_\tau^0(S)&=\emptyset\\
2249: O_\tau^{i+1}(S)&=\bigcup\left\{\{o\}\cup O^i_{F(k(o.\pi))}(o.\phi\sep\mu)
2250: \left|\begin{array}{l}
2251: \phi\sep\mu\in S,\ v\in\domain(\tau)\\
2252: \phi(v)\in\Loc,\ o=\mu\phi(v)
2253: \end{array}\right.\right\}.
2254: \end{align*}
2255: The maps $O_\tau^i$ are extended to $\wp(\Sigma_\tau)$ as
2256: $O_\tau^i(S)=\cup\{O_\tau^i(\sigma)\mid\sigma\in S\}$.
2257: %
2258: \end{definition}
2259: %
2260: Proposition~\ref{prop:recursive}
2261: provides a guarantee that Definition~\ref{def:reachability}
2262: is well-defined.
2263: Observe that variables and fields of type $\integer$
2264: do not contribute to $O_\tau$.
2265: %
2266: We can now define the abstraction map for $\e$.
2267: It selects the creation points of the reachable objects.
2268: %
2269: \begin{definition}[Abstraction Map for $\e$]\label{def:alpha}
2270: Let $S\subseteq\Sigma_\tau$.
2271: The \emph{abstraction map} for $\e$ is
2272: \[
2273: \alpha_\tau^\e(S)=\{o.\pi\mid\sigma\in S\text{ and }
2274: o\in O_\tau(\sigma)\}\subseteq\Pi.
2275: \]
2276: \end{definition}
2277: %
2278: \begin{example}\label{ex:e_domain}
2279: \ifcorr{%
2280: Let $\phi_1$, $\mu_1$, $\sigma_1 = \phi_1 \sep \mu_1$, $o_1$ and
2281: $o_2$ be as defined in Figure~\ref{fig:state}. Then
2282: $\{v \in \domain(\tau_{w_1}) \mid \phi_1(v) \in \Loc\} = \{\mathtt{f},\this\}$,
2283: $\mu_1\phi_1(\this) = o_1$ and $\mu_1\phi_1(\mathtt{f}) = o_2$
2284: so that we have
2285: \(
2286: O_\tau^1(\sigma_1)
2287: = \{o_1,o_2\}.
2288: \)
2289: However $o_1.\pi = \overline{\pi}$ and $o_2.\pi = \pi_2$ so that,
2290: by using the static information in Figure~\ref{fig:static_information},
2291: we have $F(k(o_1.\pi)) = \emptyset$ and
2292: $\domain(F(k(o_2.\pi)))
2293: = \{\mathtt{next},
2294: \mathtt{rotation}, \mathtt{side},\linebreak
2295: \mathtt{Square.x},
2296: \mathtt{Square.y}\}$.
2297: From Figure~\ref{fig:state} we conclude that
2298: \(
2299: \{\mu_1(o_2.\phi(f))\mid \ f\in\domain(F(k(o_2.\pi)))
2300: ,
2301: o_2.\phi(f)\in\Loc\}
2302: = \{o_2\}
2303: \)
2304: and therefore
2305: \[
2306: O^1_{F(k(o_2.\pi))}(o_2.\phi\sep\mu_1)=
2307: \left\{\mu(o_2.\phi(f))\left|\begin{array}{l}
2308: f\in\domain(F(k(o_2.\pi)))\\
2309: o_2.\phi(f)\in\Loc
2310: \end{array}\right.\right\}=\{o_2\}
2311: \]
2312: so that
2313: \(
2314: O_\tau^2(\sigma_1)
2315: = \{o_1, o_2\} \cup \{o_2\} = \{o_1, o_2\}
2316: = O_\tau^1(\sigma_1)
2317: \).
2318: Thus we have a fixpoint and $O_\tau(\sigma_1) = \{o_1,o_2\}$.
2319: Note that $o_4\not\in O_\tau(\sigma_1)$ \ie it is \emph{garbage}.
2320: }
2321:
2322: \ifcorrx{%
2323: As $o_1. \pi = \overline{\pi}$ and $o_2. \pi = \pi_2$, we have
2324: $\alpha_{\tau_{w_1}}^\e(\sigma_1)=\{\overline{\pi},\pi_2\}$.
2325: This corresponds with the approximation
2326: we used in Example~\ref{ex:e_imprecise}
2327: to decorate program point $w_1$.
2328: \qed
2329: }
2330: \end{example}
2331:
2332: \subsection{The Domain $\e$ in the Presence of Type Information}
2333: \label{subsec:types_escape}
2334: %
2335: Definition~\ref{def:alpha} seems to suggest that $\codom(\alpha^\e_\tau)
2336: =\wp(\Pi)$ \ie that every set of creation points is a legal approximation
2337: in each given program point.
2338: However, this is not true if type information is taken into account.
2339: %
2340: \begin{example}\label{ex:rho_not_onto}
2341: \ifcorr{%
2342: Consider the program point $w_0$ in Figure~\ref{fig:program} and its type
2343: environment $\tau_{w_0}=[\Out\mapsto\integer,\mathtt{this}\mapsto
2344: \mathtt{Circle}]$.
2345: Then $\alpha^\e_{\tau_{w_0}}(\sigma)\not=\{\pi_4\}$ for every
2346: $\sigma=\phi\sep\mu\in\Sigma_\tau$. This is because
2347: %
2348: \[
2349: \alpha^\e_{\tau_{w_0}}(\sigma)=\bigcup\left\{\left.
2350: \{o.\pi\}\cup\alpha^\e_{F(k(o.\pi))}((o.\phi)\sep\mu)\right|
2351: \begin{array}{l}
2352: v\in\{\mathtt{this}\},\ \phi(v)\in\Loc\\
2353: o=\mu\phi(v)
2354: \end{array}\right\}.
2355: \]
2356: %
2357: By Definition~\ref{def:weak_correctness} we know that if
2358: $\phi(v)\in\Loc$ then $k(o.\pi)=\mathtt{Circle}$. Hence
2359: $o.\pi=\pi_3$. We conclude that either $\phi(v)=\nil$
2360: and $\alpha_{\tau_{w_0}}^\e(\sigma)=\emptyset$, or $\phi(v)\in\Loc$
2361: and $\pi_3\in\alpha_{\tau_{w_0}}^\e(\sigma)$. In both cases it is not
2362: possible that $\alpha^\e_{\tau_{w_0}}(\sigma)=\{\pi_4\}$.
2363: \qed
2364: }
2365: \end{example}%
2366: %
2367: Example~\ref{ex:rho_not_onto} shows that
2368: \emph{static type information provides escape information} by
2369: indicating which subsets of creation points are not the abstraction of any
2370: concrete states. We should therefore characterise which are the \emph{good} or
2371: meaningful elements of $\wp(\Pi)$.
2372: This is important because it reduces the size of the abstract domain
2373: and removes useless creation points during the analysis through the use
2374: of an \emph{abstract garbage collector} $\delta_\tau$
2375: (Definition~\ref{def:delta}).
2376:
2377: Let $\ee\in\wp(\Pi)$. Then $\delta_\tau(\ee)$ is defined as the largest subset
2378: of $\ee$ which contains only those
2379: creation points deemed useful by the type environment $\tau$.
2380: This set is computed first by collecting the creation points
2381: that create objects compatible with the types in $\tau$.
2382: For each of these points, this check is reiterated
2383: for each of the fields of the object it creates until a fixpoint is reached.
2384: Note that if there are no possible creation points for \texttt{this},
2385: all creation points are useless.
2386: %We can see $\delta$ as an
2387: %\emph{abstract garbage collector} which removes the creation points of the
2388: %objects that can never be reached.
2389: %
2390: \begin{definition}[Abstract Garbage Collector $\delta$]\label{def:delta}
2391: Let $\ee\subseteq\Pi$. We define
2392: $\delta_\tau(\ee)=\cup\{\delta_\tau^i(\ee)\mid i\ge 0\}$ with
2393: \begin{align*}
2394: \delta_\tau^0(\ee)&=\emptyset\\
2395: \delta_\tau^{i+1}(\ee)&=\begin{cases}
2396: \emptyset\\
2397: \quad\text{if $\mathtt{this}\in\domain(\tau)$ and
2398: no $\pi\in \ee$ is
2399: s.t.\ $k(\pi)\le\tau(\mathtt{this})$}\\
2400: \mbox{}\\
2401: \cup\bigl\{\,
2402: \{\pi\}\cup\delta^i_{F(\pi)}(\ee)\bigm|
2403: \kappa\in\codom(\tau)\cap\mathcal{K},\ \pi\in \ee,\ k(\pi)\le\kappa
2404: \,\bigr\}\\
2405: \quad\text{otherwise.}
2406: \end{cases}
2407: \end{align*}
2408: \end{definition}
2409: %
2410: It follows from Definition~\ref{def:delta}
2411: that $\delta_\tau^i\subseteq\delta_\tau^{i+1}$ and
2412: hence $\delta_\tau=\delta_\tau^{\#\Pi}$.
2413: Note that in Definition~\ref{def:delta} we consider all
2414: subclasses of $\kappa$ (Example~\ref{ex:escape_analysis}).
2415: %
2416: \begin{example}\label{ex:delta1}
2417: \ifcorr{%
2418: Let us look at the program in Figure~\ref{fig:program}.
2419: }
2420:
2421: \ifcorrx{%
2422: Consider first the program point $w_0$ and the type environment
2423: \(
2424: \tau_{w_0} \!=
2425: [\Out\!\mapsto\integer,
2426: \mathtt{this}\!\mapsto\mathtt{Circle}]
2427: \)
2428: at program point $w_0$.
2429: Let $\ee\!=\!\{\overline{\pi},\pi_1,\pi_3,\pi_4\}$.
2430: Then, it can be seen in Figure~\ref{fig:static_information} that
2431: $\codom(F(\mathtt{Circle})) \cap \mathcal{K} = \{\mathtt{Figure}\}$.
2432: Note that $\kappa(\pi_3) = \mathtt{Circle} = \tau_{w_0}(\this)$.
2433: Thus, for every $i\in\nat$, we have
2434: %
2435: \begin{align*}
2436: \delta^1_{F(\mathtt{Circle})}(\ee)&=
2437: \cup \bigl\{\, \{\pi\}\cup\delta^0_{F(k(\pi))}(\ee) \bigm|
2438: \pi\in \ee,\ k(\pi)\le\mathtt{Figure} \,\bigr\}=\{\pi_3\}\\
2439: \delta^{i+1}_{F(\mathtt{Circle})}(\ee)&=
2440: \cup \bigl\{\, \{\pi\}\cup\delta^i_{F(k(\pi))}(\ee) \bigm|
2441: \pi\in \ee,\ k(\pi)\le\mathtt{Figure} \,\bigr\}\\
2442: &=\{\pi_3\}\cup\delta^i_{F(\mathtt{Circle})(\ee)}~,
2443: \end{align*}
2444: which is enough to prove, by induction, that
2445: $\delta^i_{F(\mathtt{Circle})}(\ee)=\{\pi_3\}$ for every $i\ge 1$.
2446: Then we have
2447: %
2448: \begin{align*}
2449: \delta^{i+2}_{\tau_{w_0}}(\ee)&=\cup \bigl\{\,
2450: \{\pi\}\cup\delta^{i+1}_{F(k(\pi))}(\ee) \bigm|
2451: \kappa\in\codom(\tau)\cap\mathcal{K},\ \pi\in \ee,\ k(\pi)\le\kappa
2452: \,\bigr\}\\
2453: &=\cup \bigl\{\, \{\pi\}\cup\delta^{i+1}_{F(k(\pi))}(\ee) \bigm|
2454: \pi\in \ee,\ k(\pi)\le\mathtt{Circle}
2455: \,\bigr\}\\
2456: &=\{\pi_3\}\cup\delta^{i+1}_{F(\mathtt{Circle})}(\ee)=\{\pi_3\}.
2457: \end{align*}
2458: %\end{example}
2459: }
2460:
2461: \ifcorrx{%
2462: %\begin{example}\label{ex:delta2}
2463: Consider now the program point $w_1$ and
2464: the type environment
2465: $\tau_{w_1}$ at program point $w_1$ as given in Figure~\ref{fig:state}.
2466: Let $\ee=\{\overline{\pi},\pi_1,\pi_3,\pi_4\}$.
2467: Suppose that $i > 0$. As $\codom(F(\mathtt{Scan}))= \emptyset$, we have
2468: $\delta^i_{F(\mathtt{Scan})}(\ee)=\emptyset$;
2469: in the previous paragraph we have shown that
2470: $\delta^i_{F(\mathtt{Circle})}(\ee)=\{\pi_3\}$;
2471: similarly, it can be seen that
2472: $\delta^i_{F(\mathtt{Square})}(\ee)=\{\pi_1,\pi_3,\pi_4\}$.
2473: We therefore can conclude that, for all $i > 0$,
2474: %
2475: \begin{align*}
2476: \delta_{\tau_{w_1}}(\ee)
2477: &=\delta^{i+1}_{\tau_{w_1}}(\ee)\\
2478: &=\cup \bigl\{\{\pi\}\cup\delta^i_{F(k(\pi))}(\ee) \bigm|
2479: \kappa\in\{\mathtt{Figure},\mathtt{Scan}\},\ \pi\in \ee,\ k(\pi)\le\kappa
2480: \,\bigr\}\\
2481: &=\{\overline{\pi},\pi_3\}\cup\delta^{i+1}_{F(\mathtt{Square})}(\ee)
2482: \cup\delta^i_{F(\mathtt{Circle})}(\ee)
2483: \cup\delta^i_{F(\mathtt{Scan})}(\ee)\\
2484: &=\{\overline{\pi},\pi_3\}\cup\{\pi_1,\pi_3,\pi_4\}\cup\{\pi_3\}\cup
2485: \emptyset\\
2486: &=\{\overline{\pi},\pi_1,\pi_3,\pi_4\}.
2487: \end{align*}
2488: %
2489: Then all the creation points in $\ee$
2490: are useful in $w_1$ (compare this with Example~\ref{ex:escape_analysis}).
2491: \qed
2492: }
2493: \end{example}
2494:
2495: Proposition~\ref{prop:delta_lco} states
2496: that the abstract garbage collector $\delta_\tau$ is a lower closure operator
2497: so that it possesses the properties of monotonicity,
2498: reductivity and idempotence that would be expected in a garbage collector.
2499: %
2500: \begin{proposition}\label{prop:delta_lco}
2501: Let $i\in\nat$. The abstract garbage collectors $\delta_\tau^i$ and
2502: $\delta_\tau$ are lco's.
2503: \end{proposition}
2504: %% \myproofbis{
2505: %% Since $\delta_\tau=\delta_\tau^{\#\Pi}$, it is enough to prove the result for
2506: %% $\delta_\tau^i$ only.
2507: %% By Definition~\ref{def:delta}, the maps $\delta_\tau^i$ for $i\in\nat$
2508: %% are reductive and monotonic.
2509: %% We prove idempotency by induction over $i\in\nat$.
2510: %% Let $\ee\subseteq\Pi$.
2511: %% We have $\delta_\tau^0\delta_\tau^0(\ee)=
2512: %% \delta_\tau^0(\emptyset)=\emptyset=\delta_\tau^0(\ee)$.
2513: %% Assume that the result holds for a given $i\in\nat$.
2514: %% If $\mathtt{this}\in\domain(\tau)$ and there
2515: %% is no $\pi\in \ee$ such that $k(\pi)\le\tau(\mathtt{this})$, then
2516: %% $\delta_\tau^i\delta_\tau^i(\ee)=\delta_\tau^i(\emptyset)=\emptyset=
2517: %% \delta_\tau^i(\ee)$.
2518: %% Suppose now that, if $\mathtt{this}\in\domain(\tau)$, then
2519: %% there exists $\pi\in \ee$ such that $k(\pi)\le\tau(\mathtt{this})$.
2520: %% By reductivity,
2521: %% $\delta_\tau^{i+1}\delta_\tau^{i+1}(\ee)\subseteq\delta_\tau^{i+1}(\ee)$.
2522: %% We prove that the converse inclusion holds.
2523: %% We have
2524: %% %
2525: %% \begin{equation}\elabel{eq:idempotency}
2526: %% \delta_\tau^{i+1}\delta_\tau^{i+1}(\ee)=\cup\left\{
2527: %% \{\pi\}\cup\delta^i_{F(\pi)}\delta_\tau^{i+1}(\ee)\left|
2528: %% \begin{array}{l}
2529: %% \kappa\in\codom(\tau)\cap\mathcal{K}\\
2530: %% \pi\in\delta_\tau^{i+1}(\ee),\ k(\pi)\le\kappa
2531: %% \end{array}\right.\right\}.
2532: %% \end{equation}
2533: %% %
2534: %% Let $\kappa\in\codom(\tau)\cap\mathcal{K}$ and $\pi\in\Pi$ be such that
2535: %% $k(\pi)\le\kappa$.
2536: %% If $\pi\in\delta_\tau^{i+1}(\ee)$ then, by reductivity, we have $\pi\in \ee$.
2537: %% Conversely, if $\pi\in \ee$ then, by Definition~\ref{def:delta},
2538: %% $\pi\in\delta_\tau^{i+1}(\ee)$.
2539: %% We conclude from~\eref{eq:idempotency} that
2540: %% %
2541: %% \begin{align*}
2542: %% \delta_\tau^{i+1}\delta_\tau^{i+1}(\ee)
2543: %% &= \cup \left\{\{\pi\}\cup\delta^i_{F(\pi)}\delta_\tau^{i+1}(\ee)\left|
2544: %% \begin{array}{l}
2545: %% \kappa\in\codom(\tau)\cap\mathcal{K}\\
2546: %% \pi\in \ee,\ k(\pi)\le\kappa
2547: %% \end{array}
2548: %% \right.\right\}\\
2549: %% \text{(monotonicity)}
2550: %% &\supseteq
2551: %% \cup\left\{\{\pi\}\cup\delta^i_{F(\pi)}\delta_{F(\pi)}^i(\ee)\left|
2552: %% \begin{array}{l}
2553: %% \kappa\in\codom(\tau)\cap\mathcal{K}\\
2554: %% \pi\in \ee,\ k(\pi)\le\kappa
2555: %% \end{array}
2556: %% \right.\right\}\\
2557: %% \text{(ind. hypothesis)}
2558: %% &= \cup \left\{\{\pi\}\cup\delta_{F(\pi)}^i(\ee)\left|
2559: %% \begin{array}{l}
2560: %% \kappa\in\codom(\tau)\cap\mathcal{K}\\
2561: %% \pi\in \ee,\ k(\pi)\le\kappa
2562: %% \end{array}
2563: %% \right.\right\}\\
2564: %% &= \delta_\tau^{i+1}(\ee).
2565: %% \end{align*}
2566: %% %
2567: %% }
2568: %
2569: The following result proves that
2570: $\delta_\tau$ can be used to define $\codom(\alpha^\e_\tau)$. Namely,
2571: the \emph{useful} elements of $\wp(\Pi)$ are those that do not contain
2572: any garbage. The proof of Proposition~\ref{prop:delta_fixpoints}
2573: %(which can be found in Section~\ref{sec:proofs})
2574: relies on the explicit
2575: construction, for every $\ee\subseteq\Pi$,
2576: of a set of concrete states $X$ such
2577: that $\alpha_\tau(X)=\delta_\tau(\ee)$, which is a fixpoint of $\delta_\tau$
2578: by a well-known property of lco's.
2579: %
2580: \begin{proposition}\label{prop:delta_fixpoints}
2581: Let $\delta(\tau)$ be an abstract garbage collector.
2582: We have that $\fp(\delta_\tau)=\codom(\alpha^\e_\tau)$ and
2583: $\emptyset\in\fp(\delta_\tau)$. Moreover, if
2584: $\mathtt{this}\in\domain(\tau)$,
2585: then for every $X\subseteq\Sigma_\tau$ we have
2586: $\alpha^\e_\tau(X)=\emptyset$ if and only if $X=\emptyset$.
2587: \end{proposition}
2588:
2589: Proposition~\ref{prop:delta_fixpoints} lets us assume that
2590: $\alpha^\e_\tau:\wp(\Sigma_\tau)\mapsto\fp(\delta_\tau)$. Moreover, it
2591: justifies the following definition of our domain
2592: $\e$ for escape analysis.
2593: Proposition~\ref{prop:delta_fixpoints} can be used to
2594: compute the possible
2595: approximations from $\e$ at a given program point. However,
2596: it does not specify which of these is best. This is
2597: the goal of an escape analysis (Subsection~\ref{subsec:static_analysis_e}).
2598: %
2599: \begin{definition}[Abstract Domain $\e$]\label{def:property_e}
2600: Our basic domain for escape analysis is
2601: $\e_\tau=\fp(\delta_\tau)$, ordered by set inclusion.
2602: \end{definition}
2603: %
2604: \begin{example}\label{ex:ew}
2605: \ifcorr{%
2606: Let $\tau_{w_0}$
2607: and $\tau_{w_1}$ be as given in Figure~\ref{fig:state}. Then
2608: \begin{align*}
2609: \e_{\tau_{w_0}}&=\{\emptyset\}\cup\{\ee\in\wp(\Pi)\mid
2610: \pi_3\in \ee\text{ and }
2611: \bigl(\{\pi_1,\pi_4\}\cap \ee \neq \emptyset
2612: \text{ entails }\pi_2\in \ee\bigr)\}\\
2613: \e_{\tau_{w_1}}&=\{\emptyset\}\cup\{\ee\in\wp(\Pi)\mid
2614: \overline{\pi}\in \ee\text{ and }
2615: \bigl(\{\pi_1,\pi_4\}\cap \ee \neq \emptyset
2616: \text{ entails }\pi_2\in \ee\bigr)\}.
2617: \end{align*}
2618: The constraints say that there must be a creation point for
2619: the $\mathtt{this}$ variable and that to reach
2620: an $\mathtt{Angle}$ (created at $\pi_1$ or at $\pi_4$)
2621: from the variables in $\domain(\tau_{w_0})$ or
2622: $\domain(\tau_{w_1})$, we must be able to reach
2623: a $\mathtt{Square}$ (created at $\pi_2$).
2624: \qed
2625: }
2626: \end{example}
2627: %
2628: By Definition~\ref{def:alpha}, we know that $\alpha^\e_\tau$
2629: is strict and additive and, by Proposition~\ref{prop:delta_fixpoints},
2630: onto $\e_\tau$. Thus,
2631: by a general result of
2632: abstract interpretation~\cite{CousotC77,CousotC92}
2633: (Section~\ref{sec:preliminaries}),
2634: we have the following proposition.
2635: %
2636: \begin{proposition}\label{prop:e_insertion}
2637: The map $\alpha^\e_\tau$ (Definition~\ref{def:alpha}) is the abstraction
2638: map of a Galois insertion from $\wp(\Sigma_\tau)$ to $\e_\tau$.
2639: \end{proposition}
2640:
2641: Note that if, in Definition~\ref{def:property_e},
2642: we had defined $\e_\tau$ as $\wp(\Pi)$, the map $\alpha^\e_\tau$
2643: would induce just a Galois connection instead of a Galois insertion, as a
2644: consequence of Proposition~\ref{prop:delta_fixpoints}.
2645:
2646: The domain $\e$
2647: % can be used to
2648: %compare abstract domains \wrt the \emph{escape property} \cite{CortesiFW98}.
2649: %Moreover, since it is an abstract domain,
2650: %it
2651: induces optimal abstract operations
2652: which can be used for an actual escape analysis.
2653: We discuss this in the next subsection.
2654: %
2655: \subsection{Static Analysis over $\e$}\label{subsec:static_analysis_e}
2656: %
2657: Figure~\ref{fig:operations_e} defines the abstract counterparts of the
2658: concrete operations in Figure~\ref{fig:concrete_states}.
2659: Proposition~\ref{prop:operations_e} states that they are correct and optimal,
2660: in the sense of abstract interpretation (Section~\ref{sec:preliminaries}).
2661: Optimality is proved by showing that each operation in
2662: Figure~\ref{fig:operations_e} coincides with the optimal operation
2663: $\alpha^\e\circ\mathit{op}\circ\gamma^\e$, where $\mathit{op}$ is the
2664: corresponding concrete operation in Figure~\ref{fig:concrete_states},
2665: as required by the
2666: abstract interpretation framework. Note that the map $\gamma^\e$ is
2667: induced by $\alpha^\e$ (Section~\ref{sec:preliminaries}).
2668: %
2669: \begin{proposition}\label{prop:operations_e}
2670: The operations in Figure~\ref{fig:operations_e} are the optimal counterparts
2671: induced by $\alpha^\e$
2672: of the operations in Figure~\ref{fig:concrete_states} and
2673: of $\cup$.
2674: They are implicitly strict on $\emptyset$, except for
2675: $\mathsf{return}$, which is strict in its first argument only,
2676: and for $\cup$.
2677: \end{proposition}
2678:
2679: \begin{figure}[t]
2680: {\small
2681: \begin{gather}
2682: \begin{align*}
2683: \mathsf{nop}_\tau(\ee)&=\ee & \mathsf{get\_int}_\tau^i(\ee)&=\ee\\
2684: \mathsf{get\_null}^\kappa_\tau(\ee)&=\ee & \mathsf{get\_var}_\tau^v(\ee)&=\ee\\
2685: \mathsf{is\_true}_\tau(\ee)&=\ee & \mathsf{is\_false}_\tau(\ee)&=\ee\\
2686: \mathsf{put\_var}_\tau^v(\ee)&=\delta_{\tau|_{-v}}(\ee) &
2687: \mathsf{is\_null}_\tau(\ee)&=\delta_{\tau|_{-\rs}}(\ee)\\
2688: \mathsf{new}_\tau^\pi(\ee)&=\ee\cup\{\pi\} &
2689: \mathsf{=}_\tau(\ee_1)(\ee_2)&=\mathsf{+}_\tau(\ee_1)(\ee_2)=\ee_2\\
2690: \mathsf{expand}_\tau^{v:t}(\ee)&=\ee &
2691: \mathsf{restrict}_\tau^{\mathit{vs}}(\ee)&=\delta_{\tau_{-\mathit{vs}}}(\ee)\\
2692: \mathsf{call}_\tau^{\nu,v_1,\ldots,v_n}(\ee)&=\delta_{\tau|_{\{v_1,\ldots
2693: v_n,\rs\}}}(\ee) & \cup_\tau(\ee_1)(\ee_2)&=\ee_1\cup \ee_2
2694: \end{align*}\\
2695: \begin{align*}
2696: \mathsf{get\_field}_\tau^f(\ee)&=\begin{cases}
2697: \emptyset & \text{if $\{\pi\in \ee\mid k(\pi)\le\tau(\rs)\}=\emptyset$}\\
2698: \delta_{\tau[\rs\mapsto F(\tau(\rs))(f)]}(\ee) & \text{otherwise}
2699: \end{cases}\\
2700: \mathsf{put\_field}_{\tau,\tau'}^f(\ee_1)(\ee_2)&=\begin{cases}
2701: \emptyset & \text{if $\{\pi\in \ee_1\mid k(\pi)\le\tau(\rs)\}=
2702: \emptyset$}\\
2703: \delta_{\tau|_{-\rs}}(\ee_2) & \text{otherwise}
2704: \end{cases}\\
2705: \mathsf{return}_\tau^\nu(\ee_1)(\ee_2)&=\cup\left\{
2706: \{\pi\}\cup\delta_{F(k(\pi))}(\Pi)\left|
2707: \begin{array}{l}
2708: \kappa\in\codom(\tau|_{-\rs})\cap\mathcal{K}\\
2709: \pi\in\ee_1,\ k(\pi)\le\kappa
2710: \end{array}\right.\right\}\cup\ee_2\\
2711: \mathsf{lookup}^{m,\nu}_\tau(\ee)&=\begin{cases}
2712: \emptyset\qquad\text{if $\ee'=\left\{\pi\in \ee\left|
2713: \begin{array}{l}
2714: k(\pi)\le\tau(\rs)\\
2715: M(k(\pi))(m)=\nu
2716: \end{array}\right.\right\}=\emptyset$}\\
2717: \delta_{\tau|_{-\rs}}(\ee)\cup\left(\bigcup
2718: \{\{\pi\}\cup\delta_{F(k(\pi))}(\ee)\mid\pi\in \ee'\}\right)\quad
2719: \text{otherwise.}
2720: \end{cases}
2721: \end{align*}
2722: \end{gather}}
2723: %
2724: \caption{The optimal abstract operations over $\e$.}
2725: \label{fig:operations_e}
2726: \end{figure}
2727:
2728: Many operations in Figure~\ref{fig:operations_e} coincide with the
2729: identity map.
2730: This is a sign of the computational imprecision conveyed by the
2731: domain $\e$. Other operations call the $\delta$ garbage collector quite often
2732: to remove creation points of objects which might become unreachable
2733: since some variable has disappeared from the scope. For instance, as the
2734: concrete $\mathsf{put\_var}$ operation removes variable $v$ from
2735: the scope (Figure~\ref{fig:concrete_states}), its abstract counterpart
2736: in Figure~\ref{fig:operations_e} calls the garbage collector.
2737: %
2738: The same happens for $\mathsf{restrict}$ which, however, removes a \emph{set}
2739: of variables from the scope.
2740: %
2741: There are also some operations ($\mathsf{is\_null}$,
2742: $\mathsf{put\_field}$, $\mathsf{lookup}$) that use $\rs$ as a
2743: temporary variable and one operation ($\mathsf{get\_field}$) that
2744: changes the type of $\rs$. Hence these abstract operations
2745: also need to call the garbage collector.
2746: %
2747: Note that the definitions of the
2748: $\mathsf{get\_field}$, $\mathsf{put\_field}$ and
2749: $\mathsf{lookup}$ operations also consider, separately, the unusual situation
2750: when we read a field, respectively, write a field or call a method and
2751: the receiver is \emph{always} $\nil$. In this case, the concrete computation
2752: always stops so that the best approximation of the (empty) set of subsequent
2753: states is $\emptyset$.
2754: %
2755: The garbage collector is also called by
2756: $\mathsf{call}$ since it creates a scope for the callee where
2757: only some of the variables of the caller (namely, the parameters of
2758: the callee) are addressable.
2759: %
2760: The $\mathsf{new}$ operation adds its creation point to the
2761: approximation, since its concrete counterpart creates an object and
2762: binds it to the temporary variable $\rs$.
2763: %
2764: The $\cup$ operation computes the union of the creation points
2765: reachable from at least one of the two branches of a conditional.
2766: %
2767: The $\mathsf{return}$ operation states that all fields of the objects bound
2768: to the
2769: variables in scope before the call might have been modified by the
2770: call. This is reflected by the use of $\delta_{F(k(\pi))}(\Pi)$ in
2771: $\mathsf{return}$, which plays the role of a worst-case assumption on
2772: the content of the fields. After
2773: Example~\ref{ex:abstract_operations_e} we discuss how to cope with the
2774: possible imprecision of this definition.
2775: %
2776: The $\mathsf{lookup}$ operation computes first the set $e'$ of the
2777: creation points of objects that may be receivers of the virtual
2778: call. If this set is not empty, the variable $\rs$ (which holds the
2779: receiver of the call) is required to be bound to an object created at
2780: some creation point in $e'$. This further constrains the creation
2781: points reachable from $\rs$ and this is why we call the garbage
2782: collector $\delta_{F(k(\pi))}$ for each $\pi\in e'$.
2783:
2784: The definitions of $\mathsf{return}$ and $\mathsf{lookup}$ are quite complex;
2785: this is a consequence of our quest for \emph{optimal} abstract operations.
2786: It is possible to replace their definitions in Figure~\ref{fig:operations_e}
2787: by the less precise but simpler definitions:
2788: \[
2789: \mathsf{return}_\tau^\nu(e_1)(e_2)=\delta_\tau(\Pi)\cup e_2\qquad
2790: \mathsf{lookup}_\tau^{m,\nu}(e)=e.
2791: \]
2792: Note though that, in practice, the results with the simpler definitions will
2793: often be the same.
2794: %
2795: \begin{example}\label{ex:abstract_operations_e}
2796: \ifcorr{%
2797: Let us mimic, in $\e$, the concrete computation
2798: of Example~\ref{ex:concrete_operations}.
2799: Let the type environment $\tau = \tau_{w_1}$
2800: and the concrete states $\sigma_1$ and $\sigma_2$
2801: be as given in Figure~\ref{fig:state}.
2802: We start by constructing elements $\ee_1$ and $\ee_2$ of $\e$
2803: corresponding to $\sigma_1$ and $\sigma_2$.
2804: The abstract state $\ee_1$ is obtained by abstracting $\sigma_1$
2805: (see Example~\ref{ex:e_domain}):
2806: \begin{align*}
2807: \ee_1&=\alpha^\e_\tau(\{\sigma_1\})=\alpha^\e_\tau(\sigma_1)
2808: =\{\overline{\pi},\pi_2\}\\
2809: \ee_2&=\mathsf{get\_var}_\tau^\mathtt{f}(\ee_1)
2810: =\{\overline{\pi},\pi_2\}.
2811: \end{align*}
2812: %
2813: There are three abstract $\mathsf{lookup}$ operations corresponding to the
2814: concrete ones and hence we construct
2815: for $i=3,\ldots,6$, elements $\ee_i'$, $\ee_i''$, $\ee_i'''$ of $\e$
2816: corresponding to the concrete states $\sigma_i'$, $\sigma_i''$, $\sigma_i'''$,
2817: respectively.
2818: %
2819: \begin{align*}
2820: \ee_3'&=\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
2821: ^{\mathtt{def},\mathtt{Figure.def}}(\ee_2)=\emptyset\\
2822: &\text{since $\{\pi\in \ee_2\mid k(\pi)\le
2823: \mathtt{Figure}\text{ and }M(\pi)(\mathtt{def})=
2824: \mathtt{Figure.def}\}=\emptyset$}\\
2825: \ee_3''&=\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
2826: ^{\mathtt{def},\mathtt{Square.def}}(\ee_2)\\
2827: &=\delta_\tau(\ee_2)\cup\left(\bigcup\left\{\left.\{\pi\}\cup
2828: \delta_{F(k(\pi))}(\ee_2)\right|\pi\in \ee''\right\}\right)
2829: =\{\overline{\pi},\pi_2\}\cup\{\pi_2\}\\
2830: &=\{\overline{\pi},\pi_2\}~,\\
2831: &\text{since $\ee''=\left\{\pi\in \ee_2\left|\begin{array}{l}
2832: k(\pi)\le\mathtt{Figure}\\
2833: M(\pi)(\mathtt{def})=\mathtt{Square.def}
2834: \end{array}\right.\right\}=\{\pi_2\}$}
2835: \end{align*}
2836: \begin{align*}
2837: \ee_3'''&=\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
2838: ^{\mathtt{def},\mathtt{Circle.def}}(\ee_2)=\emptyset\\
2839: &\text{since $\ee'''=\left\{\pi\in \ee_2\left|
2840: \begin{array}{l}
2841: k(\pi)\le\mathtt{Figure}\\
2842: M(\pi)(\mathtt{def})=\mathtt{Circle.def}
2843: \end{array}\right.\right\}=\emptyset$.}
2844: \end{align*}
2845: %
2846: The $\mathsf{lookup}$ operations for
2847: $\mathtt{Figure}$ and $\mathtt{Circle}$ return $\emptyset$ so that,
2848: as the abstract operations over $\e$ are strict on $\emptyset$
2849: (Proposition~\ref{prop:operations_e}), $\ee_4' = \ee_5' = \ee_6' =
2850: \ee_4'''=\ee_5'''=\ee_6'''= \emptyset$. This is because the analysis is able
2851: to guess the target of the virtual call $\mathtt{f.def()}$, since the only
2852: objects reachable there are
2853: a $\mathtt{Square}$ (created in $\pi_2$)
2854: and a $\mathtt{Scan}$ which, however, is not compatible with the declared type
2855: of the receiver of the call.
2856: Hence we only have to consider the case when a
2857: $\mathtt{Square}$ is selected:
2858: %
2859: \begin{align*}
2860: \ee_4''&=\mathsf{call}^\mathtt{Square.def}_{\tau[\rs\mapsto\mathtt{Square}]}
2861: (\ee_3'')=\delta_{[\rs\mapsto\mathtt{Square}]}(\ee_3'')=\{\pi_2\}.
2862: \end{align*}
2863: %
2864: Since $P(\mathtt{Square.def})|_{\Out}
2865: =[\Out\mapsto\integer]$ and $\e_{[\Out\mapsto\integer]}=\{\emptyset\}$,
2866: we do not need to execute the method $\mathtt{Square.def}$ to conclude that
2867: \[
2868: \ee_5''=\emptyset.
2869: \]
2870: Hence
2871: \begin{align*}
2872: \ee_6''&=\mathsf{return}^\mathtt{Square.def}
2873: _{\tau[\rs\mapsto\mathtt{Square}]}(\ee_3'')(\ee_5'')\\
2874: &=\cup\{\{\pi\}\cup\delta_{F(k(\pi))}(\Pi)\mid\pi\in
2875: \{\overline{\pi},\pi_2\}\}=
2876: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}.
2877: \end{align*}
2878: %
2879: Since the abstract semantics is non-deterministic, we merge the results
2880: of every thread of execution through the $\cup$ operation. Hence the abstract
2881: state after the execution of the call $\mathtt{f.def()}$ in Figure
2882: \ref{fig:program} is
2883: \[
2884: \ee_6=\ee_6'\cup \ee_6''\cup \ee_6'''=\emptyset\cup
2885: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\cup\emptyset=
2886: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}.
2887: \]
2888: \qed
2889: }
2890: \end{example}
2891:
2892: \ifcorrx{%
2893: In Example~\ref{ex:abstract_operations_e}, the imprecision of the analysis
2894: induced by $\e$ is largely due to the abstract operation $\mathsf{return}$
2895: used to compute $\ee_6''$. The creation points $\pi_1$ and
2896: $\pi_4$ for $\mathtt{Angle}$s need to be added
2897: because in the execution of the methods $\mathtt{Square.def}$
2898: any field of the object bound to $\mathtt{this}$ \emph{could} be
2899: modified. For instance, an $\mathtt{Angle}$
2900: could be bound to the field $\mathtt{rotation}$ of
2901: the object bound to $\mathtt{this}$.
2902: This is what actually happens
2903: for $\pi_1$ in the method $\mathtt{Square.def}$
2904: (Figure~\ref{fig:program}), while the introduction of the creation point
2905: $\pi_4$ is an imprecise (but correct) assumption.
2906: This is a consequence of the definition
2907: of $\e$ as the set of sets of \emph{reachable} creation points.
2908: At the end of a method, we only have rather weak information about
2909: the set $\ee$ of creation points of the objects reachable from $\Out$.
2910: For instance, if $\Out$ has type $\integer$, such as in
2911: Example~\ref{ex:abstract_operations_e}, we can only have $\ee=\emptyset$.
2912: When we return to the caller, the actual parameters return into scope.
2913: The definition of $\mathsf{return}$ in Figure~\ref{fig:concrete_states} shows
2914: that these parameters are unchanged (because of the condition
2915: $\mu_1=_L\mu_2$, where $L = \codom(\phi_1)|_{-\rs}\cap\Loc$,
2916: on the concrete operation).
2917: This is reflected by the condition $\pi\in e_1$
2918: in the abstract $\mathsf{return}$ operation in Figure~\ref{fig:operations_e}.
2919: However, we do not know anything about their \emph{fields}.
2920: Without such information,
2921: only a pessimistic assumption can be made, which is
2922: expressed by the use of $\Pi$ in the abstract $\mathsf{return}$ operation.
2923: This problem can be solved
2924: by including a \emph{shadow copy} of the actual parameters among
2925: the variables in scope inside a method.
2926: An example of the use of this
2927: technique will be given later (see Example~\ref{ex:abstract_operations_er2}).
2928: By using this technique, we can actually improve the precision of the
2929: computation in Example~\ref{ex:abstract_operations_e}. As reported in
2930: Example~\ref{ex:e_imprecise}, we get the more precise approximation
2931: $\{\overline{\pi},\pi_1,\pi_2\}$ after the first call to $\mathtt{f.def()}$.
2932: }
2933:
2934: There is, however, another problem related with the domain $\e$.
2935: It is exemplified below.
2936: %
2937: \begin{example}\label{ex:abstract_operations_e2}
2938: \ifcorr{%
2939: Let the approximation provided by $\e$ before the statement
2940: $\mathtt{f\ =\ new\ Circle()}$ in Figure~\ref{fig:program}
2941: be $\{\overline{\pi},\pi_1,\pi_2,\pi_4\}$ (Example~\ref{ex:e_imprecise}).
2942: We can compute the approximation \emph{after}
2943: that statement by executing two abstract operations.
2944: Since the object created in $\pi_3$ gets stored
2945: inside the variable $\mathtt{f}$, we would expect the creation point $\pi_2$
2946: of the old value of $\mathtt{f}$ to disappear. But this does not happen:
2947: %
2948: \begin{align*}
2949: \mathsf{new}_\tau^{\pi_3}(\{\overline{\pi},\pi_1,\pi_2,\pi_4\})
2950: &=\{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}\\
2951: \mathsf{put\_var}^\mathtt{f}_{\tau[\rs\mapsto\mathtt{Circle}]}
2952: (\{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\})&=
2953: \{\overline{\pi},\pi_1,\pi_2,\pi_3,\pi_4\}.
2954: \end{align*}
2955: \qed
2956: }
2957: \end{example}
2958: %
2959: \ifcorrx{%
2960: This time, the imprecision is a consequence of the fact that
2961: $\mathtt{n}\in\domain(\tau)$, $\tau(\mathtt{n})=\mathtt{Figure}$ and
2962: $k(\pi_2)=\mathtt{Square}\le\mathtt{Figure}$. Since the abstract domain
2963: $\e$ does not allow one to know the creation points of the objects
2964: bound to \emph{a given} variable,
2965: but only provides global information on the creation points of the objects
2966: bound to variables and fields \emph{as a whole},
2967: we do not know whether $\pi_2$ is the creation point of an object bound
2968: to $\mathtt{f}$ (and in such a case it disappears) or to
2969: $\mathtt{n}$ instead (and in such a case it must \emph{not} disappear). Hence
2970: a correct $\mathsf{put\_var}$ operation cannot make $\pi_2$ disappear.
2971: We solve this problem in Section~\ref{sec:erdomain} by introducing this
2972: missing information into a new, more precise, abstract domain $\er$.
2973: }
2974: %
2975: %We can solve this problem is two ways.
2976: %The first technique uses two elements of $\e$ during the analysis of
2977: %a method. The first element uses a type environment that describes only
2978: %the variables of the callee. The second element uses a type
2979: %environment that includes also the fields of the variables of the caller.
2980: %In this way, at the end of the method we have information about those fields.
2981: %A much simpler technique, but quite effective in practice, uses only the
2982: %first element of $\e$ during the analysis. At $\mathsf{return}$ time, it
2983: %uses, instead of $\Pi$,
2984: %the set $S_\nu$ of the creation points of the objects which can actually be
2985: %created during the execution of the callee $\nu$. This set can be computed by
2986: %a simple inspection of the program, by using its control-flow graph
2987: %in case the callee calls other methods itself. For instance, in Figure
2988: %\ref{fig:program} we have $S_{\mathtt{square\_def}}=\{\pi_1\}$ and
2989: %$S_{\mathtt{circle\_def}}=\emptyset$. Then
2990: %\begin{align*}
2991: % S_8''&=\mathsf{return}^\mathtt{square\_def}
2992: % _{\tau[\rs\mapsto\mathtt{square}]}(S_5'')(S_7'')\\
2993: % &=\cup\{\{\pi\}\cup\delta_{F(\pi)}(\{\pi_1\})\mid\pi\in
2994: % \{\overline{\pi},\pi_2,\pi_3\}\}=
2995: % \{\overline{\pi},\pi_1,\pi_2,\pi_3\}\\
2996: % S_8'''&=\mathsf{return}^\mathtt{circle\_def}
2997: % _{\tau[\rs\mapsto\mathtt{circle}]}(S_5''')(S_7''')\\
2998: % &=\cup\{\{\pi\}\cup\delta_{F(\pi)}(\emptyset)\mid\pi\in
2999: % \{\overline{\pi},\pi_2,\pi_3\}\}=
3000: % \{\overline{\pi},\pi_2,\pi_3\}
3001: %\end{align*}
3002: %
3003: %and $S_8=\{\overline{\pi},\pi_1,\pi_2,\pi_3\}$.
3004:
3005: %Although the abstract domain $\e$ was meant as a starting point
3006: %for more precise escape analyses rather than for an actual implementation,
3007: %we provide below the theoretical worst-case complexity of the static analysis
3008: %induced by $\e$.
3009: %
3010: %\begin{proposition}\label{prop:complexity}
3011: %Let $p=\#\Pi$, $n$ be the number of commands of the program $P$ to be analysed,
3012: %$b$ the number of nodes of the call graph of $P$ and $t$ the maximal number
3013: %of fields of an object or of variables in scope. The cost in time
3014: %of the analysis induced by $\e$ is $O(bnt2^p)$.
3015: %\end{proposition}
3016: %\myproofbis{
3017: %The result, from given inputs, of an operation
3018: %in Figure~\ref{fig:operations_e} can be computed in time
3019: %$O(p^2t)$. For instance, consider the $\mathsf{lookup}$ operation, which
3020: %is the more complex one. The computation of $\ee'$ and its test for emptiness
3021: %can be computed in $O(p)$. Then we compute the $\delta$ function
3022: %$\#\ee'+1$ times \ie $O(p)$ times. Computing $\delta$ requires
3023: %at most $p$ iterations, and each iteration can be computed in
3024: %$O(t)$ (Definition~\ref{def:delta}). Then the cost for computing
3025: %$\mathsf{lookup}$ from a given input is $O(p^2t)$. Simpler reasonings apply
3026: %to the other operations in Figure~\ref{fig:operations_e}.
3027: %Since we have $O(2^p)$ possible inputs,
3028: %the cost for computing the denotation of an operation
3029: %in Figure~\ref{fig:operations_e} is $O(tp^22^p)=O(t2^p)$.
3030: %
3031: %The cost in time for joining two denotations $d_1$ and $d_2$
3032: %(\ie for computing the denotation of the
3033: %composition of two operations in Figure~\ref{fig:operations_e}) is
3034: %$O(2^p)$, since for every input $i$ of $d_1$ we search
3035: %$d_1(i)$ among the inputs of $d_2$. This search costs $O(2^p)$ and is performed
3036: %$O(2^p)$ times (similarly for binary operations).
3037: %
3038: %The cost in time for computing the denotation of a sequence of $m$
3039: %commands is then $O(mt2^p+m2^p)=O(mt2^p)$,
3040: %since we compute the denotation of every
3041: %single command and then we join them. Note that a sequence of $m$ commands
3042: %is translated in a sequence of $O(m)$ operations from Figure
3043: %\ref{fig:operations_e} \cite{Spoto01}.
3044: %
3045: %Let $l$ be the number of strongly connected components of the call graph
3046: %of the program, $f$ be one of these components,
3047: %$b_f$ the number of nodes of $f$ and $n_f$ the total number of commands
3048: %in the nodes of $f$. Every iteration of the local fixpoint over $f$
3049: %costs $O(n_ft2^p)$ as shown before. At every iteration, the
3050: %denotation of at least one node of $f$ must change, and that denotation
3051: %can change at most $p2^p$ times (every denotation has at most $2^p$ outputs
3052: %and each output can take at most $p$ different values). Then
3053: %the local fixpoint is reached after at most
3054: %$O(b_fp2^p)$ iterations. The total cost for its computation is then
3055: %$O(b_fp2^pn_ft2^p)=O(b_fn_ft2^p)$.
3056: %
3057: %The cost for computing the denotation (analysis) of the whole program is
3058: %
3059: %\begin{equation}\label{eq:cost}
3060: % \sum_{f=1}^lO(b_fn_ft2^p)
3061: % =O\left(t2^p\cdot\sum_{f=1}^l(b_fn_f)\right).
3062: %\end{equation}
3063: %%
3064: %Since $\sum_{f=1}^l(b_fn_f)\le
3065: %\sum_{f=1}^l(b_fn)=n\cdot\sum_{f=1}^lb_f=bn$, \eref{eq:cost} is
3066: %$O(bnt2^p)$.}
3067: %
3068: \section{The Refined Domain $\er$}\label{sec:erdomain}
3069: %
3070: We define here a \emph{refinement} $\er$ of the domain $\e$ of
3071: Section~\ref{sec:edomain}, in the sense that $\er$ is a concretisation of
3072: $\e$ (Proposition~\ref{prop:inclusion}). The idea underlying the
3073: definition of $\er$ is that the precision of $\e$ can be improved
3074: if we can speak about the creation points of the objects bound
3075: to \emph{a given} variable or field (see the problem
3076: highlighted in Example~\ref{ex:abstract_operations_e2}).
3077: The construction of $\er$ is very similar to that of $\e$.
3078: %
3079: \subsection{The Domain}\label{subsec:erdomain}
3080: %
3081: Definition~\ref{def:domains2} defines concrete values.
3082: The domain $\er$ we are going to define approximates
3083: every concrete value with an \emph{abstract value}.
3084: An abstract value is either $*$, which approximates the integers, or
3085: a set $\ee\subseteq\Pi$, which approximates $\nil$ and all locations
3086: containing an object created in some creation point in $\ee$.
3087: An abstract frame maps variables to
3088: abstract values consistent with their type.
3089: %and such that \texttt{this} is bound.
3090: %
3091: \begin{definition}[Abstract Values and Frames]\label{def:frames1}
3092: Let the \emph{abstract values} be
3093: $\Value^{\er}=\{*\}\cup\wp(\Pi)$. We define
3094: \[
3095: \Frame_\tau^{\er}=\left\{\phi\in\domain(\tau)\mapsto\Value^{\er}\left|
3096: \begin{array}{l}
3097: % \text{if $\mathtt{this}\in\domain(\tau)$ then $\phi(\mathtt{this})
3098: % \not=\emptyset$}\\
3099: \text{for every }v\in\domain(\tau)\\
3100: \text{ if }\tau(v)=\integer\text{ then }\phi(v)=*\\
3101: \text{ if }\tau(v)\in\mathcal{K}\text{ and }\pi\in\phi(v)\\
3102: \ \ \text{ then }k(\pi)\le\tau(v)
3103: \end{array}
3104: \right.\right\}.
3105: \]
3106: The set $\Frame_\tau^\er$ is ordered by pointwise set-inclusion.
3107: \end{definition}
3108: %
3109: \begin{example}\label{ex:frames_er}
3110: \ifcorr{%
3111: Let $\tau_{w_1}$ be as defined in Figure~\ref{fig:state}.
3112: Then we have
3113: \begin{align*}
3114: [\mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\{\pi_2,\pi_3\},
3115: \Out\mapsto *,\mathtt{this}\mapsto\{\overline{\pi}\}]
3116: &\in\Frame_{\tau_{w_1}}^{\er}\\
3117: [\mathtt{f}\mapsto\{\overline{\pi},\pi_2\},\mathtt{n}\mapsto\{\pi_2,\pi_3\},
3118: \Out\mapsto *,\mathtt{this}\mapsto\{\overline{\pi}\}]
3119: &\not\in\Frame_{\tau_{w_1}}^{\er}~,
3120: \end{align*}
3121: since $k(\overline{\pi})=\mathtt{Scan}$,
3122: $\tau_{w_1}(\mathtt{f})=\mathtt{Figure}$ and
3123: $\mathtt{Scan}\not\le\mathtt{Figure}$.
3124: \qed
3125: }
3126: \end{example}
3127:
3128: The map $\varepsilon$ \emph{extracts} the creation points of the objects
3129: bound to the variables.
3130: %
3131: \begin{definition}[Extraction Map]\label{def:extractor}
3132: The map $\varepsilon_\tau:\wp(\Sigma_\tau)\mapsto\Frame^\er_\tau$ is such that,
3133: for every $S\subseteq\Sigma_\tau$ and $v\in\domain(\tau)$,
3134: \[
3135: \varepsilon_\tau(S)(v)=
3136: \begin{cases}
3137: * & \text{if $\tau(v)=\integer$}\\
3138: \{(\mu\phi(v)).\pi\mid\phi\sep\mu\in S
3139: \text{ and }\phi(v)\in\Loc\} & \text{if $\tau(v)\in\mathcal{K}$.}
3140: \end{cases}
3141: \]
3142: \end{definition}
3143: %
3144: \begin{example}\label{ex:extractor}
3145: \ifcorr{%
3146: Consider the state $\sigma_1$ in Figure~\ref{fig:state}. Then
3147: \[
3148: \varepsilon_{\tau_{w_1}}(\sigma_1)=
3149: [
3150: \mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\emptyset,
3151: \Out\mapsto *,\mathtt{this}\mapsto\{\overline{\pi}\}
3152: ].
3153: \]
3154: \qed
3155: }
3156: \end{example}
3157:
3158: Since it is assumed that all the fields are uniquely identified by their
3159: fully qualified name, the type environment $\widetilde{\tau}$
3160: \emph{of all the fields} introduced by the program is well-defined.
3161: %
3162: \begin{definition}[Type Environment of All Fields]\label{def:all_fields}
3163: \hspace*{-1ex}We define the \emph{type environment of all fields} as
3164: $\widetilde{\tau}=\cup\{F(\kappa)\mid\kappa\in\mathcal{K}\}$.
3165: Let $\tau\in\Typing$
3166: be such that $\domain(\tau)\subseteq\domain(\widetilde{\tau})$
3167: and $\phi\in Frame_\tau$. Its \emph{extension}
3168: $\widetilde{\phi}\in\Frame_{\widetilde{\tau}}$ is such that, for every
3169: $v\in\domain(\widetilde{\tau})$,
3170: \[
3171: \widetilde{\phi}(v)=\begin{cases}
3172: \phi(v) & \text{if $v\in\domain(\tau)$}\\
3173: \init(\widetilde{\tau}(v)) &
3174: \text{otherwise (Definition~\ref{def:domains2}).}
3175: \end{cases}
3176: \]
3177: \end{definition}
3178: %
3179: \begin{example}\label{ex:tauoverlined}
3180: \ifcorr{%
3181: Consider the map $F$ in Figure~\ref{fig:static_information}
3182: for the program in Figure~\ref{fig:program}. Then
3183: \[
3184: \widetilde{\tau}=\left[\begin{array}{l}
3185: \mathtt{Circle.x}\mapsto\integer,
3186: \mathtt{Circle.y}\mapsto\integer,\mathtt{degree}\mapsto\integer\\
3187: \mathtt{next}\mapsto\mathtt{Figure},\mathtt{radius}\mapsto\integer,
3188: \mathtt{rotation}\mapsto\mathtt{Angle}\\
3189: \mathtt{side}\mapsto\integer,
3190: \mathtt{Square.x}\mapsto\integer,\mathtt{Square.y}\mapsto\integer
3191: \end{array}\right].
3192: \]
3193: Let $\phi=[\mathtt{Circle.x}\mapsto 12,\mathtt{Circle.y}\mapsto 5,
3194: \mathtt{next}\mapsto l,\mathtt{radius}\mapsto 5]\in F(\mathtt{Circle})$,
3195: with $l\in\Loc$. We have
3196: \[
3197: \widetilde{\phi}=\left[\begin{array}{l}
3198: \mathtt{Circle.x}\mapsto 12,
3199: \mathtt{Circle.y}\mapsto 5,\mathtt{degree}\mapsto 0\\
3200: \mathtt{next}\mapsto l,\mathtt{radius}\mapsto 5,
3201: \mathtt{rotation}\mapsto\nil,
3202: \mathtt{side}\mapsto 0\\
3203: \mathtt{Square.x}\mapsto 0,\mathtt{Square.y}\mapsto 0
3204: \end{array}\right].
3205: \]
3206: }
3207: \qed\end{example}
3208:
3209: An abstract memory is an abstract frame for $\widetilde{\tau}$.
3210: The abstraction map computes the abstract memory by extracting
3211: the creation points of the fields of the reachable objects
3212: of the concrete memory (Definition~\ref{def:reachability}).
3213: %
3214: \begin{definition}[Abstract Map for $\er$]\label{def:er_abstraction}
3215: Let the set of abstract memories be
3216: $\Memory^\er=\Frame_{\widetilde{\tau}}^\er$. We define the map
3217: \[
3218: \alpha_\tau^\er:\wp(\Sigma_\tau)\mapsto\{\bot\}\cup
3219: (\Frame_\tau^\er\times\Memory^\er)
3220: \]
3221: such that, for $S\subseteq\Sigma_\tau$,
3222: %
3223: \[
3224: \alpha_\tau^\er(S)=\begin{cases}
3225: \bot & \text{if $S=\emptyset$}\\
3226: \varepsilon_\tau(S)\sep\varepsilon_{\widetilde{\tau}}(
3227: \{\widetilde{o.\phi} \sep \sigma.\mu \mid
3228: \sigma\in S\text{ and }o\in O_\tau(\sigma)\}) & \text{otherwise.}
3229: \end{cases}
3230: \]
3231: \end{definition}
3232: %
3233: \begin{example}\label{ex:er_domain}
3234: \ifcorr{%
3235: Consider the state $\sigma_1$ in Figure~\ref{fig:state}.
3236: Let $\tau = \tau_{w_1}$ be as given in Figure~\ref{fig:state}.
3237: In Example~\ref{ex:e_domain}
3238: we have shown that $O_\tau(\sigma_1) = \{o_1, o_2\}$
3239: and in Example~\ref{ex:extractor}
3240: we have computed the value of $\varepsilon_\tau(\sigma_1)$. We have
3241: \begin{align*}
3242: \widetilde{o_1.\phi}&=\left[\begin{array}{l}
3243: \mathtt{Circle.x}\mapsto 0,
3244: \mathtt{Circle.y}\mapsto 0,\mathtt{degree}\mapsto 0\\
3245: \mathtt{next}\mapsto\nil,\mathtt{radius}\mapsto 0,
3246: \mathtt{rotation}\mapsto\nil\\
3247: \mathtt{side}\mapsto 0,
3248: \mathtt{Square.x}\mapsto 0,\mathtt{Square.y}\mapsto 0
3249: \end{array}\right],\\
3250: \widetilde{o_2.\phi}&=\left[\begin{array}{l}
3251: \mathtt{Circle.x}\mapsto 0,
3252: \mathtt{Circle.y}\mapsto 0,\mathtt{degree}\mapsto 0\\
3253: \mathtt{next}\mapsto l',\mathtt{radius}\mapsto 0,
3254: \mathtt{rotation}\mapsto\nil\\
3255: \mathtt{side}\mapsto 4,
3256: \mathtt{Square.x}\mapsto 3,\mathtt{Square.y}\mapsto -5
3257: \end{array}\right]
3258: \end{align*}
3259: %
3260: %in $\Memory^\er$.
3261: Then (fields not represented are implicitly bound to $*$)
3262: %
3263: \begin{align*}
3264: \alpha_\tau^\er(\sigma_1)
3265: &=\alpha_\tau^\er(\phi_1 \sep \mu_1)\\
3266: &=\varepsilon_\tau(\sigma_1)\sep\varepsilon_{\widetilde{\tau}}(
3267: \{\widetilde{o_1.\phi}\sep\mu_1,\widetilde{o_2.\phi}\sep\mu_1\})\\
3268: &=\varepsilon_\tau(\sigma_1)\sep\varepsilon_{\widetilde{\tau}}(
3269: \{\widetilde{o_2.\phi}\sep\mu_1\})\\
3270: &=\varepsilon_\tau(\sigma_1)\sep
3271: [\mathtt{next}\mapsto\{\mu_1(l').\pi\},
3272: \mathtt{rotation}\mapsto\emptyset,\ldots]\\
3273: &=[\mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\emptyset,
3274: \Out\mapsto *,\mathtt{this}\mapsto\{\overline{\pi}\}]\\
3275: &\qquad\qquad\qquad \sep [\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation}\mapsto\emptyset,\ldots].
3276: \end{align*}
3277: \qed
3278: }
3279: \end{example}
3280: %
3281: Compare Examples~\ref{ex:er_domain} and~\ref{ex:e_domain}. You can see
3282: that $\er$ distributes over the variables and fields the same creation points
3283: observed by $\e$.
3284:
3285: As a notational simplification, we often assume that each field not
3286: reported in the approximation of the memory is implicitly bound to
3287: $\emptyset$, if it has class type, and bound to $*$, if it has
3288: $\integer$ type.
3289:
3290: Just as for $\alpha_\tau^\e$ (Example~\ref{ex:rho_not_onto}), the
3291: following example shows that the map $\alpha_\tau^\er$ is not
3292: necessarily onto.
3293: %
3294: \begin{example}\label{ex:alpha_er_not_onto}
3295: \ifcorr{%
3296: Let $\tau=[\mathtt{c}\mapsto\mathtt{Circle}]$. A $\mathtt{Circle}$ has no
3297: field called $\mathtt{rotation}$. Then there is no state
3298: $\sigma\in\Sigma_\tau$ such that its abstraction is
3299: $\alpha_\tau^\er(\sigma)=[\mathtt{c}\mapsto\{\pi_3\}]\sep
3300: [\mathtt{next}\mapsto\emptyset,\mathtt{rotation}\mapsto\{\pi_1\},\ldots]$,
3301: since only a $\mathtt{Circle}$ created at $\pi_3$ is reachable from the
3302: variables.
3303: \qed
3304: }
3305: \end{example}
3306: %
3307: Hence, we define
3308: a map $\xi$ which forces to $\emptyset$ the fields of type class
3309: of the objects which have no reachable creation points.
3310: Just as for the garbage collector $\delta$ for $\e$,
3311: the map $\xi$ can be seen as an abstract garbage collector for $\er$.
3312: This $\xi$ uses an auxiliary map $\rho$ to compute
3313: the set of creation points $r$ reachable from
3314: the variables in scope.
3315: %
3316: The approximations of the fields of the objects created at $r$ are not
3317: garbage collected by $\xi$. The approximations of the other fields are
3318: garbage collected instead.
3319: %
3320: \begin{definition}[Abstract Garbage Collector $\xi$]\label{def:xi}
3321: We define $\rho_\tau:\Frame_\tau^\er
3322: \times\Memory^\er\mapsto\wp(\Pi)$ and
3323: $\xi_\tau:\{\bot\}\cup(\Frame_\tau^\er\times\Memory^\er)\linebreak
3324: \mapsto\{\bot\}\cup(\Frame_\tau^\er\times\Memory^\er)$
3325: as $\rho_\tau(s)=\cup\{\rho_\tau^i(s)\mid i\ge 0\}$, where
3326: %
3327: \begin{align*}
3328: \rho_\tau^0(\phi\sep\mu)&=\emptyset\\
3329: \rho_\tau^{i+1}(\phi\sep\mu)&=\bigcup\left\{\left.\{\pi\}\cup
3330: \rho^i_{F(k(\pi))}
3331: (\mu|_{\domain(F(k(\pi)))}\sep\mu)\right|\begin{array}{l}
3332: v\in\domain(\tau)\\
3333: \pi\in\phi(v)
3334: \end{array}\right\}
3335: \end{align*}
3336: and
3337: \begin{align*}
3338: \xi_\tau(\bot)&=\bot\\
3339: \xi_\tau(\phi\sep\mu)&=\begin{cases}
3340: \bot\qquad\text{if $\mathtt{this}\in\domain(\tau)$ and $\phi(\mathtt{this})
3341: =\emptyset$}\\
3342: \phi\sep\left(\cup\{\mu|_{\domain(F(k(\pi)))}\mid
3343: \pi\in\rho_\tau(\phi \sep \mu)\}
3344: %\cup\init(\widetilde{\tau})
3345: \right)\quad\text{otherwise.}
3346: \end{cases}
3347: \end{align*}
3348: \end{definition}
3349: %
3350: \begin{example}
3351: \ifcorr{%
3352: Let $s=[\mathtt{c}\mapsto\{\pi_3\}]
3353: \sep[\mathtt{next}\mapsto\emptyset,\mathtt{rotation}\mapsto\{\pi_1\},\ldots]$.
3354: We have $\rho_\tau(s)=\{\pi_3\}$ and hence
3355: \[
3356: \xi_\tau(s)=[\mathtt{c}\mapsto\{\pi_3\}]\sep
3357: [\mathtt{next}\mapsto\emptyset,\mathtt{rotation}\mapsto\emptyset,\ldots]
3358: \]
3359: \ie the abstract garbage collector $\xi$ has recognised $\pi_1$ as garbage
3360: (compare with Example~\ref{ex:alpha_er_not_onto}).
3361: \qed
3362: }
3363: \end{example}
3364: %
3365: The following property is expected to hold for a garbage collector.
3366: Compare Propositions~\ref{prop:delta_lco} and~\ref{prop:xi_lco}.
3367: %
3368: \begin{proposition}\label{prop:xi_lco}
3369: The abstract garbage collector $\xi_\tau$ is an lco.
3370: \end{proposition}
3371: %
3372: The garbage collector $\xi_\tau$ can be used
3373: to define $\codom(\alpha_\tau^\er)$.
3374: Namely, the \emph{useful} elements of $\Frame^\er_\tau\times\Memory^\er$
3375: are exactly those that do not contain any garbage.
3376: Compare Propositions~\ref{prop:delta_fixpoints} and~\ref{prop:xi_fixpoints}.
3377: %
3378: \begin{proposition}\label{prop:xi_fixpoints}
3379: Let $\xi_\tau$ be the abstract garbage collector of
3380: Definition~\ref{def:xi}. Then $\fp(\xi_\tau)=\codom(\alpha_\tau^\er)$.
3381: \end{proposition}
3382: %
3383: Proposition~\ref{prop:xi_fixpoints}
3384: %(whose proof can be found in Section~\ref{sec:proofs})
3385: allows us to assume that $\alpha_\tau^\er:
3386: \wp(\Sigma_\tau)\mapsto\fp(\xi_\tau)$
3387: and justifies the following definition.
3388: %
3389: \begin{definition}[Abstract Domain $\er$]\label{def:er_domain}
3390: We define $\er_\tau=\fp(\xi_\tau)$, ordered by
3391: pointwise set-inclusion (with the assumption that $*\subseteq *$ and
3392: $\bot\subseteq s$ for every $s\in\er_\tau$).
3393: \end{definition}
3394: %
3395: By Definitions~\ref{def:extractor} and~\ref{def:er_abstraction} we know
3396: that the map $\alpha_\tau^\er$ is strict and additive.
3397: By Proposition~\ref{prop:xi_fixpoints} we know that it is onto.
3398: Thus we have the following result corresponding to
3399: Proposition~\ref{prop:e_insertion} for the domain $\e$.
3400: %
3401: \begin{proposition}\label{prop:er_insertion}
3402: The map $\alpha_\tau^\er$ is
3403: the abstraction map of a Galois insertion from
3404: $\wp(\Sigma_\tau)$ to $\er_\tau$.
3405: \end{proposition}
3406: %
3407: \subsection{Static Analysis over $\er$}\label{subsec:static_analysis_er}
3408: %
3409: In order to use the domain $\er$ for an escape analysis, we need to provide
3410: the abstract counterparts over $\er$ of the concrete operations in
3411: Figure~\ref{fig:concrete_states}. Since $\er$ approximates every
3412: variable and field with an abstract value, those abstract
3413: operations are similar to those of the Palsberg and Schwartzbach's domain
3414: for \emph{class analysis} in~\cite{PalsbergS91} as formulated
3415: in~\cite{SpotoJ03}. However, $\er$ observes the fields of just
3416: the reachable objects (Definition~\ref{def:er_abstraction}), while
3417: Palsberg and Schwartzbach's domain observes the fields of all objects
3418: in memory.
3419:
3420: Figure~\ref{fig:operations_er} reports the abstract counterparts on $\er$ of
3421: the concrete operations in Figure~\ref{fig:concrete_states}.
3422: These operations are implicitly strict on $\bot$ except for $\cup$.
3423: In this case, we define
3424: $\bot \cup (\phi\sep\mu) = (\phi\sep\mu) \cup \bot = \phi\sep\mu$.
3425: Their optimality is proved by showing that each operation in
3426: Figure~\ref{fig:operations_er} coincides with the optimal operation
3427: $\alpha^\er\circ\mathit{op}\circ\gamma^\er$, where $\mathit{op}$ is the
3428: corresponding concrete operation in Figure~\ref{fig:concrete_states},
3429: as required by the
3430: abstract interpretation framework. Note that the map $\gamma^\er$ is
3431: induced by $\alpha^\er$ (Section~\ref{sec:preliminaries}).
3432: %
3433: \begin{proposition}\label{prop:operations_er}
3434: The operations in Figure~\ref{fig:operations_er} are the optimal counterparts
3435: induced by $\alpha^\er$ of the operations in Figure~\ref{fig:concrete_states}
3436: and of $\cup$.
3437: \end{proposition}
3438: %
3439: \begin{figure}[ht]
3440: {\small
3441: \begin{gather}
3442: \begin{align*}
3443: \mathsf{nop}_\tau(\phi\sep\mu)&=\phi\sep\mu\\
3444: \mathsf{get\_int}_\tau^i(\phi\sep\mu)&=\phi[\rs\mapsto *]\sep\mu\\
3445: \mathsf{get\_null}^\kappa_\tau(\phi\sep\mu)&=\phi[\rs\mapsto\emptyset]\sep\mu\\
3446: \mathsf{get\_var}_\tau^v(\phi\sep\mu)&=\phi[\rs\mapsto\phi(v)]\sep\mu\\
3447: \mathsf{is\_true}_\tau(\phi\sep\mu)&=\phi\sep\mu\\
3448: \mathsf{is\_false}_\tau(\phi\sep\mu)&=\phi\sep\mu\\
3449: \cup_\tau(\phi_1\sep\mu_1)(\phi_2\sep\mu_2)&=(\phi_1\cup\phi_2)\sep
3450: (\mu_1\cup\mu_2)\\
3451: \mathsf{is\_null}_\tau(\phi\sep\mu)&=\xi_{\tau[\rs\mapsto\integer]}
3452: (\phi[\rs\mapsto *]\sep\mu)\\
3453: \mathsf{new}_\tau^\pi(\phi\sep\mu)&=\phi[\rs\mapsto\{\pi\}]\sep\mu\\
3454: \mathsf{put\_var}_\tau^v(\phi\sep\mu)&=\xi_{\tau|_{-\rs}}
3455: (\phi[v\mapsto\phi(\rs)]|_{-\rs}\sep\mu)\\
3456: \mathsf{restrict}_\tau^{\mathit{vs}}(\phi\sep\mu)
3457: &=\xi_{\tau|_{-\mathit{vs}}}(\phi|_{-\mathit{vs}}\sep\mu)\\
3458: \mathsf{expand}_\tau^{v:t}(\phi\sep\mu)&=\begin{cases}
3459: \phi[v\mapsto *]\sep\mu & \text{if $t=\integer$}\\
3460: \phi[v\mapsto\emptyset]\sep\mu & \text{otherwise}
3461: \end{cases}\\
3462: \mathsf{=}_\tau(\phi_1\sep\mu_1)(\phi_2\sep\mu_2)&=
3463: \mathsf{+}_\tau(\phi_1\sep\mu_1)(\phi_2\sep\mu_2)=\phi_2\sep\mu_2
3464: \end{align*}\\
3465: \begin{align*}
3466: \mathsf{get\_field}_\tau^f(\phi\sep\mu)&=\begin{cases}
3467: \bot\quad\text{if $\phi(\rs)=\emptyset$}\\
3468: \xi_{\tau[\rs\mapsto F(\tau(\rs))(f)]}(\phi[\rs\mapsto\mu(f)]\sep\mu)
3469: \quad\text{else}
3470: \end{cases}\\
3471: \begin{array}{c}
3472: \mathsf{put\_field}_{\tau,\tau'}^f\\
3473: (\phi_1\sep\mu_1)(\phi_2\sep\mu_2)
3474: \end{array}&=
3475: \begin{cases}
3476: \bot\quad\text{if $\phi_1(\rs)=\emptyset$}\\
3477: \xi_{\tau|_{-\rs}}(\phi_2|_{-\rs}\sep\mu_2) \\
3478: \quad\text{else, if no
3479: $\pi\in\phi_1(\rs)$ occurs in $\phi_2|_{-\rs}\sep\mu_2$}\\
3480: \xi_{\tau|_{-\rs}}(\phi_2|_{-\rs}\sep\mu_2[f\mapsto\mu_2(f)\cup
3481: \phi_2(\rs)])\\
3482: \quad\text{otherwise}
3483: \end{cases}\\
3484: \mathsf{call}_\tau^{\nu,v_1,\ldots,v_n}(\phi\sep\mu)&=
3485: \xi_{P(\nu)|_{-\Out}}
3486: \left(\left[\begin{array}{l}
3487: \iota_1\mapsto\phi(v_1),\ldots,\iota_n\mapsto\phi(v_n)\\
3488: \mathtt{this}\mapsto\phi(\rs)
3489: \end{array}\right]\sep\mu\right)\\
3490: \begin{array}{c}
3491: \mathsf{return}_\tau^\nu\\
3492: (\phi_1\sep\mu_1)(\phi_2\sep\mu_2)
3493: \end{array}&=
3494: \xi_{\tau|_{-\rs}}(\phi_1|_{-\rs}\sep\mu^\top)
3495: \cup([\rs\mapsto\phi_2(\Out)]\sep\mu_2)\\
3496: &\quad\text{where $\mu^\top$ is the top of $\Memory^\er$}\\
3497: \mathsf{lookup}^{m,\nu}_\tau(\phi\sep\mu)&=\begin{cases}
3498: \bot\quad\text{if $\ee\!=\!\{\pi\in\phi(\rs)\mid
3499: M(\pi)(m)\!=\!\nu\}\!=\!\emptyset$}\\
3500: \xi_\tau(\phi[\rs\mapsto \ee]\sep\mu)\quad\text{otherwise.}
3501: \end{cases}
3502: \end{align*}
3503: \end{gather}}
3504: %
3505: \caption{The abstract operations over $\er$.}\label{fig:operations_er}
3506: \end{figure}
3507: %
3508: Let us consider each of the abstract operations.
3509: The operation $\mathsf{nop}$ leaves the
3510: state unchanged. The same happens for the operations working
3511: with integer values only, such as $\mathsf{is\_true}$,
3512: $\mathsf{is\_false}$, $\mathsf{=}$ and $\mathsf{+}$, since the domain
3513: $\er$ ignores variables with integer values.
3514: The concrete operation $\mathsf{get\_int}$ loads an integer
3515: into $\rs$. Hence, its abstract
3516: counterpart loads $*$ into $\rs$, since $*$ is the approximation for
3517: integer values (Definition~\ref{def:frames1}). The concrete operation
3518: $\mathsf{get\_null}$ loads $\nil$ into $\rs$ and hence its
3519: abstract counterpart approximates $\rs$ with $\emptyset$.
3520: The operation $\mathsf{get\_var}^v$ copies the creation points of $v$
3521: into those of $\rs$.
3522: The $\cup$ operation merges the creation points of the objects bound to each
3523: given variable or field in one of the two branches of a conditional.
3524: The concrete $\mathsf{is\_null}$ operation checks if $\rs$ contains
3525: $\nil$ or not, and loads $1$ or $-1$ in $\rs$ accordingly.
3526: Hence its abstract counterpart loads $*$ into $\rs$.
3527: Since the old value of $\rs$ may no longer be reachable,
3528: we apply the abstract garbage collector $\xi$.
3529: %
3530: The $\mathsf{new}^\pi$ operation binds $\rs$ to an object created at $\pi$.
3531: The $\mathsf{put\_var}^v$ operation copies the value of $\rs$ into $v$,
3532: and removes $\rs$. Since the old value of $v$ may be lost, we apply the
3533: abstract garbage collector $\xi$. The $\mathsf{restrict}$ operation removes
3534: some variables from the scope and, hence, calls $\xi$.
3535: The $\mathsf{expand}^v$ operation adds the variable $v$ in scope.
3536: Its initial value is approximated with $*$, if it is $0$, and with
3537: $\emptyset$, if it is $\nil$. The $\mathsf{get\_field}^f$ operation
3538: returns $\bot$ if it is \emph{always} applied to states where the receiver
3539: $\rs$ is $\nil$. This is because $\bot$ is the best approximation
3540: of the empty set of final states.
3541: %
3542: If, instead, the receiver is not necessarily
3543: $\nil$, the creation points of the field $f$ are copied from the
3544: approximation $\mu(f)$ into the approximation of $\rs$. Since this operation
3545: changes the value of $\rs$, possibly making
3546: some object unreachable, it needs to call $\xi$.
3547: %
3548: For the $\mathsf{put\_field}^f$ operation, we first check if the
3549: receiver is always $\nil$, in which case the abstract operation returns $\bot$.
3550: Then we consider the case in which the evaluation of what is going to be
3551: put inside the field makes the receiver unreachable. This (pathological) case
3552: happens in a situation such as $\mathtt{a.g.f=m(a)}$ where the method call
3553: $\mathtt{m(a)}$ sets to $\nil$ the field $\mathtt{g}$ of the object
3554: bound to $\mathtt{a}$.
3555: Since we assume that the left-hand side is evaluated before
3556: the right-hand side, the receiver is not necessarily $\nil$,
3557: but the field updates might not be observable if $\mathtt{a.g.f}$ is only
3558: reachable from $\mathtt{a}$. In the third and final
3559: case for $\mathsf{put\_field}$ we consider the standard situation
3560: when we write into a reachable field of a non-$\nil$ receiver.
3561: The creation points of
3562: the right-hand side are added to those already approximating the objects stored
3563: in $f$.
3564: %
3565: The $\mathsf{call}$ operation restricts the scope to the parameters
3566: passed to a method and hence $\xi$ is used.
3567: The $\mathsf{return}$ operation copies into $\rs$ the return value of the
3568: method which is held in $\Out$. The local variables of the caller
3569: are put back into scope, but the approximation of their fields is provided
3570: through a worst-case assumption $\mu^\top$ since they may be modified by
3571: the call. This loss of precision
3572: can be overcome by means of shadow copies of the variables, just as for $\e$
3573: (see Example~\ref{ex:abstract_operations_er2}).
3574: %
3575: The $\mathsf{lookup}^m$ operation first computes the subset $e$ of the
3576: approximation of the receiver of the call only containing the creation
3577: points whose class leads to a call to the method $m$. If $e =
3578: \emptyset$, a call to $m$ is impossible and the result of the
3579: operation is $\bot$. Otherwise, $e$ becomes the approximation of the
3580: receiver $\rs$, so that some creation points can disappear
3581: and we need to call $\xi$.
3582: %
3583: \begin{example}\label{ex:abstract_operations_er}
3584: \ifcorr{%
3585: As in Example~\ref{ex:abstract_operations_e} for $\e$,
3586: let us mimic, in $\er$, the concrete computation
3587: of Example~\ref{ex:concrete_operations}.
3588: We start from the abstraction (Definition~\ref{def:er_abstraction})
3589: of $\sigma_1$, given in Example~\ref{ex:er_domain}.
3590: Variables and fields not shown are implicitly bound to $\emptyset$ if they have
3591: class type and to $*$ if they have type $\integer$.
3592: %
3593: \begin{align*}
3594: s_1&=\alpha_\tau^\er(\sigma_1)=\left[\begin{array}{l}
3595: \mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\emptyset\\
3596: \mathtt{this}\mapsto\{\overline{\pi}\}
3597: \end{array}\right]\sep
3598: \left[\begin{array}{l}
3599: \mathtt{next}\mapsto\{\pi_2\}\\
3600: \mathtt{rotation}\mapsto\emptyset
3601: \end{array}\right]\\
3602: s_2&=\mathsf{get\_var}_\tau^\mathtt{f}(s_1)=\left[\begin{array}{l}
3603: \mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\emptyset\\
3604: \rs\mapsto\{\pi_2\},\mathtt{this}\mapsto\{\overline{\pi}\}
3605: \end{array}\right]\sep
3606: \left[\begin{array}{l}
3607: \mathtt{next}\mapsto\{\pi_2\}\\
3608: \mathtt{rotation}\mapsto\emptyset
3609: \end{array}\right].
3610: \end{align*}
3611: %
3612: There are three abstract $\mathsf{lookup}$ operations corresponding to the
3613: concrete ones and hence we construct
3614: for $i=3,\ldots,6$, elements $s_i'$, $s_i''$, $s_i'''$ of $\er$
3615: corresponding to the concrete states $\sigma_i'$, $\sigma_i''$, $\sigma_i'''$,
3616: respectively.
3617: %
3618: \begin{align*}
3619: s_3'&=\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
3620: ^{\mathtt{def},\mathtt{Figure.def}}(s_2)=\bot\\
3621: &\text{since $e'=\{\pi\in\{\pi_2\}\mid M(\pi)(\mathtt{def})=
3622: \mathtt{Figure.def}\}=\emptyset$},\\
3623: s_3''&=\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
3624: ^{\mathtt{def},\mathtt{Square.def}}(s_2)=\xi_\tau(s_2)=s_2\\
3625: &\text{since $e''=\{\pi\in\{\pi_2\}\mid M(\pi)(\mathtt{def})=
3626: \mathtt{Square.def}\}=\{\pi_2\}$},\\
3627: s_3'''&=\mathsf{lookup}_{\tau[\rs\mapsto\mathtt{Figure}]}
3628: ^{\mathtt{def},\mathtt{Circle.def}}(s_2)=\bot\\
3629: &\text{since $e'''=\{\pi\in\{\pi_2\}\mid
3630: M(\pi)(\mathtt{def})=\mathtt{Circle.def}\}=\emptyset$.}
3631: \end{align*}
3632: %
3633: The $\mathsf{lookup}$ operations for
3634: $\mathtt{Figure}$ and $\mathtt{Circle}$ return $\bot$ so that,
3635: as the abstract operations over $\er$ are strict on $\bot$
3636: (Proposition~\ref{prop:operations_er}), $s_4' = s_5' = s_6' =
3637: s_4'''=s_5'''=s_6'''= \bot$. This is because the analysis is able
3638: to guess the target of the virtual call $\mathtt{f.def()}$, since the only
3639: creation point for the receiver $\mathtt{f}$ is $\pi_2$, which creates
3640: $\mathtt{Square}$s. Hence we only have to consider the case when a
3641: $\mathtt{Square}$ is selected:
3642: %
3643: \begin{align*}
3644: s_4''&=\mathsf{call}^\mathtt{Square.def}_{\tau[\rs\mapsto\mathtt{Square}]}
3645: (s_3'')\\
3646: &=\xi_{[\rs\mapsto\mathtt{Square}]}\left(
3647: [\mathtt{this}\mapsto\{\pi_2\}]
3648: \sep\left[\begin{array}{l}
3649: \mathtt{next}\mapsto\{\pi_2\}\\
3650: \mathtt{rotation}\mapsto\emptyset
3651: \end{array}\right]\right)\\
3652: &=[\mathtt{this}\mapsto\{\pi_2\}]
3653: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation}\mapsto\emptyset].
3654: \end{align*}
3655: %
3656: Since $P(\mathtt{Square.def})|_{\Out}
3657: =[\Out\mapsto\integer]$ and $\er_{[\Out\mapsto\integer]}=\{\bot,
3658: [\Out\mapsto *]\sep[\mathtt{next}\mapsto\emptyset
3659: ,\ \mathtt{rotation}\mapsto\emptyset]\}$,
3660: we can just observe that the method
3661: $\mathtt{Square.def}$ does not diverge to conclude that
3662: \[
3663: s_5''=[\Out\mapsto *]\sep[\mathtt{next}\mapsto\emptyset
3664: ,\ \mathtt{rotation}\mapsto\emptyset].
3665: \]
3666: Hence, by letting $\mu^\top$ denote the top element of $\Memory^\er$
3667: so that
3668: \[
3669: \mu^\top =
3670: \left[
3671: \mathtt{next}\mapsto\{\pi_2,\pi_3\},
3672: \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}
3673: \right],
3674: \]
3675: we have
3676: \begin{align*}
3677: s_6''
3678: &=\mathsf{return}^\mathtt{Square.def}
3679: _{\tau[\rs\mapsto\mathtt{Square}]}(s_3'')(s_5'')\\
3680: &=\mathsf{return}_{\tau[\rs\mapsto\mathtt{Square}]}^\mathtt{Square.def}
3681: (s_2)(s_5'')\\
3682: &=\xi_{\left[
3683: \begin{smallmatrix}
3684: \mathtt{f}\mapsto\mathtt{Figure},\ \mathtt{n}\mapsto\mathtt{Figure},\\
3685: \Out\mapsto\integer,\ \mathtt{this}\mapsto\mathtt{Scan}
3686: \end{smallmatrix}
3687: \right]}
3688: \left(\left[
3689: \mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\emptyset,
3690: \mathtt{this}\mapsto\{\overline{\pi}\}
3691: \right]\sep \mu^{\top} \right)
3692: \cup\\
3693: &\qquad\cup([\rs\mapsto *]\sep[\mathtt{next}\mapsto\emptyset,
3694: \ \mathtt{rotation}\mapsto\emptyset])\\
3695: &=\left[
3696: \mathtt{f}\mapsto\{\pi_2\},\mathtt{n}\mapsto\emptyset,
3697: \mathtt{this}\mapsto\{\overline{\pi}\}
3698: \right]\sep \mu^{\top}.
3699: \end{align*}
3700: %
3701: Since the abstract semantics is non-deterministic, we merge the results
3702: of every thread of execution through the $\cup$ operation. Hence the abstract
3703: state after the execution of the call $\mathtt{f.def()}$ in Figure
3704: \ref{fig:program} is
3705: \[
3706: s_6=s_6'\cup s_6''\cup s_6'''=\bot\cup s_6''\cup\bot=s_6''.
3707: \]
3708: \qed
3709: }
3710: \end{example}
3711:
3712: The abstract state $s_6''$ shows that the imprecision problem of $\e$,
3713: related to the $\mathsf{return}$ operation, is still present in $\er$.
3714: By comparing $s_2$ with $s_6''$, it can be seen that
3715: the $\mathsf{return}$ operation makes a very pessimistic
3716: assumption about the possible creation points for the $\mathtt{next}$
3717: and $\mathtt{rotation}$ fields.
3718: In particular, from $s_6''$ it seems that creation points
3719: $\pi_3$ and $\pi_4$ are reachable (they belong to $\mu^\top$),
3720: which is not the case in the concrete state
3721: (compare this with $\sigma_6''$ in Example~\ref{ex:concrete_operations}).
3722: %We will discuss in Subsection~\ref{subsec:further_refinement}
3723: %how to cope with this second problem
3724: As for the domain $\e$,
3725: this problem can be solved by including, in the state of the callee,
3726: \emph{shadow copies} of the parameters of the caller.
3727: This is implemented through a preprocessing of the bodies of the
3728: methods which prepend statements of the form
3729: $v'\mathtt{:=}v$ for each parameter $v$, where $v'$ is the shadow
3730: copy of $v$. Since shadow copies are fresh new variables, not
3731: already occurring in the method's body, their value is never changed.
3732: %
3733: In this way, at the end of the method we know which creation points are
3734: reachable from the fields of the objects bound to such parameters.
3735: %Note that, to obtain this improvement, we only need to modify
3736: %the operations $\mathsf{call}$ and $\mathsf{return}$.
3737: %We do not provide any formal proof of the
3738: %correctness of this technique, while we give an example of its application.
3739: %
3740: \begin{example}\label{ex:abstract_operations_er2}
3741: \ifcorr{%
3742: Let us reexecute the abstract computation of
3743: Example~\ref{ex:abstract_operations_er}, but including shadow copies of the
3744: parameters in the abstract states. We denote by $p'$ the shadow copy of the
3745: parameter $p$. We assume that the method $\mathtt{scan}$ was called
3746: with an actual parameter $\nil$ for the formal parameter $\mathtt{n}$.
3747: The abstract state $s_1$ contains now two shadow copies
3748: %\footnote{A shadow
3749: %copy of the $\mathtt{this}$
3750: %parameter is not strictly necessary, since that variable cannot be
3751: %assigned to, and hence the actual and formal parameters $\mathtt{this}$
3752: %always coincide.}:
3753: \[
3754: s_1=\left[\begin{array}{l}
3755: \mathtt{f}\mapsto\{\pi_2\},
3756: \mathtt{n}\mapsto\emptyset,\mathtt{n}'\mapsto\emptyset\\
3757: \mathtt{this}\mapsto\{\overline{\pi}\},
3758: \mathtt{this}'\mapsto\{\overline{\pi}\}
3759: \end{array}\right]\sep
3760: \left[\begin{array}{l}
3761: \mathtt{next}\mapsto\{\pi_2\}\\
3762: \mathtt{rotation}\mapsto\emptyset
3763: \end{array}\right].
3764: \]
3765: The same change applies to the abstract states $s_2$ and
3766: $s_3''$ in Example~\ref{ex:abstract_operations_er}. The abstract state
3767: $s_4''$ uses a new shadow copy for the actual parameter
3768: of the method $\mathtt{Square.def}$ \ie
3769: \[
3770: s_4''=[\mathtt{this}\mapsto\{\pi_2\},\mathtt{this}'\mapsto
3771: \{\pi_2\}]\sep[
3772: \mathtt{next}\mapsto\{\pi_2\},\ \mathtt{rotation}\mapsto\emptyset].
3773: \]
3774: The static analysis of the method $\mathtt{Square.def}$ easily concludes that
3775: no object has been created. Hence now we have
3776: \[
3777: s_5''=[\Out\mapsto *,\mathtt{this}'\mapsto\{\pi_2\}]\sep[
3778: \mathtt{next}\mapsto\{\pi_2\},\ \mathtt{rotation}\mapsto\{\pi_1\}].
3779: \]
3780: Note that the abstract memory is not empty now (compare with
3781: Example~\ref{ex:abstract_operations_er}). This is because the shadow variable
3782: $\mathtt{this}'$ prevents the abstract garbage collector from deleting the
3783: creation point $\pi_2$ from $\mathtt{next}$ and the creation point
3784: $\pi_1$ from $\mathtt{rotation}$.
3785: Moreover, we know what is reachable at the end of
3786: the execution of the $\mathtt{Square.def}$ method from its
3787: parameters (through their shadow copies). Therefore we do not need to apply any
3788: pessimistic assumption at $\mathsf{return}$ time, and we can define the
3789: abstract $\mathsf{return}$ operation
3790: in such a way that it just transfers
3791: the result of the method call into the $\rs$ variable:
3792: \[
3793: \mathsf{return}_\tau^\nu(\phi_1\sep\mu_1)(\phi_2\sep\mu_2)
3794: =\xi_{\tau[\rs\mapsto P(\nu)(\Out)]}
3795: (\phi_1[\rs\mapsto\phi_2(\Out)]\sep\mu_2)
3796: \]
3797: so that we have
3798: \[
3799: s_6''=\left[\begin{array}{l}
3800: \mathtt{f}\mapsto\{\pi_2\},
3801: \mathtt{n}\mapsto\emptyset,\mathtt{n}'\mapsto\emptyset\\
3802: \mathtt{this}\mapsto\{\overline{\pi}\},
3803: \mathtt{this}'\mapsto\{\overline{\pi}\}
3804: \end{array}\right]\sep
3805: \left[\begin{array}{l}
3806: \mathtt{next}\mapsto\{\pi_2\}\\
3807: \mathtt{rotation}\mapsto\{\pi_1\}
3808: \end{array}\right].
3809: \]
3810: Note that creation points $\pi_3$ and $\pi_4$ are no longer
3811: reachable (compare with Example~\ref{ex:abstract_operations_er}).
3812: \qed
3813: }
3814: \end{example}
3815: %
3816: As previously noted in Subsection~\ref{subsec:e}, shadow copies of the
3817: parameters are also useful for dealing with methods that modify their
3818: formal parameters.
3819: %
3820: %
3821: %We provide now the worst-case complexity of the analysis induced by $\er$.
3822: %%
3823: %\begin{proposition}\label{prop:complexity_er}
3824: %Let $p=\#\Pi$, $n$ be the number of commands of the program $P$ to be analysed,
3825: %$b$ the number of nodes of the call graph of $P$ and $t$ the maximal number
3826: %of fields of an object or of variables in scope. The cost in time
3827: %of the analysis induced by $\er$ is $O(bnt^42^p)$.
3828: %\end{proposition}
3829: %\myproofbis{
3830: %The result, from given inputs, of an operation
3831: %in Figure~\ref{fig:operations_er} can be computed in time
3832: %$O(t^22^p)$. For instance, consider the $\mathsf{lookup}$ operation, which
3833: %is the more complex one. The computation of $\ee$ and its test for emptiness
3834: %can be computed in $O(p)$. Then we compute the $\xi$ function. This requires
3835: %at most $p$ iterations for computing $\rho$
3836: %(Definition~\ref{def:xi}), and each iteration can be computed in
3837: %$O(pt)$. Then the cost for computing
3838: %$\mathsf{lookup}$ from a given input is $O(p^2t)$. Simpler reasonings apply
3839: %to the other operations in Figure~\ref{fig:operations_er}.
3840: %Since we have $O(t2^p)$ possible inputs,
3841: %the cost for computing the denotation of an operation
3842: %in Figure~\ref{fig:operations_er} is $O(p^2tt2^p)=O(t^22^p)$.
3843: %
3844: %The cost in time for joining two denotations $d_1$ and $d_2$
3845: %(\ie for computing the denotation of the
3846: %composition of two operations in Figure~\ref{fig:operations_er}) is
3847: %$O(t^32^p)$, since for every input $i$ of $d_1$ we search
3848: %$d_1(i)$ among the inputs of $d_2$. This search costs $O(t2^p)$
3849: %and is performed $O(t2^p)$ times for unary operations,
3850: %and $t^22^p$ for binary operations.
3851: %
3852: %The cost in time for computing the denotation of a sequence of $m$
3853: %commands is then $O(mt^22^p+mt^32^p)=O(mt^32^p)$,
3854: %since we compute the denotation of every
3855: %single command and then we join them. Note that a sequence of $m$ commands
3856: %is translated in a sequence of $O(m)$ operations from Figure
3857: %\ref{fig:operations_er} \cite{SpotoJ03}.
3858: %
3859: %Let $l$ be the number of strongly connected components of the call graph
3860: %of the program, $f$ be one of these components,
3861: %$b_f$ the number of nodes of $f$ and $n_f$ the total number of commands
3862: %in the nodes of $f$. Every iteration of the local fixpoint over $f$
3863: %costs $O(n_ft^32^p)$ as shown before. At every iteration, the
3864: %denotation of at least one node of $f$ must change, and that denotation
3865: %can change at most $pt2^p$ times (every denotation has at most $t2^p$ outputs
3866: %and each output can take at most $p$ different values). Then
3867: %the local fixpoint is reached after at most
3868: %$O(b_fpt2^p)$ iterations. The total cost for its computation is then
3869: %$O(b_ftp2^pn_ft^32^p)=O(b_fn_ft^42^p)$.
3870: %
3871: %The cost for computing the denotation (analysis) of the whole program is
3872: %%
3873: %\begin{equation}\label{eq:cost_er}
3874: % \sum_{f=1}^lO(b_fn_ft^42^p)
3875: % =O\left(t^42^p\cdot\sum_{f=1}^l(b_fn_f)\right).
3876: %\end{equation}
3877: %%
3878: %Since $\sum_{f=1}^l(b_fn_f)\le
3879: %\sum_{f=1}^l(b_fn)=n\cdot\sum_{f=1}^lb_f=bn$, \eref{eq:cost} is
3880: %$O(bnt^42^p)$.}
3881: %
3882:
3883: There was another problem with $\e$, related to the fact that $\e$ does not
3884: distinguish between different variables
3885: (see end of Section~\ref{sec:edomain}). It is not surprising that
3886: $\er$ solves that problem, as shown below.
3887: %
3888: \begin{example}\label{ex:abstract_operations_er3}
3889: \ifcorr{%
3890: Let the approximation provided by $\er$ before the statement
3891: $\mathtt{f\ =\ new\ Circle()}$ in Figure~\ref{fig:program} be
3892: \[
3893: s=[\mathtt{f}\mapsto\{\pi_2\},\mathtt{this}\mapsto\{\overline{\pi}\}]
3894: \sep[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation}\mapsto\{\pi_1,\pi_4\}]
3895: \]
3896: (Example~\ref{ex:er_precision}). We can compute the approximation \emph{after}
3897: that statement by executing two abstract operations.
3898: Since the object created at $\pi_3$ gets stored
3899: inside the variable $\mathtt{f}$, we expect the creation point $\pi_2$
3900: of the old value of $\mathtt{f}$ to disappear from the approximation
3901: of $\mathtt{f}$, which is what actually happens:
3902: %
3903: \begin{align*}
3904: &s'=\mathsf{new}_\tau^{\pi_3}(s)\\
3905: &=\left[\begin{array}{l}
3906: \mathtt{f}\mapsto\{\pi_2\},\rs\mapsto\{\pi_3\},\\
3907: \mathtt{this}\mapsto\{\overline{\pi}\}
3908: \end{array}\right]
3909: \sep\left[\begin{array}{l}
3910: \mathtt{next}\mapsto\{\pi_2\},\\
3911: \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}\end{array}\right],\\
3912: &\mathsf{put\_var}^\mathtt{f}_{\tau[\rs\mapsto\mathtt{Circle}]}(s')\\
3913: &=\xi_\tau\left([\mathtt{f}\mapsto\{\pi_3\},
3914: \mathtt{this}\mapsto\{\overline{\pi}\}]
3915: \sep\left[\begin{array}{l}
3916: \mathtt{next}\mapsto\{\pi_2\}\\
3917: \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}
3918: \end{array}\right]\right)\\
3919: &=[\mathtt{f}\mapsto\{\pi_3\},
3920: \mathtt{this}\mapsto\{\overline{\pi}\}]
3921: \sep\left[\begin{array}{l}
3922: \mathtt{next}\mapsto\{\pi_2\}\\
3923: \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}
3924: \end{array}\right].
3925: \end{align*}
3926: %
3927: Note that the creation points for $\mathtt{rotation}$ do not disappear,
3928: since from the $\mathtt{Circle}$ bound to $\mathtt{f}$ it might be
3929: possible to reach a $\mathtt{Square}$ through its $\mathtt{next}$ field,
3930: and a $\mathtt{Square}$ has a $\mathtt{rotation}$ field.
3931: \qed
3932: }
3933: \end{example}
3934: %
3935: %In Example~\ref{ex:abstract_operations_er3}, the static analysis is
3936: %not able to see that $\mathtt{f}$ is approximated with a \emph{new}
3937: %object, whose fields are initially set to $0$ or $\nil$. Since the
3938: %$\mathsf{new}$ and $\mathsf{put\_var}$ operations are optimal
3939: %(Proposition~\ref{prop:operations_er}), we can only improve the
3940: %precision of the analysis by refining the domain.
3941: %Namely, we would need a different approximation of the fields
3942: %for each variable, so that the fields of the object bound
3943: %to $\rs$ are approximated
3944: %with $*$ or $\emptyset$ after a $\mathtt{new}$ statement.
3945: %
3946: %The domain $\er$ also loses precision since it contains
3947: %no information on the number of different fields reachablwhen we write
3948: %$\nil$ inside a field.
3949: %as a consequence
3950: %of the non-optimality of $\mathsf{put\_field}$
3951: %(Proposition~\ref{prop:operations_er}).
3952: %This is illustrated by the following example.
3953: %
3954: %\begin{example}\label{ex:abstract_operations_er4}
3955: %Let $\tau = \tau_{w_1}$ be as given in Figure~\ref{fig:state}.
3956: %Consider the execution from $s=[\mathtt{f}\mapsto\{\pi_3\},
3957: %\mathtt{this}\mapsto\{\overline{\pi}\}]\sep
3958: %[\mathtt{next}\mapsto\{\pi_2\},\mathtt{rotation}\mapsto\{\pi_1,\pi_4\}]$
3959: %of the statement $\mathtt{f.next\ =\ n}$ in Example~\ref{ex:er_precision}.
3960: %It combines three operations in Figure~\ref{fig:operations_er}:
3961: %
3962: %\begin{align*}
3963: % s'&=\mathsf{get\_var}_\tau^{\mathtt{f}}(s)\\
3964: % &=[\mathtt{f}\mapsto\{\pi_3\},\rs\mapsto\{\pi_3\},
3965: % \mathtt{this}\mapsto\{\overline{\pi}\}]\sep
3966: % \left[\begin{array}{l}
3967: % \mathtt{next}\mapsto\{\pi_2\}\\
3968: % \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}
3969: % \end{array}\right]\\
3970: % s''&=\mathsf{get\_var}_\tau^{\mathtt{n}}(s)\\
3971: % &=[\mathtt{f}\mapsto\{\pi_3\},\rs\mapsto\emptyset,
3972: % \mathtt{this}\mapsto\{\overline{\pi}\}]\sep
3973: % \left[\begin{array}{l}
3974: % \mathtt{next}\mapsto\{\pi_2\}\\
3975: % \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}
3976: % \end{array}\right]\\
3977: % s'''&=\mathsf{put\_field}_{\tau[\rs\mapsto\mathtt{Figure}],
3978: % \tau[\rs\mapsto\mathtt{Figure}]}^\mathtt{next}(s')(s'')\\
3979: % &=\xi_\tau([\mathtt{f}\mapsto\{\pi_3\},
3980: % \mathtt{this}\mapsto\{\overline{\pi}\}]\sep
3981: % [\mathtt{next}\mapsto\{\pi_2\},
3982: % \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}])\\
3983: % &=[\mathtt{f}\mapsto\{\pi_3\},
3984: % \mathtt{this}\mapsto\{\overline{\pi}\}]\sep
3985: % [\mathtt{next}\mapsto\{\pi_2\},
3986: % \mathtt{rotation}\mapsto\{\pi_1,\pi_4\}].
3987: %\end{align*}
3988: %
3989: %Note that the computation of $s'''$ uses the third case in the definition of
3990: %$\mathsf{put\_field}_{\tau,\tau'}^f$ in Figure~\ref{fig:operations_er}.
3991: %This result is imprecise since we are putting $\nil$ inside the field
3992: %$\mathtt{next}$ of
3993: %the object bound to $\mathtt{f}$. Since no other field called $\mathtt{next}$
3994: %is reachable, a better approximation for $\mathtt{next}$ is $\emptyset$,
3995: %which also entails that the creation points for $\mathtt{rotation}$ can be
3996: %garbage collected.
3997: %\qed\end{example}
3998: %
3999: \subsection{$\er$ is a Refinement of $\e$}\label{subsec:refinement}
4000: %
4001: We have called $\er$ a \emph{refinement} of $\e$. In order to give
4002: this word a formal justification, we show here that
4003: $\er$ actually includes the elements of $\e$.
4004: Namely, we show how every element $\ee\in\e$ can be \emph{embedded} into
4005: an element $\theta(\ee)$ of $\er$, such that $\ee$ and $\theta(\ee)$
4006: have the same concretisation \ie they represent the same property
4007: of concrete states.
4008: %
4009: The idea, formalised in Definition \ref{def:implementation},
4010: is that every variable or field must be bound in $\er$ to all those
4011: creation points in $\ee$ compatible with its type.
4012: %
4013: \begin{definition}[Embedding of $\e$ into $\er$]
4014: \label{def:implementation}
4015: Let $s\subseteq\Pi$. We define
4016: $\vartheta_\tau(s)\in\Frame^\er_\tau$ such that, for every $v\in\domain(\tau)$,
4017: \[
4018: \vartheta_\tau(s)(v)=\begin{cases}
4019: * & \text{if $\tau(v)=\integer$}\\
4020: \{\pi\in s\mid k(\pi)\le\tau(v)\} & \text{if $\tau(v)\in\mathcal{K}$.}
4021: \end{cases}
4022: \]
4023: The \emph{embedding} $\theta_\tau(\ee)\in\er_\tau$ of
4024: $\ee\in\e_\tau$ is $\theta_\tau(\ee)=\xi_\tau(\vartheta_\tau(\ee)\sep
4025: \vartheta_{\widetilde{\tau}}(\ee))$.
4026: \end{definition}
4027: %
4028: \begin{example}\label{ex:implementation}
4029: \ifcorr{%
4030: Let $\tau_{w_1}$ be as given in Figure~\ref{fig:state} and
4031: $\ee=\{\overline{\pi},\pi_1,\pi_2,\pi_3\}\in\e_{\tau_{w_1}}$
4032: (Example~\ref{ex:ew}). Then
4033: \[
4034: \theta_{\tau_{w_1}}(\ee)=\left[\begin{array}{l}
4035: \mathtt{f}\mapsto\{\pi_2,\pi_3\},\mathtt{n}\mapsto\{\pi_2,\pi_3\}\\
4036: \Out\mapsto *,\mathtt{this}\mapsto\{\overline{\pi}\}
4037: \end{array}\right]\sep
4038: \left[\begin{array}{l}
4039: \mathtt{next}\mapsto\{\pi_2,\pi_3\}\\
4040: \mathtt{rotation}\mapsto\{\pi_1\}
4041: \end{array}\right]
4042: \]
4043: where the missing fields are implicitly bound
4044: to $*$ since they have $\mathit{int}$ type.
4045: \qed
4046: }
4047: \end{example}
4048:
4049: Proposition~\ref{prop:inclusion} states that the embedding
4050: of Definition~\ref{def:implementation} is correct.
4051: The proof proceeds by showing
4052: that $\theta_\tau(e)$ is an element of $\er_\tau$ and
4053: approximates exactly the same concrete states as $e$, that is,
4054: for every element of $\e$ there is an element
4055: of $\er$ which represents exactly the same set of concrete states.
4056: %
4057: \begin{proposition}\label{prop:inclusion}
4058: Let $\gamma_\tau^\e$ and $\gamma_\tau^\er$ be the
4059: concretisation maps induced by the abstraction maps of
4060: Definitions~\ref{def:alpha} and~\ref{def:er_abstraction}, respectively.
4061: Then $\gamma_\tau^\e(\e_\tau)\subseteq\gamma_\tau^\er(\er_\tau)$.
4062: \end{proposition}
4063: %
4064: The following example shows that the inclusion relation
4065: in Proposition~\ref{prop:inclusion} must be strict.
4066: %
4067: \begin{example}\label{ex:strict_inclusion}
4068: \ifcorr{%
4069: Let $\tau_{w_1}$ be as given in Figure~\ref{fig:state}.
4070: By Example~\ref{ex:ew} we know that $\emptyset\in\e_{\tau_{w_1}}$ and that
4071: every $\ee\in\e_{\tau_{w_1}}\!\setminus\{\emptyset\}$
4072: must contain $\overline{\pi}$. Moreover, we know that
4073: $\{\pi_1\}\not\in\e_{\tau_{w_1}}$ and
4074: $\{\pi_4\}\not\in\e_{\tau_{w_1}}$. Hence
4075: \[
4076: \#\e_{\tau_{w_1}}\le 1+(\#\wp(\{\pi_1,\pi_2,\pi_3,\pi_4\})-2)<2^4.
4077: \]
4078: For what concerns $\er_{\tau_{w_1}}$, note that for every
4079: $\ee_1,\ee_2\in\wp(\{\pi_2,\pi_3\})$ the element
4080: \[
4081: [\mathtt{f}\mapsto\ee_1,\mathtt{n}\mapsto\ee_2,\Out\mapsto *,
4082: \mathtt{this}\mapsto\{\overline{\pi}\}]\sep[\mathtt{next}
4083: \mapsto\emptyset,\mathtt{rotation}\mapsto\emptyset,\ldots]
4084: \]
4085: is a fixpoint of $\xi_\tau$ and hence an element of $\er_{\tau_{w_1}}$
4086: (Definition~\ref{def:er_domain}). Hence
4087: \[
4088: \#\er_{\tau_{w_1}}\ge(\#\wp(\{\pi_2,\pi_3\}))^2=2^4>\#\e_{\tau_{w_1}}.
4089: \]
4090: \qed
4091: }
4092: \end{example}
4093: %
4094: %\subsection{A Further Refinement}\label{subsec:further_refinement}
4095: %
4096: %At the end of Subsection~\ref{subsec:static_analysis_er} we have said that
4097: %the abstract domain $\er$ does not solve the second imprecision problem
4098: %discussed after Example~\ref{ex:abstract_operations_e}. This is because
4099: %at the end of a method the information about the creation points of the
4100: %fields of the objects reachable from the only variable $\Out$ is too poor
4101: %to recover some useful information about the creation points of the
4102: %fields of the objects reachable from the variables in the scope of the caller.
4103: %
4104: %This problem can be solved by further refining $\er$. Namely, we add
4105: %to $\er$ a further component from $\Memory^\er$ (Definition
4106: %\ref{def:er_abstraction}). This extra component overapproximates the
4107: %set of creation points of the fields of the objects reachable from the
4108: %parameters $p=P(\nu)|_{-\Out}$
4109: %of the method $\nu$ that we are analysing. This information is
4110: %used to improve the precision of the $\mathsf{return}$ operation.
4111: %Note that this refined domain $\er^+$ is an abstract
4112: %interpretation of concrete states $\Sigma_\tau$ if we assume that
4113: %the domain of $\tau$ includes $p$. This can be achieved by a simple
4114: %modification of the operations $\mathsf{call}$ and $\mathsf{return}$ in
4115: %Figure~\ref{fig:concrete_states}. However, we do not provide any formal
4116: %proof about the construction of $\er^+$ here.
4117: %
4118: %\begin{definition}\label{def:er_plus}
4119: %Let $p\subseteq\domain(\tau)$ be a given set of variables.
4120: %We define
4121: %\[
4122: % \er^+_\tau=\{\bot\}\cup\{s\sep m\in\er_{\tau|_{-p}}\times\Memory^\er\mid
4123: % s\not=\bot\}
4124: %\]
4125: %and the map $\alpha_\tau^{\er^+}:\wp(\Sigma_\tau)\mapsto\er^+_\tau$ such that
4126: %\[
4127: % \alpha_\tau^{\er^+}(S)=\alpha^\er_{\tau|_{-p}}(\{\phi|_{-p}\sep\mu\mid
4128: % \phi\sep\mu\in S\})\sep\alpha^\er_{\tau|_p}(\{\phi|_p\sep\mu\mid
4129: % \phi\sep\mu\in S\}).\mu.
4130: %\]
4131: %\end{definition}
4132: %
4133: %While the first component of $\er^+_\tau$, except for the operation
4134: %$\mathsf{return}$, behaves exactly as shown in
4135: %Figure~\ref{fig:operations_er}, the second component is only affected by
4136: %the $\mathsf{put\_field}$ operation, and interacts with the first component
4137: %during the $\mathsf{call}$ and $\mathsf{return}$ operation. Namely, these
4138: %operations are defined as
4139: %\begin{align*}
4140: % \mathsf{call}_\tau^{\nu,v_1,\ldots,v_n}((\phi\sep\mu)\sep\mu')&=
4141: % \left[\xi_p([\iota_1\mapsto\phi(v_1),\ldots,\iota_n\mapsto\phi(v_n),
4142: % \mathtt{this}\mapsto\phi(\rs)]\sep\mu)\right]\sep\\
4143: % &\qquad\sep\left[\xi_{\tau|_{\{v_1,\ldots,v_n\}}}(\phi\sep\mu)\right].\mu\\
4144: % \mathsf{return}_\tau^\nu((\phi_1\sep\mu_1)\sep\mu_1')((\phi_2\sep\mu_2)
4145: % \sep\mu_2')&=(\phi_1|_{-\rs}\sep)
4146: %\end{align*}
4147: %
4148: \section{Implementation}\label{sec:implementation}
4149: \ifcorr{}
4150: %
4151: \ifthenelse{\boolean{PROOFSONLY}}{}
4152: {
4153: In this section, we present our practical evaluation of the
4154: abstract domain $\er$.
4155: In Subsection~\ref{subsec:julia}, we describe the implementation of
4156: $\er$ used to do the experiments and, in
4157: Subsection~\ref{subsec:tests}, we present the experimental results.
4158:
4159: %Note that, prior to implementing the domain $\er$ as described below,
4160: %we performed an experimental implementation of this domain
4161: %inside \textsc{Loop}~\cite{LOOP01,Spoto01}, an analyser for
4162: %programs written in a toy object-oriented language.
4163: %The goal of this implementation was to investigate the feasibility of
4164: %our approach.
4165: %
4166: %Although the performance was extremely poor,
4167: %our experience with this implementation proved
4168: %invaluable for the more challenging task of developing an analyser suitable
4169: %for the escape analysis of real Java applications using the domain $\er$.
4170: %
4171: \subsection{Analysing Java Bytecode}\label{subsec:julia}
4172: %
4173: We implemented the abstract domain $\er$ inside \textsc{Julia}~\cite{julia}.
4174: This is a generic static analyser written in Java
4175: that is designed for analysing full Java bytecode.
4176: %
4177: Generic means that \textsc{Julia} does not
4178: embed any abstract domain but, instead, can be instantiated
4179: for a specific static analysis once
4180: an appropriate abstract domain and the attached abstract
4181: operations are provided.
4182: For instance, \textsc{Julia} can perform \emph{rapid type
4183: analysis} (a kind of \emph{class analysis}~\cite{BaconS96})
4184: or instead escape analysis through $\er$
4185: by simply swapping these abstract domains.
4186:
4187: In order to target the escape analysis of real Java bytecode programs,
4188: the implementation had to address a number of problems due to
4189: features of the Java bytecode itself.
4190: We describe the main problems and how we addressed them.
4191: These problems were:
4192: %
4193: \begin{enumerate}
4194: \item
4195: \label{prob:local-stack}
4196: the Java Virtual Machine frame contains
4197: both local variables and an operand stack and the number of
4198: elements in the operand stack can change within the same method,
4199: although its size at a given program point is fixed and statically known;
4200: %\item
4201: %\label{prob:library-fields}
4202: % because of the number of classes that are part of either the application
4203: % or the libraries, the number of fields can be very large;
4204: \item
4205: \label{prob:library-classes}
4206: a very large number of library classes are likely to be called and,
4207: hence, would need to be analysed;
4208: \item
4209: \label{prob:gotos}
4210: Java bytecode is unstructured \ie lacking any explicit
4211: scope structure and code is weaved through an extensive use
4212: of explicit \texttt{goto} jumps;
4213: \item
4214: \label{prob:exceptions}
4215: since the Java bytecode makes extensive use of exceptions, the
4216: control flow for exceptions must also be considered.
4217: \item
4218: \label{prob:static}
4219: Java bytecode has static fields, which are like global variables
4220: of traditional imperative languages, and are always in scope,
4221: so that the objects bound to static fields cannot be garbage-collected.
4222: \end{enumerate}
4223:
4224: We solved Problem (\ref{prob:local-stack}) by rewording our notion of frame
4225: (Definition~\ref{def:frames1}) into a set of local variables and a stack of
4226: variables. The number of stack variables (elements) in a given program point is
4227: statically determined since \texttt{.class} files must be
4228: verifiable~\cite{LindholmY99}.
4229: Since Java bytecode holds intermediate results in the operand stack,
4230: the latter plays the role of our $\rs$ variable.
4231:
4232: %We solved Problem (\ref{prob:library-fields})
4233: %by letting the user decide to merge all fields into a single variable
4234: %or rather keep a specific variable for each field. In the first case,
4235: %the analysis will be faster, but also less precise. Next Section will
4236: %show the difference in time and precision.
4237: %If the first choise is used,
4238: %we refine the result of reading from a field through a
4239: %\texttt{getfield} bytecode by using the declared type $t$
4240: %of the field. Namely, only creation points of objects compatible with $t$
4241: %can be read by that bytecode.
4242: %
4243:
4244: We dealt with Problem (\ref{prob:library-classes})
4245: by analysing some library classes only, and making
4246: \emph{worst-case assumptions}~\cite{CousotC02}
4247: about the behaviour of calls to methods
4248: of other classes. This means that we assume that such calls can potentially
4249: do everything, such as storing the parameters into (instance or class)
4250: fields or returning
4251: objects created in every creation point $\pi$ (with the restriction, however,
4252: that $\pi$ creates objects
4253: of class compatible with the return type of the method). It is easy to see
4254: how an extensive use of this policy quickly leads to imprecision.
4255: The situation
4256: is made worse in Java (bytecode) because of constructor chaining, stating that
4257: every call to a constructor eventually leads to a constructor in
4258: the \emph{library} class \texttt{java.lang.Object}~\cite{ArnoldGH00}.
4259: To cope with these problems, we allowed the analyser to access at least
4260: the code of \texttt{java.lang.Object}.
4261: We also allowed the analyser access to yet more library classes, leading
4262: to more precise but also more costly analyses.
4263: For many native methods, whose Java bytecode is not available, we have provided
4264: hand-made bytecode stubs which agree with the declared abstract behaviour
4265: of the methods.
4266: %
4267:
4268: Problem (\ref{prob:gotos})
4269: was solved by building a graph of blocks of codes, each
4270: bound to all its possible successors in the control-flow.
4271: We use
4272: class hierarchy analysis to deal with virtual calls whose target is
4273: not explicitly embedded in the code~\cite{DeanGC95}.
4274: Java bytecode subroutines (\ie the \texttt{jsr}/\texttt{ret} mechanism)
4275: are handled by linking each block ending with a \texttt{jsr} to the block
4276: starting with its target. The block ending with \texttt{ret} is then
4277: conservatively linked with all blocks starting
4278: with an instruction immediately following a \texttt{jsr} bytecode
4279: \emph{in the same method} of \texttt{ret}.
4280: The restriction to the
4281: same method is correct because of a constraint imposed on
4282: valid Java bytecode by the verification algorithm~\cite{LindholmY99}.
4283: %
4284: The resulting graph is the same as that of \emph{dominators}
4285: that are defined in~\cite{ASU86} for much simpler languages.
4286: The graph is then used for a fixpoint computation
4287: by following the structure of its strongly connected components.
4288:
4289: We solved Problem (\ref{prob:exceptions})
4290: by using the technique pioneered in~\cite{JacobsP03}.
4291: It consists in denoting a piece of code $c$ through a map from the input state
4292: to the \emph{normal} output state
4293: \emph{and} an \emph{exceptional} output state, representing the
4294: state of the Java virtual machine if an exception has been thrown inside $c$.
4295: Composition of commands uses the normal output state~\cite{SpotoJ03},
4296: but composition with exception handlers uses the exceptional final state.
4297:
4298: We dealt with Problem (\ref{prob:static}) by modifying the abstract garbage
4299: collector of Definition~\ref{def:xi} so that it does not
4300: garbage collect the creation points reachable from static fields.
4301: Technically, this amounts to adding to the map $\rho_\tau$ of
4302: Definition~\ref{def:xi} the creation points bound to the approximation
4303: of the static fields of the classes of the program.
4304:
4305: The abstract domain $\er$ is implemented inside
4306: \textsc{Julia} as a Java class extending
4307: an abstract (in the sense of Java~\cite{ArnoldGH00})
4308: class standing for a generic abstract domain.
4309: This class contains methods that compute the denotation of
4310: every single Java bytecode
4311: (\ie denotations similar to those given in Figure~\ref{fig:operations_er}
4312: for our simplified bytecode).
4313: %, a method for computing the join of two denotations
4314: %(\ie the $\cup$ operation in Figure~\ref{fig:operations_er}),
4315: %a method for computing the meet (functional composition) of two
4316: %denotations and a method for testing for equivalence of denotations
4317: %(needed to terminate the fixpoint computations).
4318:
4319: The choice of representation for a denotation affects the speed of the
4320: analysis. The representation we chose was a set-constraint~\cite{DovierPPR00}
4321: between its input and output variables.
4322: For instance, the denotation for the $\mathsf{new}^\pi$ operation in
4323: Figure~\ref{fig:operations_er} is implemented as a constraint
4324: $\{\pi\}\subseteq S$ over the unknown $S$. It states that the creation
4325: point $\pi$ must belong to the set $S$ of the creation points for $\rs$ in the
4326: output of the operations (\ie for the top of the operand stack when considering
4327: the real Java bytecode).
4328: We use $\subseteq$ instead of $=$ since there might be many possible
4329: ways of reaching the program point that follows $\mathsf{new}^\pi$.
4330: We use default reasoning to state that the other variables are unchanged.
4331: This is a generalisation of the technique we introduced in~\cite{HillS03}.
4332: As another example, the denotation for the $\mathsf{get\_var}^v$
4333: operation in Figure~\ref{fig:operations_er}
4334: is implemented as a constraint $S_1\subseteq S_2$ over the unknowns
4335: $S_1$ and $S_2$. It states that the set $S_2$
4336: of creation points for $\rs$ in the output must contain
4337: the set $S_1$ of creation points for $v$ in the input.
4338: We solve the set-constraints constructed from a program by propagation of
4339: creation points. Namely, a constraint such as $\{\pi\}\subseteq S$ propagates
4340: $\pi$ into $S$. A constraint such as
4341: $S_1\subseteq S_2$ propagates the creation points inside $S_1$
4342: into $S_2$. Propagation starts with empty
4343: approximations for the unknowns and
4344: continues until there is no further growth in these approximations.
4345: We have implemented this propagation by exploiting a preliminary
4346: topological sort of the unknowns of the constraints. Namely,
4347: a constraint $S_1\subseteq S_2$ induces a pre-order (a reflexive and
4348: transitive relation) $S_1\le S_2$. A topological sort \wrt this pre-order
4349: builds a tree of strongly-connected
4350: components of unknowns. A strongly-connected component represents
4351: a set of mutually dependent unknowns. We propagate the
4352: creation points by following the topological ordering backwards, so that
4353: we can consider one strongly-connected component at a time. This technique
4354: significantly speeds up the propagation.
4355: %end
4356:
4357: There were two alternative choices we might have taken for the representation.
4358: The simplest would have been an extensional definition,
4359: in the form of an exhaustive
4360: input/output tabling; but that would have been far too slow.
4361: Alternatively, we could have used binary decision diagrams~\cite{Bryant86}
4362: to represent the denotations; this traditional approach can
4363: represent the denotations in a compact and efficient way.
4364: This technique is certainly possible,
4365: but it requires more technical work since we
4366: have to code maps over sets of creation points through Boolean functions.
4367: Moreover, since bytecodes usually apply local modifications to the
4368: state (for instance, the $\mathsf{put\_var}^v$ bytecode in
4369: Figure~\ref{fig:operations_er} leaves all variables other than $v$
4370: untouched), they would be coded into binary decision diagrams
4371: which mainly assert that the output variables are a copy of their input
4372: counterparts. In terms of Boolean functions, this means that
4373: such functions would contain a lot of \emph{if and only if} constraints,
4374: which significantly increases the size of the diagram. By using
4375: set-constraints, we solve this problem through default reasoning.
4376:
4377: The use of set-constraints is appealing since we can easily use the
4378: same unknown to represent two or more distinct approximations.
4379: %PAT0704 ``in'' -> ``at'' and ``first'' -> ``second''
4380: For instance,
4381: different unknowns might represent the approximation of a field at
4382: different program points, or rather the same unknown might represent
4383: all those approximations. The second choice leads to a less precise
4384: analysis but also to fewer unknowns and constraints than
4385: the first choice. Thus, the second choice should lead to faster analyses.
4386: %PAT0704 end
4387: In the first case we say that the approximation of the fields
4388: is \emph{flow-sensitive}, while in the second case we say that it is
4389: \emph{flow-insensitive}.
4390: The same idea can be used for the approximations of local variables or
4391: even operand stack elements. In Section~\ref{subsec:tests} we evaluate
4392: the practical consequences of merging different approximations into
4393: the same unknown.
4394:
4395: The use of set-constraints for the representation
4396: %PAT0704 ``some little'' -> ``a few''
4397: has, however, also a few negative consequences.
4398: %PAT0704 end
4399: To keep the implementation simple and fast, our set-constraints
4400: are built from equality, union and intersection only. But these
4401: operations do not allow us
4402: to represent
4403: %the application of the $\xi$ abstract garbage collector
4404: %(Figure~\ref{fig:operations_er} and Definition~\ref{def:xi}) nor
4405: tests on the input variables (such as in \textsf{put\_field}, see
4406: Figure~\ref{fig:operations_er}). Hence conservative approximations
4407: must be made. For instance, the third case of the definition of
4408: \textsf{put\_field} is \emph{always} used.
4409: This is correct since it is a conservative approximation of all three cases.
4410: Moreover, it does not introduce a significant precision loss since the first
4411: alternative of the definition of \textsf{put\_field} deals with the
4412: pathological case when a given \textsf{put\_field} is \emph{always} applied
4413: to a $\nil$ receiver; and the second alternative deals with
4414: the case when a given
4415: \textsf{put\_field} is \emph{always} applied to a receiver
4416: which is made unreachable by the evaluation of the value which must be
4417: put inside the field. Both the first two alternatives correspond to legal
4418: but quite unusual ways of using \textsf{put\_field}
4419: and are almost never applicable.
4420: For efficiency reasons, the $\xi$ garbage collector is only used
4421: at the end of a method.
4422: This is a correct approximation since $\xi$ is an
4423: lco (Proposition~\ref{prop:xi_lco})
4424: although \emph{forgetting} some of its applications can lose precision.
4425: Also for efficiency reasons, we have used
4426: memoisation to cache repeated calls to the abstract garbage collector.
4427:
4428: We have described how we map the input abstract
4429: state to the output (and exceptional) abstract state.
4430: However, the information needed for stack allocation is related to some
4431: internal points of the program.
4432: For instance, in the program in Figure~\ref{fig:program},
4433: we would like to know if the creation point $\pi_4$ inside
4434: \texttt{rotate} could be stack allocated.
4435: For this, we need to know the set of the
4436: creation points of objects that are reachable at the end of \texttt{rotate}
4437: from each return value,
4438: from the (possible) objects thrown as an exception,
4439: or from the fields of the objects bound to its parameter
4440: (\ie the set $E$ of Subsection~\ref{subsec:e}).
4441: Therefore, we need information related to some
4442: internal program points.
4443: This can be obtained by placing a \emph{watchpoint}
4444: %at the beginning of each method such as \texttt{rotate} and at
4445: %every exit point of the same method.
4446: at every exit point of a method such as \texttt{rotate}.
4447: Note that, with the analyser \textsc{Julia}, we can do this automatically
4448: and obtain the set of creation points that can be stack allocated.
4449: %
4450: \subsection{Experimental Evaluation}\label{subsec:tests}
4451: %
4452: We report our experiments with the escape analysis through $\er$ of
4453: some Java applications:
4454: \texttt{Figures} is the program in Figure~\ref{fig:program}
4455: fed with a list of \texttt{Circle}s;
4456: \texttt{LimVect} is a small Java program used in~\cite{Blanchet03};
4457: \texttt{Dhrystone} version $2.1$ is a testbench for numerical computations
4458: (most of the arrays it creates can be stack allocated);
4459: \texttt{ImageVwr} is an image visualisation applet;
4460: \texttt{Morph} is an image morphing program;
4461: \texttt{JLex} version
4462: $1.2.6$ is the Java version of the well-known \texttt{lex}
4463: lexical analysers generator;
4464: \texttt{JavaCup} version $0.10j$ and \texttt{Javacc} version $3.2$
4465: are compilers' compilers;
4466: \texttt{Julia} version $0.39$ is our \textsc{Julia} analyser itself;
4467: \texttt{Jess} version $6.1p7$
4468: is a rule engine and scripting language for developing
4469: rule-based expert systems.
4470: %\texttt{jEdit} is a text-editor.
4471: All these benchmarks are free software
4472: %and are available with the distribution of
4473: %\textsc{Julia}~\cite{julia},
4474: except \texttt{Jess} which is copyrighted.
4475: Some of these programs were
4476: analysed in~\cite{Blanchet03}; these are \texttt{LimVect}, \texttt{Dhrystone},
4477: \texttt{JLex}, an older version of \texttt{Javacc} and an older version
4478: of \texttt{Jess}.
4479: Note that the newer versions of \texttt{Javacc} and \texttt{Jess}
4480: considered here are bigger
4481: than those used in~\cite{Blanchet03}.
4482: % and well beyond
4483: %the typical size of an embedded Java bytecode application,
4484: %such as for smart cards (\texttt{Jess} features
4485: %$266$ classes, standard Java libraries not included).
4486:
4487: Our experiments have been performed on a \textsf{Pentium}
4488: $2.1$ Ghz machine with $1024$ megabytes of RAM, running
4489: Linux $2.6$ and Sun Java Development Kit version
4490: $1.5.0$ with HotSpot just-in-time compiler.
4491:
4492: For each experiment, we report how many
4493: Java classes, methods and bytecodes are analysed, as well as
4494: the time taken by the analysis (in seconds)
4495: to build and solve the set of constraints
4496: generated for our escape analysis.
4497: %
4498: We first show the \emph{static} precision of the analyses
4499: (Subsection~\ref{subsub:static}). Namely, we report the number of
4500: creation points which can be stack allocated. We study how the
4501: precision of the analyses is affected by flow sensitivity and by the ability
4502: to approximate precisely each field.
4503: Later (Subsection~\ref{subsub:dynamic}),
4504: we report the \emph{dynamic} precision of the analyses \ie
4505: the number of creation operations which are stack allocated \emph{at run-time}
4506: and their relative ratio \wrt those which are heap allocated. We also
4507: provide information on the amount of memory which is stack allocated rather
4508: than heap allocated at run-time.
4509: Finally (Subsection~\ref{subsub:cost}) we briefly discuss the cost of the
4510: analyses.
4511: %
4512: \subsubsection{Static Tests}\label{subsub:static}
4513: %
4514: \begin{figure}[t]
4515: \[\begin{array}{|r|r|r|r||r|r|r|r|r|r|}\hline
4516: \multicolumn{1}{|c}{\mbox{benchmark}} &
4517: \multicolumn{1}{|c}{\mbox{clss}} &
4518: \multicolumn{1}{|c}{\mbox{meth}} &
4519: \multicolumn{1}{|c||}{\mbox{bytec}} &
4520: \multicolumn{1}{|c}{\mbox{time}} &
4521: \multicolumn{2}{|c}{\textit{SA}
4522: %\begin{array}{c}
4523: % \mbox{stack}\\
4524: % \mbox{allocations}
4525: %\end{array}
4526: } &
4527: \multicolumn{1}{|c|}{\textit{TT}
4528: %\begin{array}{c}
4529: % \mbox{time per}\\
4530: % \mbox{1000 bytec.}
4531: %\end{array}
4532: } &
4533: \multicolumn{1}{|c|}{\textit{NC}
4534: %\begin{array}{c}
4535: % \mbox{number of}\\
4536: % \mbox{constraints}
4537: %\end{array}
4538: } &
4539: \multicolumn{1}{|c|}{\textit{LIN}%\begin{array}{c}
4540: %\mbox{linearity}
4541: %\end{array}
4542: } \\\hline
4543: \mathtt{Figures} & 6 & 17 & 146
4544: & 0.06 & 1 & (20\%) & 0.41 & 109 & 2.067\\\hline
4545: \mathtt{LimVect} & 2 & 8 & 48
4546: & 0.02 & 1 & (0\%) & 0.42 & 46 & 1.631\\\hline
4547: \mathtt{Dhrystone} & 7 & 24 & 610
4548: & 0.17 & 4 & (25\%) & 0.28 & 253 & 1.640\\\hline
4549: \mathtt{ImageVwr} & 3 & 23 & 1238
4550: & 0.35 & 0 & (0\%) & 0.28 & 412 & 1.669\\\hline
4551: \mathtt{Morph} & 1 & 14 & 1367
4552: & 0.30 & 0 & (0\%) & 0.22 & 253 & 1.355\\\hline
4553: \mathtt{JLex} & 26 & 138 & 12520
4554: & 0.76 & 2 & (0\%) & 0.06 & 2904 & 1.974\\\hline
4555: \mathtt{JavaCup} & 37 & 317 & 14390
4556: & 1.76 & 1 & (0\%) & 0.12 & 5577 & 2.206\\\hline
4557: \mathtt{Julia} & 164 & 821 & 28507
4558: & 10.45 & 6 & (0\%) & 0.37 & 17653 & 2.672\\\hline
4559: \mathtt{Jess} & 268 & 1543 & 51663
4560: & 31.04 & 2 & (0\%) & 0.60 & 45614 & 2.914\\\hline
4561: \mathtt{Javacc} & 65 & 953 & 79325
4562: & 15.32 & 0 & (0\%) & 0.19 & 17759 & 2.162\\\hline
4563: \end{array}\]
4564: \caption{Flow insensitive escape analyses with $\er$. Fields are merged. Only
4565: \texttt{java.lang.Object} is included in the analysis.
4566: $\mathit{SA}$ is the number of creation points which are stack allocated;
4567: $\mathit{TT}$ is the time per one thousand bytecodes;
4568: $\mathit{NC}$ is the number of constraints generated;
4569: $\mathit{LIN}$ is the linearity of the set of constraints.
4570: }
4571: \label{fig:analyses_er}
4572: \end{figure}
4573: %
4574: We start from the fastest but also less precise way of using our escape
4575: analysis. Namely, the analyses are completely flow insensitive
4576: and field insensitive, in the sense that
4577: the fields are approximated into one variable
4578: and, except for \texttt{java.lang.Object}, library classes are not included.
4579: As we said in Subsection~\ref{subsec:julia}, calls to methods
4580: of other library classes are approximated through a worst-case assumption.
4581: In particular, this assumption states that the parameters passed to the call
4582: escape, since they might be stored into a static field, and hence be accessible
4583: after the call has returned. Because of constructor chaining, all
4584: object creations result in a call to the constructor of
4585: \texttt{java.lang.Object}. This is why the inclusion of that class is
4586: a minimum requirement to the precision of the analysis. Otherwise, every
4587: newly created object would escape as soon as it is initialised.
4588: The results are shown in Figure~\ref{fig:analyses_er}, where for each
4589: benchmark we report the number of classes, methods and bytecodes
4590: analysed and the time of the analysis (in seconds).
4591:
4592: Figure~\ref{fig:analyses_er} also reports the number of set-constraints
4593: generated for the analysis.
4594: These constraints are organised into a graph.
4595: Each variable in the constraints is a node in the graph; nodes
4596: are connected if they are related by some constraint.
4597: The \emph{linearity} column reports
4598: the average size of a strongly-connected component.
4599: %the ratio between the number of nodes
4600: %in the graph of constraints and
4601: %the number of strongly-connected components in this graph.
4602: Linearity is equal to $1.000$ for fully non-recursive programs without cycles.
4603: Higher values of linearity represent programs which use recursion and cycles
4604: extensively. For a given number of constraints, their solution is computed
4605: more efficiently if linearity is low.
4606:
4607: Although the analyses in Figure~\ref{fig:analyses_er} are relatively fast,
4608: it can be seen that almost no creation points
4609: are found to be stack allocatable.
4610: The analyses can be made more precise if flow sensitivity is used, at least
4611: for the operand stack.
4612: Results using this level of flow sensitivity are shown in
4613: Figure~\ref{fig:analyses_er2}.
4614: They are more precise than those in Figure~\ref{fig:analyses_er},
4615: but the analyses are also more expensive.
4616: If we also analyse some library classes, the precision of the analyses
4617: improves further.
4618: Namely, we decided to add part of the \texttt{java.lang} and
4619: \texttt{java.util} standard Java packages. Such classes are chosen
4620: in such a way to include typical candidates for stack allocation and to
4621: form an upward closed set, so that constructor chaining
4622: for those classes never goes out of the set of analysed classes.
4623: The results with these additions are shown
4624: in Figure~\ref{fig:analyses_er3}.
4625: We only count the creation points inside the classes of the application,
4626: so that numbers are comparable with those in Figures~\ref{fig:analyses_er}
4627: and~\ref{fig:analyses_er2}.
4628: In comparison with Figure~\ref{fig:analyses_er2}, we manage to stack allocate
4629: many more creation points, but with a further increase in
4630: the cost of the analyses.
4631: %
4632: \begin{figure}
4633: \[\begin{array}{|r|r|r|r||r|r|r|r|r|r|}\hline
4634: \multicolumn{1}{|c}{\mbox{benchmark}} &
4635: \multicolumn{1}{|c}{\mbox{clss}} &
4636: \multicolumn{1}{|c}{\mbox{meth}} &
4637: \multicolumn{1}{|c||}{\mbox{bytec}} &
4638: \multicolumn{1}{|c}{\mbox{time}} &
4639: \multicolumn{2}{|c}{\textit{SA}
4640: %\begin{array}{c}
4641: % \mbox{stack}\\
4642: % \mbox{allocations}
4643: %\end{array}
4644: } &
4645: \multicolumn{1}{|c|}{\textit{TT}
4646: %\begin{array}{c}
4647: % \mbox{time per}\\
4648: % \mbox{1000 bytec.}
4649: %\end{array}
4650: } &
4651: \multicolumn{1}{|c|}{\textit{NC}
4652: %\begin{array}{c}
4653: % \mbox{number of}\\
4654: % \mbox{constraints}
4655: %\end{array}
4656: } &
4657: \multicolumn{1}{|c|}{\textit{LIN}
4658: %\begin{array}{c}
4659: % \mbox{linearity}
4660: %\end{array}
4661: } \\\hline
4662: \mathtt{Figures} & 6 & 17 & 146
4663: & 0.08 & 3 & (60\%) & 0.54 & 454 & 1.003\\\hline
4664: \mathtt{LimVect} & 2 & 8 & 48
4665: & 0.06 & 1 & (33\%) & 1.25 & 214 & 1.007\\\hline
4666: \mathtt{Dhrystone} & 7 & 24 & 610
4667: & 0.20 & 8 & (50\%) & 0.33 & 2784 & 1.174\\\hline
4668: \mathtt{ImageVwr} & 3 & 23 & 1238
4669: & 0.50 & 0 & (0\%) & 0.40 & 7831 & 1.377\\\hline
4670: \mathtt{Morph} & 1 & 14 & 1367
4671: & 0.35 & 0 & (0\%) & 0.26 & 6483 & 1.110\\\hline
4672: \mathtt{JLex} & 26 & 138 & 12520
4673: & 2.40 & 11 & (5\%) & 0.19 & 60379 & 1.298\\\hline
4674: \mathtt{JavaCup} & 37 & 317 & 14390
4675: & 14.98 & 15 & (3\%) & 1.04 & 124097 & 1.578\\\hline
4676: \mathtt{Julia} & 164 & 821 & 28472
4677: & 33.30 & 30 & (3\%) & 1.17 & 217874 & 1.788\\\hline
4678: \mathtt{Jess} & 268 & 1543 & 51663
4679: & 51.77 & 51 & (3\%) & 1.00 & 335010 & 1.645\\\hline
4680: \mathtt{Javacc} & 65 & 953 & 79325
4681: & 239.22 & 45 & (3\%) & 3.01 & 382862 & 1.629\\\hline
4682: \end{array}\]
4683: \caption{Flow sensitive (on the operand stack only)
4684: escape analyses with $\er$. Fields are merged. Only
4685: \texttt{java.lang.Object} is included in the analysis.}
4686: \label{fig:analyses_er2}
4687: \end{figure}
4688:
4689: \begin{figure}
4690: \[\begin{array}{|r|r|r|r||r|r|r|r|r|r|}\hline
4691: \multicolumn{1}{|c}{\mbox{benchmark}} &
4692: \multicolumn{1}{|c}{\mbox{clss}} &
4693: \multicolumn{1}{|c}{\mbox{meth}} &
4694: \multicolumn{1}{|c||}{\mbox{bytec}} &
4695: \multicolumn{1}{|c}{\mbox{time}} &
4696: \multicolumn{2}{|c}{\textit{SA}
4697: %\begin{array}{c}
4698: % \mbox{stack}\\
4699: % \mbox{allocations}
4700: %\end{array}
4701: } &
4702: \multicolumn{1}{|c|}{\textit{TT}
4703: %\begin{array}{c}
4704: % \mbox{time per}\\
4705: % \mbox{1000 bytec.}
4706: %\end{array}
4707: } &
4708: \multicolumn{1}{|c|}{\textit{NC}
4709: %\begin{array}{c}
4710: % \mbox{number of}\\
4711: % \mbox{constraints}
4712: %\end{array}
4713: } &
4714: \multicolumn{1}{|c|}{\textit{LIN}
4715: %\begin{array}{c}
4716: % \mbox{linearity}
4717: %\end{array}
4718: } \\\hline
4719: \mathtt{Figures} & 6 & 17 & 146
4720: & 0.10 & 3 & (60\%) & 0.68 & 454 & 1.003\\\hline
4721: \mathtt{LimVect} & 4 & 11 & 1057
4722: & 0.18 & 1 & (33\%) & 0.17 & 2743 & 1.007\\\hline
4723: \mathtt{Dhrystone} & 14 & 54 & 2240
4724: & 0.35 & 12 & (75\%) & 0.16 & 7157 & 1.116\\\hline
4725: \mathtt{ImageVwr} & 47 & 209 & 8557
4726: & 1.64 & 1 & (8\%) & 0.19 & 43152 & 1.242\\\hline
4727: \mathtt{Morph} & 18 & 93 & 7302
4728: & 1.20 & 1 & (5\%) & 0.16 & 33512 & 1.168\\\hline
4729: \mathtt{JLex} & 72 & 396 & 21025
4730: & 3.71 & 48 & (22\%) & 0.18 & 94243 & 1.248\\\hline
4731: \mathtt{JavaCup} & 84 & 569 & 23196
4732: & 11.98 & 213 & (39\%) & 0.52 & 147139 & 1.434\\\hline
4733: \mathtt{Julia} & 530 & 2007 & 60846
4734: & 50.47 & 331 & (41\%) & 0.83 & 348621 & 1.551\\\hline
4735: \mathtt{Jess} & 363 & 2151 & 71329
4736: & 53.71 & 289 & (22\%) & 0.75 & 399188 & 1.539\\\hline
4737: \mathtt{Javacc} & 160 & 1489 & 97981
4738: & 65.75 & 878 & (61\%) & 0.67 & 418552 & 1.436\\\hline
4739: \end{array}\]
4740: \caption{Flow sensitive (on the operand stack only) escape analyses with the
4741: abstract domain $\er$.
4742: Fields are merged. The standard library classes
4743: \texttt{java.lang.}$\{$\texttt{Object},
4744: \texttt{CharSequence},
4745: \texttt{String*},
4746: \texttt{AbstractStringBuilder},
4747: \texttt{Integer},\texttt{Number},
4748: \texttt{Character}$\}$ and
4749: \texttt{java.util.}$\{$\texttt{AbstractList},
4750: \texttt{AbstractCollection},
4751: \texttt{Vector},
4752: \texttt{HashMap},\texttt{Hashtable},
4753: \texttt{AbstractMap}$\}$ are included in the analysis.
4754: For $\mathtt{Julia}$,
4755: we also included the \textsf{bcel} libraries for bytecode manipulation.}
4756: \label{fig:analyses_er3}
4757: \end{figure}
4758: %
4759: \begin{figure}
4760: \[\begin{array}{|r|r|r|r||r|r|r|r|r|r|}\hline
4761: \multicolumn{1}{|c}{\mbox{benchmark}} &
4762: \multicolumn{1}{|c}{\mbox{clss}} &
4763: \multicolumn{1}{|c}{\mbox{meth}} &
4764: \multicolumn{1}{|c||}{\mbox{bytec}} &
4765: \multicolumn{1}{|c}{\mbox{time}} &
4766: \multicolumn{2}{|c}{\textit{SA}
4767: %\begin{array}{c}
4768: % \mbox{stack}\\
4769: % \mbox{allocations}
4770: %\end{array}
4771: } &
4772: \multicolumn{1}{|c|}{\textit{TT}
4773: %\begin{array}{c}
4774: % \mbox{time per}\\
4775: % \mbox{1000 bytec.}
4776: %\end{array}
4777: } &
4778: \multicolumn{1}{|c|}{\textit{NC}
4779: %\begin{array}{c}
4780: % \mbox{number of}\\
4781: % \mbox{constraints}
4782: %\end{array}
4783: } &
4784: \multicolumn{1}{|c|}{\textit{LIN}
4785: %\begin{array}{c}
4786: % \mbox{linearity}
4787: %\end{array}
4788: } \\\hline
4789: \mathtt{Figures} & 6 & 17 & 146
4790: & 0.13 & 3 & (60\%) & 0.89 & 454 & 1.003\\\hline
4791: \mathtt{LimVect} & 4 & 11 & 1057
4792: & 0.18 & 1 & (33\%) & 0.17 & 2743 & 1.001\\\hline
4793: \mathtt{Dhrystone} & 14 & 54 & 2240
4794: & 0.34 & 12 & (75\%) & 0.15 & 7157 & 1.080\\\hline
4795: \mathtt{ImageVwr} & 47 & 209 & 8557
4796: & 1.76 & 1 & (8\%) & 0.20 & 43174 & 1.218\\\hline
4797: \mathtt{Morph} & 18 & 93 & 7302
4798: & 1.14 & 1 & (5\%) & 0.16 & 33526 & 1.158\\\hline
4799: \mathtt{JLex} & 72 & 396 & 21025
4800: & 3.11 & 49 & (23\%) & 0.15 & 94383 & 1.153\\\hline
4801: \mathtt{JavaCup} & 84 & 569 & 23196
4802: & 9.24 & 215 & (39\%) & 0.40 & 147159 & 1.319\\\hline
4803: \mathtt{Julia} & 530 & 2007 & 60846
4804: & 38.61 & 336 & (41\%) & 0.63 & 348799 & 1.428\\\hline
4805: \mathtt{Jess} & 363 & 2151 & 71329
4806: & 56.71 & 289 & (22\%) & 0.79 & 399289 & 1.488\\\hline
4807: \mathtt{Javacc} & 160 & 1489 & 97981
4808: & 59.45 & 895 & (62\%) & 0.61 & 419067 & 1.378\\\hline
4809: \end{array}\]
4810: \caption{Flow sensitive (on the operand stack only) escape analyses with the
4811: abstract domain $\er$.
4812: A specific approximation is used for each field.
4813: The same library classes as in Figure~\ref{fig:analyses_er3}
4814: %\texttt{java.lang.}$\{$\texttt{Object},\texttt{Character},
4815: %\texttt{String*},\texttt{Integer},
4816: %\texttt{CharSequence},\texttt{Number},\texttt{AbstractStringBuilder}$\}$ as
4817: %well as
4818: %\texttt{java.util.}$\{$\texttt{Vector},\texttt{AbstractList},
4819: %\texttt{AbstractCollection},\texttt{Hashtable},
4820: %\texttt{AbstractMap},\texttt{HashMap}$\}$
4821: are included in the analysis.
4822: For $\mathtt{Julia}$,
4823: we also included the \textsf{bcel} libraries for bytecode manipulation.}
4824: \label{fig:analyses_er4}
4825: \end{figure}
4826: %
4827:
4828: The final experiments used the full power of
4829: the $\er$ abstract domain by providing a (flow insensitive)
4830: specific approximation for each field. The results are shown in
4831: Figure~\ref{fig:analyses_er4}. The precision is just slightly better
4832: than in Figure~\ref{fig:analyses_er3}, and the analyses
4833: require less time. They are sometimes even faster than those
4834: in Figure~\ref{fig:analyses_er2}.
4835: This reduction in time might seem surprising. However, this is a consequence
4836: of the fact that a field-specific approximation slightly increases
4837: the number of constraints, but reduces
4838: linearity and the average size of creation point sets;
4839: hence, less time is needed to solve the constraints
4840: (compare the linearity columns in Figures~\ref{fig:analyses_er3}
4841: and~\ref{fig:analyses_er4}). A similar behaviour has been experienced
4842: in~\cite{RountevMR01}.
4843: More generally, it has been witnessed in different contexts that increasing the
4844: precision of a static analysis may yield faster computations, since
4845: an imprecise analysis yields spurious execution paths which
4846: slow down the analysis itself.
4847:
4848: Beyond these experiments, we also tried to include more library classes in the
4849: analysis (such as all \texttt{java.lang} and \texttt{java.util} packages),
4850: but the results were very similar to those in Figure~\ref{fig:analyses_er4},
4851: confirming the claim in~\cite{Blanchet03} that most of the
4852: stack allocatable objects are arrays,
4853: \texttt{java.lang.StringBuffer}s and a few objects of the collection
4854: classes (vectors and sets).
4855: We also tried to use flow sensitivity for the local variables and the
4856: field approximations but this did not improve the results.
4857: This behaviour can be
4858: explained, for local variables, by observing that typical Java compilers
4859: do not try to recycle local variables if they can be used for different tasks
4860: in different parts of a method. Hence one approximation per method is
4861: enough.
4862: %For fields, it is probable that the fact that object escapes
4863: %is not strictly related to the field which holds the object.
4864: Note that both conclusions agree with the results provided
4865: in~\cite{ChoiGSSM03} where flow sensitivity looks
4866: useless for stack allocation and a bounded field approximation
4867: reduces the precision of stack allocation in at most one case in ten.
4868: The analysis in~\cite{ChoiGSSM03} works for Java instead of Java
4869: bytecode, so flow sensitivity for the operand stack is meaningless in their
4870: case.
4871: %For fields, our explanation is that our
4872: %$\er$ abstract domain can only \emph{accumulate} the creation points stored in
4873: %a field (Figure~\ref{fig:operations_er}) so flow sensitivity for the fields
4874: %cannot be very effective.
4875:
4876: The precision of the analyses seems similar to that of the experiments
4877: reported in~\cite{Blanchet03}. The results reported in
4878: Figure~\ref{fig:analyses_er4} for the first five benchmarks are actually
4879: optimal, in the sense that no other creation point can ever be stack allocated.
4880: For the other five benchmarks, the exact comparison is hard since the
4881: older versions of the benchmarks, as analysed in~\cite{Blanchet03}, are
4882: not available anymore. See, however, Section~\ref{sec:discussion}
4883: for a theoretical comparison.
4884:
4885: The overall conclusion we draw from our experiments is that flow sensitivity
4886: is important, but only for the stack variables. The inclusion of library
4887: classes is also essential for the precision although,
4888: in practice, only very few
4889: classes are needed. The ability to approximate each field
4890: individually does not contribute significantly to the precision of the
4891: analyses, but improves their efficiency.
4892: %
4893: \subsubsection{Dynamic Tests}\label{subsub:dynamic}
4894: %
4895: The static measurements in Subsection~\ref{subsub:static} have been
4896: useful to compare the relative precision and cost of different
4897: implementations of our escape analysis.
4898: However, another piece of information, important
4899: for an escape analysis, is the number of creation operations that are actually
4900: avoided \emph{at run-time} because their creation point has been
4901: stack allocated.
4902: As well as the size of the objects which are stack allocated
4903: \wrt the size of the objects which are heap allocated.
4904: We computed these measurements for
4905: the analyses reported in Figure~\ref{fig:analyses_er4} only, which are
4906: the most precise escape analyses which we managed to implement with
4907: $\er$. Some results are shown in Figure~\ref{fig:dynamic}. For each
4908: benchmark, we report the number of objects and the amount of memory allocated
4909: in the stack or in the heap.
4910: %
4911: In Section~\ref{sec:discussion}, these results are compared with
4912: results reported for other escape analysers. Here we just note that
4913: the poor result for the escape analysis of \texttt{Julia} is a consequence
4914: of the fact that \texttt{Julia} mainly computes a large set of constraints
4915: which escape from their creating methods to flow into the methods that
4916: solve them. We note that escape analysis is of little use for this
4917: type of program.
4918: %and that we do not count the stack allocations performed inside
4919: %the standard Java classes, while the implementation described
4920: %in~\cite{Blanchet03} is actually part of a Java to C compiler
4921: %which generates a C program from the original Java application,
4922: %libraries included.
4923: %
4924: \begin{figure}
4925: \[
4926: \begin{array}{c}
4927: \begin{array}{|r||r|r|r|r|}\hline
4928: \multicolumn{1}{|c||}{\mbox{benchmark}} &
4929: \multicolumn{2}{|c}{\begin{array}{c}
4930: \mbox{objects in}\\
4931: \mbox{the stack}
4932: \end{array}} &
4933: \multicolumn{2}{|c|}{\begin{array}{c}
4934: \mbox{objects in}\\
4935: \mbox{the heap}
4936: \end{array}} \\\hline
4937: \mathtt{Figures} & 101 & 97.11\% & 3 & 2.89\% \\\hline
4938: \mathtt{LimVect} & 1 & 33.33\% & 2 & 66.66\% \\\hline
4939: \mathtt{Dhrystone} & 200009 & 99.99\% & 4 & 0.01\% \\\hline
4940: \mathtt{JLex} & 672 & 8.92\% & 6854 & 91.08\% \\\hline
4941: \mathtt{JavaCup} & 141875 & 62.37\% & 85564 & 37.63\% \\\hline
4942: \mathtt{Julia} & 5534 & 6.56\% & 78748 & 93.44\% \\\hline
4943: \mathtt{Jess} & 924 & 7.81\% & 10897 & 92.19\% \\\hline
4944: \mathtt{Javacc} & 26461 & 43.72\% & 34050 & 56.28\% \\\hline
4945: \end{array}\\
4946: \mbox{}\\
4947: \begin{array}{|r||r|r|r|r|}\hline
4948: \multicolumn{1}{|c||}{\mbox{benchmark}} &
4949: \multicolumn{2}{|c}{\begin{array}{c}
4950: \mbox{memory in}\\
4951: \mbox{the stack}
4952: \end{array}} &
4953: \multicolumn{2}{|c|}{\begin{array}{c}
4954: \mbox{memory in}\\
4955: \mbox{the heap}
4956: \end{array}} \\\hline
4957: \mathtt{Figures} & 2024 & 98.82\% & 24 & 1.18\%\\\hline
4958: \mathtt{LimVect} & 12 & 30.00\% & 28 & 70.00\%\\\hline
4959: \mathtt{Dhrystone} & 1600140 & 96.03\% & 66144 & 3.97\%\\\hline
4960: \mathtt{JLex} & 147060 & 47.77\% & 160772 & 52.23\% \\\hline
4961: \mathtt{JavaCup} & 1580336 & 48.76\% & 1660516 & 51.24\% \\\hline
4962: \mathtt{Julia} & 70764 & 5.57\% & 1198120 & 94.47\%\\\hline
4963: \mathtt{Jess} & 13328 & 4.90\% & 258128 & 95.10\% \\\hline
4964: \mathtt{Javacc} & 604244 & 40.72\% & 883224 & 59.28\% \\\hline
4965: \end{array}
4966: \end{array}
4967: \]
4968: \caption{The dynamic statistics for our benchmarks. Memory is
4969: expressed in bytes. \texttt{Dhrystone} performs its numerical benchmark
4970: $100000$ times; \texttt{JLex} is applied to \texttt{sample.tex}.
4971: \texttt{JavaCup} is
4972: applied to the grammar \texttt{tiger.cup} (included in the distribution
4973: of \textsc{Julia}) with the \texttt{-dump\_states} option on.
4974: \texttt{Julia} is applied to the escape analysis
4975: of \texttt{Dhrystone} performed as in Figure~\ref{fig:analyses_er4}.
4976: \texttt{Javacc} is applied to the grammar \texttt{Java1.1.jj}.
4977: \texttt{Jess} is applied to the solution of \texttt{fullmab.clp}.}
4978: \label{fig:dynamic}
4979: \end{figure}
4980: %
4981: %
4982: \subsubsection{Cost of the Analysis}\label{subsub:cost}
4983: %
4984: Figure~\ref{fig:analyses_er4} shows that one minute is more than enough to
4985: analyse each of the benchmarks, some of them featuring more than
4986: $2000$ methods.
4987: The \textsc{Julia} analyser is under development,
4988: so that analysis times can only improve.
4989: %PAT0704 rewording and reordering
4990: In theory, as a consequence of using sets of creation
4991: points as variable approximations (Section~\ref{subsec:julia}),
4992: their computation as a
4993: fixpoint of a system of set constraints might require an exponential
4994: number of iterations.
4995: Thus, an important observation from
4996: the same Figure~\ref{fig:analyses_er4} is that there is no
4997: exponential blow-up of the analysis time with the size of the benchmarks
4998: (see the \emph{time per $1000$ bytecodes} column $\mathit{TT}$);
4999: hence, it appears from these results that the worst-case scenario,
5000: leading to an exponential blow-up, is not frequent in practice.
5001: %PAT end
5002: Moreover, from Figure~\ref{fig:analyses_er4} it seems
5003: that the cost of the analysis is not only related to the size of the
5004: benchmark, but also to its linearity. See for instance the case of
5005: \texttt{JLex} and \texttt{JavaCup} in Figure~\ref{fig:analyses_er4}, which have
5006: comparable size (\ie number of bytecodes) but quite different linearity.
5007: %
5008: }
5009: \section{Discussion}\label{sec:discussion}
5010: %
5011: \ifthenelse{\boolean{PROOFSONLY}}{}{
5012: The first escape
5013: analysis~\cite{ParkG92} was designed for functional languages
5014: where lists are the representative data structure.
5015: Hence the analysis
5016: was meant to stack allocate portions of lists which do not escape
5017: from the function which creates them. That analysis was
5018: later made more efficient in~\cite{Deutsch97} and finally extended to some
5019: imperative constructs and applied to very large programs~\cite{Blanchet98}.
5020:
5021: More recently, escape analysis has been studied for object-oriented
5022: languages. In this context, there are actually different formalisations
5023: of the meaning of \emph{escaping}.
5024: While we assume that an object $o$ escapes from
5025: its creating method if it is still reachable after this method terminates,
5026: others (such as~\cite{Ruf00,SalcianuR01,WhaleyL04})
5027: further require that $o$ is actually used after the method terminates.
5028: This results in less conservative and hence
5029: potentially more precise analyses than ours. Note, however,
5030: that our notion of \emph{escaping} allows us to analyse libraries whose calling
5031: contexts are not known at the time of the analysis.
5032:
5033: %~\cite{Blanchet03,ChoiGSSM03,GayS00,HillS02b,HillS02,RuggieriM88,WhaleyR99}.
5034: The first work which can be related to escape analysis seems to us
5035: to be~\cite{RuggieriM88} where
5036: a \emph{lifetime analysis} propagates the \emph{sources}
5037: of data structures. This same idea has been used in~\cite{Agrawal99}
5038: where the traditional reaching definition analysis is extended to
5039: object-oriented programs.
5040: Note that, to improve efficiency,~\cite{Agrawal99}
5041: made the escape analysis demand-driven.
5042:
5043: Many escape analyses use however some graph-based
5044: representation of the memory of the system, typically derived from
5045: previous work on points-to analysis. Escaping objects are then identified
5046: by applying some form of reachability on this graph. Examples
5047: are~\cite{WhaleyR99,SalcianuR01,VivienR01,ChoiGSSM03,WhaleyL04}.
5048: Points-to information lets such analyses select the target of virtual calls
5049: on the basis of the class of the objects pointed to by the
5050: receiver of the virtual call. Although these works abstract
5051: \emph{the memory graph} into a graph while we abstract \emph{the state}
5052: into $\e$ or $\er$, we think that the information
5053: expressed by $\e$ or $\er$ can be derived by
5054: abstracting such graphs. Hence our analyses should be
5055: less precise but more efficient
5056: than~\cite{WhaleyR99,SalcianuR01,VivienR01,ChoiGSSM03,WhaleyL04}.
5057: Namely, we miss the sharing information contained in a graph-based
5058: representation of the memory of the system.
5059: Note that, to improve efficiency, some escape analyses such as~\cite{VivienR01}
5060: have been made incremental.
5061:
5062: A large group of escape analyses use constraints (typically,
5063: set-constraints) for expressing escape analyses. These
5064: include~\cite{BogdaH99,GayS00,Ruf00,StreckenbachS00,RountevMR01},
5065: although~\cite{StreckenbachS00} assumes that points-to information is
5066: available at the time of the analysis.
5067: The escape analysis in~\cite{Blanchet03} is unique
5068: in that it uses integer \emph{contexts} to
5069: specify the part of a data structure which can escape.
5070: %This is the only
5071: %example where typing information is used to improve the
5072: %precision of the escape analysis.
5073: However, integer contexts are
5074: an approximation of the full typing information used in
5075: our abstract domain $\er$ as well as in most of the previously
5076: cited escape analyses. This possible imprecision has been observed also
5077: by~\cite{ChoiGSSM03} where it is said (without formal proof)
5078: that their analysis is \emph{inherently more precise} than that
5079: defined in~\cite{Blanchet03}.
5080: The simplicity of Blanchet's escape analysis is however appealing,
5081: and the experimental times he reports in~\cite{Blanchet03}
5082: currently score as the fastest of all the cited analyses that provide timings.
5083:
5084: The way we deal with exceptions (Subsection~\ref{subsec:julia})
5085: is largely inspired by~\cite{JacobsP03}.
5086: It is also similar to the technique in~\cite{ChoiGHS99}, although their
5087: optimised factorisation is not currently implemented
5088: inside our \textsc{Julia} analyser. Once implemented, we expect it to improve
5089: the overall efficiency of the analyses shown in Figure~\ref{fig:analyses_er4}.
5090:
5091: Some escape analyses have been formally proved correct.
5092: Namely,~\cite{WhaleyR99} has been proved correct in~\cite{Salcianu01t},
5093: and~\cite{ChoiGSSM03} in~\cite{ChoiGSSM02}. Neither proof is based
5094: on abstract interpretation, and no optimality result is proved.
5095: The proof in~\cite{Blanchet03} is closer to ours, since it
5096: is based on abstract interpretation. However, a Galois connection is proved
5097: to exist between the concrete and the abstract domain, rather than
5098: a Galois insertion. Moreover, no optimality result for the abstract operations
5099: is provided.
5100:
5101: To the best of our knowledge,
5102: our notion of abstract garbage collector (Definitions~\ref{def:delta}
5103: and~\ref{def:xi}) and its use for deriving Galois \emph{insertions}
5104: rather than \emph{connections} (Propositions~\ref{prop:e_insertion}
5105: and~\ref{prop:er_insertion}) is new.
5106: A similar idea has been used in~\cite{ChoiGSSM03}, which
5107: removes from the connection graphs (their abstraction)
5108: that part that consists only of captured nodes (unreachable from
5109: parameters, result and static variables). However, this was not
5110: related to the Galois insertion property.
5111: Static types of variables are used in~\cite{LhotakH03} to improve the
5112: precision of a points-to analysis by removing spurious points-to
5113: sets which are not allowed by the static typing of the variables.
5114: This idea is somehow similar to our garbage-collectors, but
5115: no connection is shown to the Galois insertion property.
5116:
5117: It is quite hard to compare the available escape analyses \wrt precision.
5118: From a theoretical point of view, their definitions are sometimes
5119: so different that a formal comparison inside the same framework is
5120: impossible. However, below we make some informal comparisons
5121: and discuss some of the issues that affect the precision.
5122: \begin{itemize}
5123: \item Escape analyses using graph-based representations of the heap should
5124: be the most precise overall since they express points-to and sharing
5125: information~\cite{WhaleyR99,SalcianuR01,VivienR01,ChoiGSSM03,WhaleyL04}.
5126: \item Precision is also significantly affected by the call-graph construction
5127: algorithm used for the analysis which is largely independent from the
5128: analysis itself~\cite{TipP00,GroveC01}.
5129: As $\er$ couples each variable with the set of its creation points,
5130: class information can be recovered and the call-graph constructed.
5131: This is also typical of those analyses that compute some form
5132: of points-to information.
5133: \item Another issue related to precision is the
5134: level of flow and context sensitivity of the analysis. Our experiments
5135: (Section~\ref{subsec:tests})
5136: have shown that flow sensitivity is important
5137: for the operand stack only. This agrees with the experiments reported
5138: in~\cite{ChoiGSSM03}, since the operand stack is
5139: a feature of Java bytecode not present in Java
5140: (the target language of~\cite{ChoiGSSM03}).
5141: Context sensitivity \ie the
5142: ability to name a given creation point in method $m$
5143: with different names, depending
5144: on the call site of $m$, is advocated as an important feature
5145: of escape analyses~\cite{WhaleyR99,VivienR01,Blanchet03}. This idea
5146: is taken further in~\cite{WhaleyL04}, where method bodies are
5147: \emph{cloned} for each different calling context in order to improve
5148: the precision of the analysis. Our analysis decorates each given program
5149: point with a unique name, and hence misses this extra axis of
5150: precision. Note, however, that method cloning can safely be
5151: applied before many escape analyses, including ours.
5152: \item The optimality of the abstract operations or algorithm used
5153: for the analysis also affects its precision, since optimality entails that the
5154: analysis uses the abstract information in the most precise possible way.
5155: To the best of our knowledge, we are the first to prove an optimality
5156: result for the abstract operations of an escape analysis, which is a
5157: significant step forward although we are aware that the composition
5158: of optimal operations to build an abstract semantics is not necessarily
5159: optimal.
5160: \item A final source of precision comes from the
5161: preliminary inlining of small methods before the actual analysis is applied.
5162: Inlining can only enlarge the possibilities for stack allocation,
5163: although care must be taken to avoid any exponential code explosion.
5164: As far as we can see, only~\cite{Blanchet03} applies method
5165: inlining before the escape analysis. This technique is largely independent
5166: from the subsequent escape analysis, so it could be applied with
5167: other escape analyses, including our own.
5168: \item Some specially designed analyses should perform better on some
5169: specific applications. For instance, the analysis in~\cite{Ruf00}
5170: is probably the most precise one
5171: \wrt synchronisation elimination. This is because it allows one
5172: to remove unnecessary synchronisation (locking)
5173: on objects which do escape from their creating
5174: thread provided that, at run-time, they are locked by at most one thread.
5175: As another example the analysis in~\cite{SalcianuR01} is expected to
5176: perform better on multithreaded applications, since it models precisely
5177: inter-thread interactions. All other escape analyses (including ours)
5178: conservatively assume instead that everything stored inside a thread object
5179: (and the thread object itself) escapes.
5180: \end{itemize}
5181:
5182: From an experimental point of view, a comparison of different escape analyses
5183: is possible although hard and sometimes contradictory. This difficulty
5184: is due to the fact that some analyses have been evaluated
5185: \wrt stack allocation, others \wrt
5186: synchonization elimination, and others \wrt both. Moreover, sometimes
5187: only compile-time (\emph{static}) statistics are provided
5188: (such as~\cite{VivienR01}), sometimes
5189: only run-time (\emph{dynamic}) statistics (such as~\cite{Blanchet03}),
5190: sometimes both (such as~\cite{ChoiGSSM03} and ourselves).
5191: Still, some statistics include the library classes (such
5192: as~\cite{BogdaH99,Ruf00,Blanchet03}), others only report numbers for
5193: the user classes (such as~\cite{ChoiGSSM03}, which analyses library
5194: code during the analysis but does not transform it for stack allocation,
5195: exactly as we do in Subsection~\ref{subsec:tests}).
5196: Furthermore, there is no standard set of benchmarks evaluated across
5197: all different escape analyses.
5198: %(the SPEC JVM98 suite is not public domain
5199: %anymore, so many, such as ourselves, do not analyse it).
5200: If some benchmark is shared by different
5201: analyses, their version number is not necessarily the same.
5202: For what concerns the dynamic statistics, the input provided to the
5203: benchmark is important. Hence we provided this information
5204: in Figure~\ref{fig:dynamic}, trying to make it as similar
5205: to that in~\cite{Blanchet03} as possible. However, others do not
5206: specify this information (such as~\cite{ChoiGSSM03}). Finally,
5207: analysis times are not always disclosed, making a fair comparison harder.
5208: Let us anyway compare the
5209: benchmarks that we share with~\cite{Blanchet03}, \cite{ChoiGSSM03}
5210: and~\cite{RountevMR01}. From Figure~\ref{fig:dynamic}, we see
5211: that we perform equally on \texttt{Dhrystone}
5212: \wrt~\cite{Blanchet03} (which, however, does not specify the
5213: parameter passed to \texttt{Dhrystone}, which completely modifies
5214: the run-time behaviour of \texttt{Dhrystone}).
5215: For \texttt{JLex}, we stack allocate $47.77\%$ of the memory
5216: while~\cite{Blanchet03} stack allocates $26\%$;
5217: we stack allocate $8.92\%$ of the run-time objects,
5218: while~\cite{RountevMR01} stack allocates $31.6\%$;
5219: we found $23\%$ of the allocation sites to be stack allocatable
5220: (Figure~\ref{fig:analyses_er4}) while~\cite{RountevMR01} found $27\%$.
5221: For \texttt{JavaCup}, we stack allocate $48.76\%$ of the memory,
5222: while~\cite{ChoiGSSM03} stack allocates $17\%$. We stack allocate $39\%$ of
5223: the allocation sites, while~\cite{RountevMR01} stack allocates $30\%$.
5224: For \texttt{Jess}, we only stack allocate $4.90\%$ of the memory,
5225: while~\cite{Blanchet03} manages to stack allocate $27\%$
5226: and~\cite{RountevMR01} $17.9\%$.
5227: %PAT0704 rewording
5228: This case may be a consequence of
5229: a preliminary lack of methods inlining,
5230: %PAT0704 end
5231: since the \texttt{Jess} program actually
5232: contains a large set of very small methods.
5233: For \texttt{Javacc}, we stack allocate $40.72\%$ of the memory,
5234: while~\cite{Blanchet03} stack allocates $43\%$; we stack allocate
5235: $43.72\%$ of the run-time objects, while~\cite{RountevMR01}
5236: stack allocates $45.8\%$; this is contradictory with the fact
5237: that we found $62\%$ of the allocation sites to be
5238: stack allocatable (Figure~\ref{fig:analyses_er4}) while~\cite{RountevMR01}
5239: found only $29\%$.
5240: %For what concerns synchronisation elimination, the more precise analysis
5241: %seems~\cite{Ruf00}, and we do not expect our analysis to improve on it.
5242:
5243: %
5244: %\begin{figure}[t]
5245: %\begin{center}
5246: %\begin{tabular}{|l||c|c|c|c|c|c|c|}
5247: %\hline
5248: %& B & C & G & R & W & $\e$ & $\er$\\\hline\hline
5249: %Is the analysis context-sensitive? & Y & Y & N & Y & Y & Y & Y\\\hline
5250: %Is the analysis compositional? & Y & N & Y & Y & Y & Y & Y\\\hline
5251: %Is there a correctness proof? & Y & N & N & N & N & Y & Y\\\hline
5252: %Is there an optimality proof of the operations? & N & N & N & N & N & Y & Y\\\hline
5253: %Is the access to a field somehow approximated? & Y & Y & N & Y & Y & Y & Y\\\hline
5254: %Are virtual calls somehow restricted? & N & N & N & N & N & Y & Y\\\hline
5255: %$\begin{array}{l}
5256: %\text{Can it derive '$\pi_4$ is unreachable in $w_3$'
5257: % (Fig.\ \ref{fig:program})}\\
5258: %\text{if $\mathtt{n}$ is a list of $\mathtt{circle}$s?}
5259: %\end{array}$
5260: % & N & N & N & N & N & N & Y\\\hline
5261: %\end{tabular}
5262: %\end{center}
5263: %\caption{A comparison of different escape analyses.}\label{fig:comparison}
5264: %\end{figure}
5265:
5266: %In Figure~\ref{fig:comparison},
5267: %the columns labeled B, C, G, R and W compare the different
5268: %escape analyses proposed for object-oriented
5269: %languages, respectively, in
5270: %\cite{Blanchet03,ChoiGSSM03,GayS00,RuggieriM88,WhaleyR99} with
5271: %the two analyses presented here ($\e$ and $\er$).
5272: %Here \emph{context-sensitive} means that the analysis can provide
5273: %different information in different program points;
5274: %\emph{compositional}, that the analysis of a compound
5275: %command is defined in terms of the analysis of its components;
5276: %\emph{approximating the access to a field}, that the analysis
5277: %can provide a better approximation of the creation points of the objects
5278: %stored in a field than the set of all creation points; and
5279: %\emph{restricting the virtual calls}, that the analysis is
5280: %able to discard some targets of a virtual call which can never be selected
5281: %at run-time, although they are allowed by the type system.
5282: %These two last aspects contribute to the precision of the analysis.
5283: %For instance, as the last line of Figure~\ref{fig:comparison} shows,
5284: %it allows us to conclude that the creation point $\pi_4$
5285: %in Figure~\ref{fig:program} is not reachable in program
5286: %point $w_3$, since the call \texttt{f.rot(a)}, contained inside
5287: %\texttt{rotate}, can only lead to
5288: %the method \texttt{rot} inside \texttt{circle}, and never to the method
5289: %\texttt{rot} inside \texttt{square}, which would store the object created at
5290: %$\pi_4$ into the field \texttt{rotation}.
5291: %This information is useful since it is enough for the stack allocation of
5292: %the object created in $\pi_4$ in the call
5293: %\texttt{rotate(f)} at program point $w_3$; or for
5294: %its stack allocation when the first
5295: %\texttt{rotate(f)} call is dropped off.
5296: }
5297: \section{Conclusion}\label{sec:conclusion}
5298: %
5299: We have presented a formal development of an escape analysis by
5300: abstract interpretation, providing optimality results in the form
5301: of a Galois insertion from the concrete to the abstract domain
5302: and of the definition of optimal abstract operations. This escape
5303: analysis has been implemented and applied to full Java (bytecode).
5304: This results in an escape analyser which is probably less precise
5305: than others already developed, but still performs well in practice from the
5306: points of view of its cost and precision
5307: \ifthenelse{\boolean{PROOFSONLY}}{}{(Sections~\ref{subsec:tests}
5308: and~\ref{sec:discussion})}.
5309:
5310: A first, basic escape domain $\e$ is defined
5311: as a property of concrete states (Definition~\ref{def:property_e}).
5312: This domain is simple but non-trivial since
5313: %
5314: \begin{itemize}
5315: \item The set of the creation points of the objects reachable from the current
5316: state can both grow ($\mathsf{new}$) and shrink ($\delta$);
5317: \ie \emph{static type information contains escape information}
5318: (Examples~\ref{ex:rho_not_onto} and~\ref{ex:abstract_operations_e});
5319: \item That set is useful, sometimes, to restrict the
5320: possible targets of a virtual call \ie
5321: \emph{escape information contains class information}
5322: (Example~\ref{ex:abstract_operations_e}).
5323: \end{itemize}
5324: %
5325: However, the escape analysis induced by our domain $\e$ is
5326: not precise enough from a computational point of view,
5327: since it induces rather imprecise abstract operations.
5328: %while those in~\cite{Blanchet03,ChoiGSSM03,GayS00,RuggieriM88,WhaleyR99}
5329: %have been developed with that in mind.
5330: %In spite of this, since the domain $\e$ can sometimes predict the target of
5331: %a virtual call, $\e$ can, on occasions, be more precise than all other escape
5332: %analyses that do not feature such property.
5333: %An example of such behaviour
5334: %is given in Section~\ref{sec:introduction}.
5335: %Since $\e$ coincides with the \emph{escape property} itself,
5336: %the other escape analyses are either not a concretisation of
5337: %this property, or their operations do not fully preserve it.
5338: %We therefore claim that $\e$ makes the right starting point
5339: %for a formal foundation of escape analysis;
5340: %more precise domains should then be \emph{refinements} of $\e$
5341: %\ie uniformly more precise than $\e$, which, as
5342: %said above, is not the case
5343: %for~\cite{Blanchet03,ChoiGSSM03,GayS00,RuggieriM88,WhaleyR99}.
5344: We have therefore defined a refinement $\er$ of $\e$, on the basis of the
5345: information that $\e$ lacks, in order to attain better precision.
5346: The relation between $\er$ and $\e$ is similar to that between Palsberg and
5347: Schwartzbach's class analysis~\cite{PalsbergS91,SpotoJ03}
5348: and \emph{rapid type analysis}~\cite{BaconS96}
5349: although, while all objects stored in memory are
5350: considered in~\cite{BaconS96,SpotoJ03,PalsbergS91},
5351: only those actually reachable from the variables in scope
5352: are considered by the domains $\e$
5353: and $\er$ (Definitions~\ref{def:alpha} and~\ref{def:er_abstraction}).
5354: The ability to describe only the reachable objects, through the use
5355: of an abstract garbage collector ($\delta$ in Figure~\ref{fig:operations_e}
5356: and $\xi$ in Figure~\ref{fig:operations_er}), improves the
5357: precision of the analysis, since it becomes focused on only those objects
5358: that can actually affect the concrete execution of the program.
5359:
5360: It is interesting to consider if this notion of reachability and the use
5361: of an abstract garbage collector can be applied to other static analyses
5362: of the run-time heap as well. Namely, class, shape, sharing and cyclicity
5363: analyses might benefit from them.
5364: %To the best of our knowledge, only~\cite{Blanchet03}, \cite{GayS00}
5365: %and~\cite{ChoiGSSM03} present an implementation
5366: %of an escape analysis for Java. We have not been able to provide a direct
5367: %comparison of the precision and efficiency of our analysis with theirs.
5368: %This is because~\cite{Blanchet03} inlines \emph{small} methods
5369: %before applying his escape analysis. He argues
5370: %that inlining increases the number of objects that
5371: %can be stack allocated. Instead, our experiments show the precision of
5372: %the escape analysis alone. Moreover, the analysis of~\cite{Blanchet03} is
5373: %implemented inside a commercial Java compiler.
5374: %Finally,~\cite{Blanchet03}, \cite{GayS00} and~\cite{ChoiGSSM03}
5375: %report the number of objects that are stack allocated \emph{at run-time}
5376: %for a specific run of the programs.
5377: %They do not present the number of creation points that can be stack allocated
5378: %\emph{at compile-time}, which is instead what we show in
5379: %Figures~\ref{fig:analyses_er} and~\ref{fig:analyses_er_string}.
5380: %The dynamic information provided in~\cite{Blanchet03},
5381: %\cite{GayS00} and~\cite{ChoiGSSM03} seems however in line with the static
5382: %information provided in Figure~\ref{fig:analyses_er_string}.
5383: %
5384: \begin{acknowledgements}
5385: This work has been funded by the Italian
5386: MURST grant \emph{Abstract Interpretation,
5387: Type Systems and Control-Flow Analysis} and by the British
5388: EPSRC grant GR/R53401.
5389: \end{acknowledgements}
5390: %
5391: %%}%%\ifthenelse{\boolean{PROOFSONLY}}{%%
5392: \bibliographystyle{plain}
5393: %
5394: \ifthenelse{\boolean{PROOFSONLY}}{%%
5395: %\bibliography{main}
5396: \begin{thebibliography}{10}
5397:
5398: \bibitem{Agrawal99}
5399: G.~Agrawal.
5400: \newblock Simultaneous {D}emand-{D}riven {D}ata-flow and {C}all {G}raph
5401: {A}nalysis.
5402: \newblock In {\em Proc.\ of the International Conference on Software
5403: Maintenance (ICSM'99)}, pages 453--462, Oxford, UK, September 1999. IEEE
5404: Computer Society.
5405:
5406: \bibitem{ArnoldGH00}
5407: K.~Arnold, J.~Gosling, and D.~Holmes.
5408: \newblock {\em The {J}ava$^{TM}$ {P}rogramming {L}anguage}.
5409: \newblock Addison-Wesley, third edition, 2000.
5410:
5411: \bibitem{BaconS96}
5412: D.~F. Bacon and P.~F. Sweeney.
5413: \newblock Fast {S}tatic {A}nalysis of {C}++ {V}irtual {F}unction {C}alls.
5414: \newblock In {\em Proc.\ of OOPSLA'96}, volume 31(10) of {\em ACM SIGPLAN
5415: Notices}, pages 324--341, New York, 1996. ACM Press.
5416:
5417: \bibitem{Blanchet98}
5418: B.~Blanchet.
5419: \newblock Escape {A}nalysis: {C}orrectness {P}roof, {I}mplementation and
5420: {E}xperimental {R}esults.
5421: \newblock In {\em 25th ACM SIGPLAN-SIGACT Symposium of Principles of
5422: Programming Languages (POPL'98)}, pages 25--37, San Diego, CA, USA, January
5423: 1998. ACM Press.
5424:
5425: \bibitem{Blanchet03}
5426: B.~Blanchet.
5427: \newblock Escape {A}nalysis for {J}ava: {T}heory and {P}ractice.
5428: \newblock {\em ACM TOPLAS}, 25(6):713--775, November 2003.
5429:
5430: \bibitem{BogdaH99}
5431: J.~Bogda and U.~H\"olzle.
5432: \newblock Removing {U}nnecessary {S}ynchronization in {J}ava.
5433: \newblock In {\em Proc.\ of OOPSLA'99}, volume 34(10) of {\em SIGPLAN Notices},
5434: pages 35--46, Denver, Colorado, USA, November 1999.
5435:
5436: \bibitem{BossiGLM94}
5437: A.~Bossi, M.~Gabbrielli, G.~Levi, and M.~Martelli.
5438: \newblock The s-{S}emantics {A}pproach: {T}heory and {A}pplications.
5439: \newblock {\em Journal of Logic Programming}, 19/20:149--197, 1994.
5440:
5441: \bibitem{ChoiGSSM03}
5442: J.-D. Choi, M.~Gupta, M.~J. Serrano, V.~C. Sreedhar, and S.~P. Midkiff.
5443: \newblock Stack {A}llocation and {S}ynchronization {O}ptimizations for {J}ava
5444: {U}sing {E}scape {A}nalysis.
5445: \newblock {\em ACM TOPLAS}, 25(6):876--910, November 2003.
5446:
5447: \bibitem{CortesiFW98}
5448: A.~Cortesi, G.~Fil\'e, and W.~Winsborough.
5449: \newblock The {Q}uotient of an {A}bstract {I}nterpretation.
5450: \newblock {\em Theoretical Computer Science}, 202(1-2):163--192, 1998.
5451:
5452: \bibitem{CousotC77}
5453: P.~Cousot and R.~Cousot.
5454: \newblock Abstract {I}nterpretation: {A} {U}nified {L}attice {M}odel for
5455: {S}tatic {A}nalysis of {P}rograms by {C}onstruction or {A}pproximation of
5456: {F}ixpoints.
5457: \newblock In {\em Proc.\ of POPL'77}, pages 238--252, 1977.
5458:
5459: \bibitem{CousotC92}
5460: P.~Cousot and R.~Cousot.
5461: \newblock Abstract {I}nterpretation and {A}pplications to {L}ogic {P}rograms.
5462: \newblock {\em Journal of Logic Programming}, 13(2 \& 3):103--179, 1992.
5463:
5464: \bibitem{Dams96}
5465: D.~R. Dams.
5466: \newblock {\em Abstract {I}nterpretation and {P}artition {R}efinement for
5467: {M}odel {C}hecking}.
5468: \newblock PhD thesis, Eindhoven University of Technology, The Netherlands, July
5469: 1996.
5470:
5471: \bibitem{Deutsch97}
5472: A.~Deutsch.
5473: \newblock On the {C}omplexity of {E}scape {A}nalysis.
5474: \newblock In {\em 24th ACM SIGPLAN-SIGACT Symposium on Principles of
5475: Programming Languages (POPL'97)}, pages 358--371, Paris, France, January
5476: 1997. ACM Press.
5477:
5478: \bibitem{GayS00}
5479: D.~Gay and B.~Steensgaard.
5480: \newblock Fast {E}scape {A}nalysis and {S}tack {A}llocation for
5481: {O}bject-{B}ased {P}rograms.
5482: \newblock In D.~A. Watt, editor, {\em Compiler Construction, 9th International
5483: Conference (CC'00)}, volume 1781 of {\em Lecture Notes in Computer Science},
5484: pages 82--93. Springer-Verlag, Berlin, March 2000.
5485:
5486: \bibitem{GiacobazziR97}
5487: R.~Giacobazzi and F.~Ranzato.
5488: \newblock Refining and {C}ompressing {A}bstract {D}omains.
5489: \newblock In {\em Proc.\ of the 24th International Colloquium on Automata,
5490: Languages and Programming (ICALP'97)}, volume 1256 of {\em LNCS}, pages
5491: 771--781. Springer-Verlag, 1997.
5492:
5493: \bibitem{GiacobazziS98}
5494: R.~Giacobazzi and F.~Scozzari.
5495: \newblock A {L}ogical {M}odel for {R}elational {A}bstract {D}omains.
5496: \newblock {\em ACM Transactions on Programming Languages and Systems},
5497: 20(5):1067--1109, 1998.
5498:
5499: \bibitem{HillS02b}
5500: P.~M. Hill and F.~Spoto.
5501: \newblock A {F}oundation of {E}scape {A}nalysis.
5502: \newblock In H.~Kirchner and C.~Ringeissen, editors, {\em Proc.\ of AMAST'02},
5503: volume 2422 of {\em LNCS}, pages 380--395, St.\ Gilles les Bains, La
5504: R\'eunion island, France, September 2002. Springer-Verlag.
5505:
5506: \bibitem{HillS02}
5507: P.~M. Hill and F.~Spoto.
5508: \newblock A {R}efinement of the {E}scape {P}roperty.
5509: \newblock In A.~Cortesi, editor, {\em Proc.\ of the VMCAI'02 workshop on
5510: Verification, Model-Checking and Abstract Interpretation}, volume 2294 of
5511: {\em Lecture Notes in Computer Science}, pages 154--166, Venice, Italy,
5512: January 2002. Springer-Verlag.
5513:
5514: \bibitem{Jensen97}
5515: T.~Jensen.
5516: \newblock Disjunctive {P}rogram {A}nalysis for {A}lgebraic {D}ata {T}ypes.
5517: \newblock {\em {ACM} Transactions on Programming Languages and Systems},
5518: 19(5):752--804, 1997.
5519:
5520: \bibitem{JS87}
5521: N.~D. Jones and H.~S{\o}ndergaard.
5522: \newblock A {S}emantics-based {F}ramework for the {A}bstract {I}nterpretation
5523: of \textsf{Prolog}.
5524: \newblock In S.~Abramsky and C.~Hankin, editors, {\em Abstract Interpretation
5525: of Declarative Languages}, pages 123--142. Ellis Horwood Ltd, 1987.
5526:
5527: \bibitem{LindholmY99}
5528: T.~Lindholm and F.~Yellin.
5529: \newblock {\em The {J}ava$^{\mathit{TM}}$ {V}irtual {M}achine {S}pecification}.
5530: \newblock Addison-Wesley, second edition, 1999.
5531:
5532: \bibitem{CousotC79}
5533: Cousot. P. and R.~Cousot.
5534: \newblock Systematic {D}esign of {P}rogram {A}nalysis {F}rameworks.
5535: \newblock In {\em Proc.\ of the Sixth Annual ACM Symposium on Principles of
5536: Programming Languages (POPL'79)}, pages 269--282, San Antonio, Texas, 1979.
5537: ACM.
5538:
5539: \bibitem{PalsbergS91}
5540: J.~Palsberg and M.~I. Schwartzbach.
5541: \newblock Object-{O}riented {T}ype {I}nference.
5542: \newblock In {\em Proc.\ of OOPSLA'91}, volume 26(11) of {\em ACM SIGPLAN
5543: Notices}, pages 146--161. ACM Press, November 1991.
5544:
5545: \bibitem{ParkG92}
5546: Y.~G. Park and B.~Goldberg.
5547: \newblock Escape {A}nalysis on {L}ists.
5548: \newblock In {\em ACM SIGPLAN'92 Conference on Programming Language Design and
5549: Implementation (PLDI'92)}, volume 27(7) of {\em SIGPLAN Notices}, pages
5550: 116--127, San Francisco, California, USA, June 1992.
5551:
5552: \bibitem{RountevMR01}
5553: A.~Rountev, A.~Milanova, and B.~G. Ryder.
5554: \newblock Points-to {A}nalysis for {J}ava {U}sing {A}nnotated {C}onstraints.
5555: \newblock In {\em Proc.\ of ACM SIGPLAN Conference on Object-Oriented
5556: Programming Systems, Languages and Applications (OOPSLA'01)}, volume 36(11)
5557: of {\em ACM SIGPLAN}, pages 43--55, Tampa, Florida, USA, October 2001.
5558:
5559: \bibitem{Ruf00}
5560: E.~Ruf.
5561: \newblock Effective {S}ynchronization {R}emoval for {J}ava.
5562: \newblock In {\em ACM SIGPLAN Conference on Programming Language Design and
5563: Implementation (PLDI'00)}, volume 35(5) of {\em SIGPLAN Notices}, pages
5564: 208--218, Vancouver, British Columbia, Canada, June 2000.
5565:
5566: \bibitem{RuggieriM88}
5567: C.~Ruggieri and T.~P. Murtagh.
5568: \newblock Lifetime {A}nalysis of {D}ynamically {A}llocated {O}bjects.
5569: \newblock In {\em 15th ACM Symposium on Principles of Programming Languages
5570: (POPL'88)}, pages 285--293, San Diego, California, USA, January 1988.
5571:
5572: \bibitem{SalcianuR01}
5573: A.~Salcianu and M.~Rinard.
5574: \newblock Pointer and {E}scape {A}nalysis for {M}ultithreaded {P}rograms.
5575: \newblock In {\em Proc.\ of ACM SIGPLAN Symposium on Principles and Practice of
5576: Parallel Programming (PPoPP'01)}, volume 36(7) of {\em SIGPLAN Notices},
5577: pages 12--23, Snowbird, Utah, USA, July 2001.
5578:
5579: \bibitem{Scozzari00}
5580: F.~Scozzari.
5581: \newblock Logical {O}ptimality of {G}roundness {A}nalysis.
5582: \newblock {\em Theoretical Computer Science}, 277(1-2):149--184, 2002.
5583:
5584: \bibitem{Sondergaard86}
5585: H.~S{\o}ndergaard.
5586: \newblock An {A}pplication of {A}bstract {I}nterpretation of {L}ogic
5587: {P}rograms: {O}ccur {C}heck {R}eduction.
5588: \newblock In B.~Robinet and R.~Wilhelm, editors, {\em Proc.\ of the European
5589: Symposium on Programming (ESOP)}, volume 213 of {\em Lecture Notes in
5590: Computer Science}, pages 327--338, Saarbr{\"u}cken, Federal Republic of
5591: Germany, March 1986. Springer.
5592:
5593: \bibitem{SpotoJ03}
5594: F.~Spoto and T.~Jensen.
5595: \newblock {C}lass {A}nalyses as {A}bstract {I}nterpretations of {T}race
5596: {S}emantics.
5597: \newblock {\em ACM Transactions on Programming Languages and Systems (TOPLAS)},
5598: 25(5):578--630, September 2003.
5599:
5600: \bibitem{StreckenbachS00}
5601: M.~Streckenbach and G.~Snelting.
5602: \newblock Points-to for {J}ava: {A} {G}eneral {F}ramework and an {E}mpirical
5603: {C}omparison.
5604: \newblock Technical report, Universit\"at Passau, Germany, November 2000.
5605:
5606: \bibitem{Ta55}
5607: A.~Tarski.
5608: \newblock A {L}attice-theoretical {F}ixpoint {T}heorem and its {A}pplications.
5609: \newblock {\em Pacific J. Math.}, 5:285--309, 1955.
5610:
5611: \bibitem{VivienR01}
5612: F.~Vivien and M.~Rinard.
5613: \newblock Incrementalized {P}ointer and {E}scape {A}nalysis.
5614: \newblock In {\em Proc.\ of ACM SIGPLAN Conference on Programming Language
5615: Design and Implementation (PLDI'01)}, volume 36(5) of {\em SIGPLAN Notices},
5616: pages 35--46, Snowbird, Utah, USA, June 2001.
5617:
5618: \bibitem{WhaleyL04}
5619: J.~Whaley and M.~S. Lam.
5620: \newblock Cloning-{B}ased {C}ontext-{S}ensitive {P}ointer {A}lias {A}nalysis
5621: {U}sing {B}inary {D}ecision {D}iagrams.
5622: \newblock In W.~Pugh and C.~Chambers, editors, {\em Proc.\ of ACM SIGPLAN 2004
5623: Conference on Programming Language Design and Implementation (PLDI'04)},
5624: pages 131--144, Washington, DC, USA, June 2004. ACM.
5625:
5626: \bibitem{WhaleyR99}
5627: J.~Whaley and M.~C. Rinard.
5628: \newblock Compositional {P}ointer and {E}scape {A}nalysis for {J}ava
5629: {P}rograms.
5630: \newblock In {\em 1999 ACM SIGPLAN Conference on Object-Oriented Programming
5631: Systems, Languages and Applications (OOPSLA'99)}, volume 34(1) of {\em
5632: SIGPLAN Notices}, pages 187--206, Denver, Colorado, USA, November 1999.
5633:
5634: \bibitem{Winskel93}
5635: G.~Winskel.
5636: \newblock {\em The {F}ormal {S}emantics of {P}rogramming {L}anguages}.
5637: \newblock The MIT Press, 1993.
5638:
5639: \end{thebibliography}
5640:
5641: }{
5642: \bibliography{escape01}
5643: }
5644: %\label{@lastpg}
5645: %
5646:
5647: \ifthenelse{\boolean{WITHAPPENDIX}}{%%
5648: \include{proofs}
5649: } %%\ifthenelse{\boolean{WITHAPPENDIX}}{%%
5650: {} %%\ifthenelse{\boolean{WITHAPPENDIX}}{%%
5651: \end{article}
5652: \end{document}
5653: