- Loading...
(To do: Format this nicely.)
...
From:
...
Vladimir
...
Kozlov
...
Date:
...
May
...
15,
...
2009
...
1:47:21
...
PM
...
PDT
...
_C2
...
implements the
...
flow-insensitive
...
escape
...
analysis
...
algorithm
...
described
...
in:
No Format |
---|
[Choi99] Jong-Deok Shoi, Manish Gupta, Mauricio Seffano, Vugranam C. Sreedhar, Sam Midkiff, "Escape Analysis for Java", Procedings of ACM SIGPLAN OOPSLA Conference, November 1, 1999 |
The
...
analysis
...
requires
...
construction
...
of
...
a
...
"connection
...
graph"
...
(CG)
...
for
...
the
...
method
...
being
...
analyzed.
...
The
...
nodes
...
of
...
the
...
connection
...
graph
...
are:
No Format |
---|
- Java objects (JO) - Local variables (LV) - Fields of an object (OF), these also include array elements |
C2
...
does
...
not
...
have
...
local
...
variables.
...
However
...
for
...
the
...
purposes
...
of
...
constructing
...
the
...
connection
...
graph,
...
the
...
following
...
IR
...
nodes
...
are
...
treated
...
as
...
local
...
variables:
No Format |
---|
Phi (pointer values) LoadP, LoadN Proj#5 (value returned from call nodes including allocations) CheckCastPP, CastPP, EncodeP, DecodeN Return (GlobalEscape) |
The
...
LoadP,
...
Proj
...
and
...
CheckCastPP
...
behave
...
like
...
variables
...
assigned
...
to
...
only
...
once.
...
Only
...
a
...
Phi
...
can
...
have
...
multiple
...
assignments.
...
Each
...
input
...
to
...
a
...
Phi
...
is
...
treated
...
as
...
an
...
assignment
...
to
...
it.
...
The
...
following
...
node
...
types
...
are
...
JavaObject:
No Format |
---|
top() Allocate AllocateArray Parm (for incoming object arguments, GlobalEscape) CastX2P ("unsafe" operations, GlobalEscape) CreateEx (GlobalEscape) ConP, ConN (GlobalEscape except for null) LoadKlass, LoadNKlass (GlobalEscape) ThreadLocal (ArgEscape) |
AddP
...
nodes
...
are
...
fields.
...
After
...
building
...
the
...
graph,
...
a
...
pass
...
is
...
made
...
over
...
the
...
nodes,
...
deleting
...
deferred
...
nodes
...
and
...
copying
...
the
...
edges
...
from
...
the
...
target
...
of
...
the
...
deferred
...
edge
...
to
...
the
...
source.
...
This
...
results
...
in
...
a
...
graph
...
with
...
no
...
deferred
...
edges,
...
only:
No Format |
---|
LV -P> JO
OF -P> JO (the object whose oop is stored in the field)
JO -F> OF
|
After that escape analysis makes a pass over the nodes and determines nodes escape state:
After escape analysis C2 eliminates scalar replaceable object allocations and associated locks. C2 also eliminates locks for all non globally escaping objects. C2 does NOT replace a heap allocation with a stack allocation for non globally escaping objects.
Some scenarios for escape analysis are described next.
No Format |
---|
public class Person { private String name; private int age; It makes a pass over the nodes and determines nodes escape state: GlobalEscape - An object escapes the method and thread public Person(String personName, int personAge) { (stored into a static field orname stored= into personName; age = personAge; a field of an escaped object or returned} as the resultpublic of the current method). ArgEscape - An object passed as argument or referenced byPerson(Person p) { this(p.getName(), p.getAge()); } public int getName() { return name; } public int getAge() { return age; } } public class Employee { private Person person; argument but not globally escape// duringmakes a call defensive copy to protect against modifications by caller public Person getPerson() { return (by analyzing the bytecode of called method). NoEscapenew Person(person) }; public void printEmployeeDetail(Employee emp) { - APerson scalarperson replaceable= objectemp. After escape analysis C2 eliminates scalar replaceable object allocations and associated locks. C2 also eliminates locks for all non globally escaping objects. C2 does NOT replace a heap allocation with a stack allocation for non globally escaping objects. getPerson(); // this caller does not modify the object, so defensive copy was unnecessary System.out.println ("Employee's name: " + person.getName() + "; age: " + person.getAge()); } } |
The method makes a copy to prevent modification of the original object by the caller. If the compiler determines that the getPerson method is being invoked in a loop, it will inline that method. In addition, through escape analysis, if the compiler determines that the original object is never modified, it might optimize and eliminate the call to make a copy.