archives

« Bugzilla Issues Index

#4268 — Presence of iterator.close checked too late


IIRC, we decided that the presence of a .close method on an iterator should be checked upon _entry_ into a loop. The current spec checks it upon abnormal _exit_ from the loop, by invoking IteratorClose (e.g. for-of loops in 13.6.4.13, but also elsewhere).

Because it is usually impossible to tell upfront that a .close method cannot be added during iteration, this requires that virtually _every_ iterator loop has to be executed inside an implicit try-finally, which is a significant overhead, even for the vast majority of cases that don't care about .close. In the interest of competitive performance, especially for for-of loops, we should change that semantics the way we discussed.


(In reply to Andreas Rossberg from comment #0)
> IIRC, we decided that the presence of a .close method on an iterator should
> be checked upon _entry_ into a loop.

We did? Where is that documented? Are you sure there weren't subsequent discussions?

The current spec checks it upon
> abnormal _exit_ from the loop, by invoking IteratorClose (e.g. for-of loops
> in 13.6.4.13, but also elsewhere).
>
> Because it is usually impossible to tell upfront that a .close method cannot
> be added during iteration, this requires that virtually _every_ iterator
> loop has to be executed inside an implicit try-finally, which is a
> significant overhead, even for the vast majority of cases that don't care
> about .close. In the interest of competitive performance, especially for
> for-of loops, we should change that semantics the way we discussed.

It's also impossible to tell whether a .close method isn't deleted during iteration.

Perhaps it's time to implement low cost if not triggers try blocks?


(In reply to Allen Wirfs-Brock from comment #1)
> (In reply to Andreas Rossberg from comment #0)
> > IIRC, we decided that the presence of a .close method on an iterator should
> > be checked upon _entry_ into a loop.
>
> We did? Where is that documented? Are you sure there weren't subsequent
> discussions?

I'm not aware of any subsequent discussions, but I might well have missed some. I do remember that checking for it early was the anodyne put on the table that convinced me to not block the feature. I regret not having ensured that this is recorded explicitly.

> The current spec checks it upon
> > abnormal _exit_ from the loop, by invoking IteratorClose (e.g. for-of loops
> > in 13.6.4.13, but also elsewhere).
> >
> > Because it is usually impossible to tell upfront that a .close method cannot
> > be added during iteration, this requires that virtually _every_ iterator
> > loop has to be executed inside an implicit try-finally, which is a
> > significant overhead, even for the vast majority of cases that don't care
> > about .close. In the interest of competitive performance, especially for
> > for-of loops, we should change that semantics the way we discussed.
>
> It's also impossible to tell whether a .close method isn't deleted during
> iteration.

Sure, but that doesn't matter -- in the few cases where .close is present initially it's fine to go on a slower path. What counts is that the extra cost of dealing with .close is not imposed on all the other uses.

> Perhaps it's time to implement low cost if not triggers try blocks?

We have recently done so in Turbofan. But try-finally is still not free, and I doubt it can ever be in JS. OTOH, a late added .close is an edge case of absolutely zero practical value, wouldn't you agree?


deferred for ES7 discussion