[gclist] Question from a newbie

Arlie Davis arlie@sublinear.org
Wed, 7 May 2003 14:07:35 -0400


I don't think it is a matter of "lowered expectations".  It is a matter
of establishing a contract between programming language/environment and
human.  Each programming language/environment provides a different
contract, and your "intuition" may or may not match that of a particular
environment.

Aggressive static analysis should never violate the contract of the
language.  In this example, the compiler should never "free" obj1 before
the call to m2, *IF* there are visible side-effects of doing so that
alter the semantics of the programming language.  (Note that "free" can
mean many different things -- I'm just using it as a placeholder for
"language knows it is garbage".)  But if there are no visible
side-effects (the object does not have a finalizer, etc.), then the
language is free to do whatever it wants.

The ability to examine a value under a debugger is a resonable
constraint/requirement to impose, but it only applies during development
and debugging.  Optimizing compilers have been doing very useful things
for us, that nonetheless make life more difficult for debugging, and I
think this is a Good Thing.  (Try stepping through assembly generated by
a decent optimizing compiler.)

However, if a compiler / runtime environment can determine that obj2 is
no longer needed before the call to m2, why not do it?  The benefits may
seem small in a case such as this -- maybe a single stack slot is made
available again, maybe a single processor register.  (Or, more
importantly, an object sub-graph may be found to be garbage.)  However,
optimizations such as this can have a significant impact when performed
over a large code base.

> Worse, if there are any side-effects associated
> with freeing of obj1 they will occur in an incorrect
> order if obj1 is freed early.

That's just the point, though -- you must define, for a particular
programming language+environment, whether those side-effects are
possible at all, and if they are possible, whether the environment
guarantees ordering semantics with regard to other language events, such
as the reclamation of other objects, or with method call frames.

Obviously, C++ specifies very rigid semantics here, and people have
relied on things like destructor call order.  Other languages have
chosen to provide different semantics, such as finalizers and
non-deterministic finalization.  (Note, however, that it is
non-deterministic from the point of view of the programmer.  If the
language/environment can, in some circumstances, deterministically know
when an object is garbage, it may exploit that knowledge, as long as
doing so maintains the semantic contract with the human.)

-- arlie


-----Original Message-----
From: owner-gclist@lists.iecc.com [mailto:owner-gclist@lists.iecc.com]
On Behalf Of Bakul Shah
Sent: Wednesday, May 07, 2003 1:30 PM
To: Wang, Daniel Chen-An (Dan)
Cc: emery@cs.umass.edu; moss@cs.umass.edu; 'Ravi Jonnalagedda';
gclist@lists.iecc.com
Subject: Re: [gclist] Question from a newbie 


> In practice "data which is not reachable" begs the question of what 
> should
> be  reachable!
> 
> For example:
> void m1() {
> Object obj1 = ...;
> Object obj2 = ...;
>    m2();
>   return obj2;
> }
> 
> void m2() {
>   /* gc gets invoked */
> }
> 
> When m2 is called an the gc is invoked is obj1 reachable?  Well that
> depends on whether or not the compiler spilled the obj1 variable on
the 
> stack or nulled out it's register holding the value. Intuitively obj1
is 
> garbage, because we don't touch it after we return from m2.

Your intuition is different from mine!  The usual language rules dictate
that the extent (i.e. lifetime) of an object such as obj1 is until the
end of m1 (where it goes out of scope and its value has not escaped to
m1's callee).  So my "intuition" says that if for instance I want to
examine obj1's value in m1 after returning from m2 I should be able to
do that!  Worse, if there are any side-effects associated with freeing
of obj1 they will occur in an incorrect order if obj1 is freed early.
In general the "as if" rule _limits_ (or ought to limit) what
optimizations are allowed but perhaps agressive optimizations have
already lowered people's expectations....