On Dec 8, 2017, at 7:13 AM, Claes Redestad <claes.redes...@oracle.com> wrote: > > http://cr.openjdk.java.net/~redestad/8193128/open.03/ > + for (int i = elements.length - 1; i > 0; i--) {
There's an OBOE in this line; should be i >= 0. Errors like this are a risk of hand-specializing code. It's probably worth it here, but it's still a risk. For immutable lists, it would be reasonable to recode the generic algorithms to use for-loops with integer indexes and get(int) access. That will remove the unused generality of iterators, and keep only the abstraction across get(). The benefits of customized inlining (to fold up the funny specialized get methods) can probably be obtained like this: class AbsImmList { @ForceInline int indexOf(Object x) { for (int i = 0, s = size(); i < s; i++) if (x.equals(this.get(i))) return i; } } final class List12 { int indexOf(Object x) { return super.indexOf(x); } // specialize size/get } final class ListN { int indexOf(Object x) { return super.indexOf(x); } // specialize size/get } The optimization of the funny 1/2 loop for List12 should unfold into the same code you'd write by hand; if not it's a bug to fix in C2. Likewise for the loop in ListN. — John P.S. If you are going to hand-specialize, it might be easier on the optimizer if you would add in this line as needed: final E[] elements = this.elements; // cache field Usually C2 gets the same answer, but not always, since final fields are not fully trustable, and "might" (in some hypothetical system which C2 can't rule out) change over a call to Object::equals. OTOH, generic coding as above is preferable, and we can fix C2 to hoist the @Stable elements field if it doesn't already. P.P.S. Why does ListN have arity 1 and arity 2 constructors?