Project Coin: Inducing contributory heap pollution
Reinier Zwitserloot
reinier at zwitserloot.com
Thu Jun 10 11:47:03 PDT 2010
As I've mentioned before in regards to this topic, there's a list of things
you can do to a potentially polluted array that are perfectly safe (or at
least as safe as anything else with generics is):
1. ask for its length: param.length
2. iterate over it in a foreach: for (Whatever x : param) { ... }
3. read (not write) a value from it: Whatever x = param[whatever];
4. use it as parameter to another method where that parameter is also marked
as "polluted array safe" - e.g. @SuppressWarnings("varargs"). For example,
if Arrays.asList() is given the marker (which it should, nothing bad
happens), then calling Arrays.asList(param) can't result in bad things
either.
I posit that less than 1 in 50 uses of varargs out in the wild today stray
from this list. Instead of having @SuppressWarnings("varargs"), imagine we
have @VarargsSafe instead. The compiler can then implicitly add a
@VarargsSafe annotation to any varargs-accepting method if it detects that
the varargs variable is only used in ways listed in the list above, and
generate a warning when compiling a varargs method that strays from the
list. There's a bit of a risk here in that "@VarargsSafe" is technically
part of the public API and thus shouldn't be removed in a later version, but
that might nevertheless happen "silently" by introducing an operation on the
variable that isn't in the list. However, heap pollution can also occur in
mixed class files situations (mixing class files produced in different
compile runs), interacting with class files produced by compilers other than
javac (e.g. jython), and in general it would seem to be acceptable to
introduce unwarned heap pollution if the odds of it actually being a problem
are spectacularly low, which it would be for this.
The notion that this is part of public API also highlights what Remi
mentioned: Any overloading of a @VarargsSafe method must deal with the fact
that his array's runtime component type is unreliable, because callers are
relying on it not being a problem.
It is perhaps prudent to remember that the current situation isn't actually
avoiding any of the problems that rule 4.12.2.1 is meant to avoid. It
follows the letter but not the spirit of that rule. Those folks that run
into this warning can do absolutely nothing about it. In other words, if the
conclusion is that nothing we do ends up fully following both the letter and
the spirit of rule 4.12.2.1, then something that follows the spirit and 99%
of the letter is a lot better than the status quo.
--Reinier Zwitserloot
On Thu, Jun 10, 2010 at 7:15 PM, Joe Darcy <joe.darcy at oracle.com> wrote:
> Neal Gafter wrote:
> > Re:
> http://blogs.sun.com/darcy/entry/projectcoin_inducing_contributory_pollution
> >
> > I thought technical documents for project Coin were supposed to be
> > published here?
> >
>
> I was planning to post on the list later today.
>
> > A nit: the @Inherited annotation "has no effect if [...] used to
> > annotate anything other than a class", and so can't be used for the
> > purpose described.
> >
>
> Yes, that is a complication.
>
> > Inheriting the diagnostic-suppression annotation would be a great way
> > to induce contributory heap pollution. All you have to do is extend a
> > class with a warning-suppressed varargs method, providing an unsafe
> > overriding implementation, and voila! Heap pollution without a
> > warning.
> >
>
> I was thinking that the spec for the annotation would allow compilers to
> issue errors if they could prove bad things actually happen in an
> implementation of a so annotated method.
>
> -Joe
>
>
More information about the coin-dev
mailing list