ext Oliver Hunt wrote:
This is quite a lot of complexity for very little real world win. You should never use |with|.
Here's the problem:
[...] Yep, makes sense, thanks for the example.
With V8 version 2.2.3.2 the eval doesn't have any performance impact.
I would check with eval not being a static string -- it would be trivial (albeit relatively pointless) to detect an eval that wouldn't introduce local variables if the input is a string.
Hehe, indeed... a = 2; (function(code) { eval(code); (function() { for (var i = 0; i < 100000; ++i) { a; a; a; a; a; a; a; a; } })(); })(String.fromCharCode(0x76, 0x61, 0x72, 0x20, 0x63, 0x3D, 0x34)); // var c=4 5x slowdown in V8 now due to the eval, about the same as with jsc.
You can't repatch to resolve_global because your function maybe called multiple times, and just because the first time you succeed doesn't mean you will the next time so you need additional opcodes. There'd also be no reason to limit this just to global resolution as the special op_resolve_global logic is purely to avoid walking the scope chain, and if you're trying to be fast in the presence of |eval| you have to check that the |eval| has not actually done anything in each effected level in the scope chain. So you'd want something like
op_resolve_with_stupid dst, levelsUpScopeChain, offset, propertyName
Once again this feels like optimising stupid behaviour however.
Yeah, the complexity doesn't seem warranted. Any way to add caching in op_resolve, e.g. could it cache if the property is found in the Global Object (last scope object)? That could speed up the eval case quite a bit; there would still be a call to the activation object's getPropertySlot() every time, but the call to Global Object would be avoided (basically dynamic fallback to resolve_global). Regards, Kent