Open Bug 638281 Opened 14 years ago Updated 2 years ago

Deoptimize variables for late-binding function statements more precisely

Categories

(Core :: JavaScript Engine, defect)

defect

Tracking

()

People

(Reporter: dmandelin, Unassigned)

References

(Blocks 2 open bugs)

Details

(Whiteboard: [js:t] [js:perf])

Currently, for this code: function () { if (cond) { function f() { } ... } } We never generate GNAME ops for any variables in the '...' area. The reason is that |f| is not bound in the parser, so that if one of those variables were named 'f', it looks free, but it isn't safe to bind it to the global scope. But of course we don't have to deoptimize all variables, just those named f. We did the easy thing the first time around, on the assumption that this usage is rare, but it did show up in bug 594230. Instead, we should track the names that may collide and deoptimize only for them.
Blocks: 638282
Sadly, we're still not doing better here. For this code: var foo = 1; function a() { if (true) { function f() { } } foo; } a(); we're emitting the following bytecode for function `a`: 00000: 3 true {"interp": 1} 00001: 3 ifeq 11 (+10) {"interp": 1} 00006: 4 deffun <value> {"interp": 1} 00011: 6 name "foo" {"interp": 1} 00016: 6 pop {"interp": 1} 00017: 6 stop {"interp": 1} Removing the `if (true)`, we get this bytecode: 00000: 4 lambda <value> {"interp": 1} 00005: 4 setlocal 0 {"interp": 1} 00008: 4 pop {"interp": 1} 00009: 6 getgname "foo" {"interp": 1} 00014: 6 pop {"interp": 1} 00015: 6 stop {"interp": 1} However, given that we want to change away from late-bound functions to block-scoped ones in bug 585536, this should just go away. If we can pull off the change without breaking the web too hard, that is.
Depends on: 585536
Whiteboard: [js:t] [js:perf]
Assignee: general → nobody
No longer depends on: 585536
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.