Open Bug 1511746 Opened 7 years ago Updated 2 years ago

Revisit how TryNotes and finally are handled

Categories

(Core :: JavaScript Engine, enhancement, P3)

enhancement

Tracking

()

People

(Reporter: tcampbell, Unassigned)

References

(Blocks 1 open bug)

Details

TryNote mechanism is currently complex, error-prone, and hard to optimize. The JS language and the SpiderMonkey codebase have both evolved since the mechanism was first added. The high-level problem that TryNotes solve is to determine which catch block (if any) that matches the current block scope. Within a frame, this is known statically at compile time. We currently store this static scope information out-of-line in the TryNotes array. One area of complexity is finally blocks and iterator closing cleanup code. This requires code to run when leaving a block scope (fallthrough, return, break, throw, etc) but that code is not considered to be inside the block. We need to be sure that if this cleanup code itself throws that we don't mistakenly catch it. We currently have two strategies for this: - For try-finally, we use JSOP_GOSUB to jump to the finally code. This code is under the correct TryNote that would apply. After running, we JSOP_RETSUB to run the final break or return. This is currently not Ion optimizable. - For for-of statements we need to close iterators in a process similar to finally blocks. Here we clone the required code where it needs to be and use special TryNotes to indicate that this code is not really part of the current scope. This has lead to bugs such as Bug 1480390. In Bug 965717, we propose fixing the performance of the finally case by cloning code. If we did this we'd need to have similar workarounds to for-of iterators. At the very least, we should have a better iterator helper for TryNotes to avoid bugs when new notes are added. Additionally, the types of notes we use can probably be make more consistent. We should have a way to describe that a region of bytecode should be considered to be in another location for the purpose of locating the containing try block. Eliminating GOSUB or otherwise finding a way to have Ion optimizations would be great. (These are some notes to start the discussion, I don't have a detailed solution worked out, but I think it is quite possible and not a huge amount of work)
Severity: normal → S3
Blocks: sm-frontend
Severity: S3 → N/A

We rewrote try-finally and eliminated GOSUB/RETSUB in bug 885514 and bug 1766730, which covers a good chunk of the problems here.

One trick that we used in bug 1766730 was to delay the generation of iterator-closing code until the end of the try block, which simplified control flow. It's possible that a similar trick could be used in for-of loops to eliminate the need for TryNoteKind::ForOfIterClose: instead of using try notes to indicate that code is not really part of the current scope, just generate it elsewhere (after we've finished the try-note region) and keep the try-notes simple. (I haven't thought this through carefully; it's possible that there's some reason this doesn't work.)

You need to log in before you can comment on or make changes to this bug.