Will the JavaScript environment be restored after changing the [[Prototype]] object?

So, I read the rejection of MDN and the warning , I read an excellent answer to the question , but I still want to find out. This question actually came from the answer I gave to another question here .

Let's say I decided to do a dirty business. Something that I will regret for the rest of my life. Something that will forever ruin my shame and dishonor my name. Purposeful, deliberate ending -

Well, that’s enough. In any case, here it is:

let proto = Object.getPrototypeOf(Function.prototype); Object.setPrototypeOf(Function.prototype, { iBetterHaveAGoodReasonForDoingThis : "Bacon!" }); //just to prove it actually worked let f = (function(){}); console.log(f.iBetterHaveAGoodReasonForDoingThis); // Quick, hide the evidence!! Object.setPrototypeOf(Function.prototype, proto); 

Basically, what I did there was a modification of the Function.prototype prototype, an object that affects almost all the pieces of JavaScript code that you could write. Then I changed it.

I wanted to illustrate the big changes in the prototype chain that would affect a lot of code and make a lot of optimizations go down. I do not expect that changing it will return anything (if anything, I expect this to degrade performance). I would like to know if this will be or not, but if that happens, it was not my intention.

I just want to know if the JavaScript environment after recovery can change and start optimizing again? Or will he just quit forever and run everything in deoptimized mode? Because of this, optimization will not be achieved? Can I hope that in the end, after a period of recovery, he will return to his normal state?

In the context, I'm talking about engines like the latest version of V8, not the primitive crap used by things like Internet Explorers. I understand that the answer may differ in different systems, but I hope that there is a commonality between them.

+8
performance javascript prototype v8 javascript-engine
source share
1 answer

V8 developer is here. This question has no easy answer.

Most of the optimizations will come back (of course, due to the extra processor time). For example, optimized code that needs to be thrown away will eventually be recompiled.

Some optimizations will be disabled forever. For example, the V8 skips certain checks when (and until) it knows that the prototype chains have not been removed. If he sees that the application modifies the prototype chains, it is safe from now on.

To make things even more complex, the details can and will change over time. (That's why there is little point in listing more specific circumstances here, sorry.)

Background:

There are many places in JavaScript where code can do a certain thing that the JavaScript engine should check, but most code doesn't. (Take, for example, the inheritance of missing elements from an array prototype: ['a', ,'c'][1] Array.prototype[1] = 'b' ['a', ,'c'][1] almost always returns undefined , unless someone has made Array.prototype[1] = 'b' or Object.prototype[1] = 'b' .) Thus, when creating optimized code for a function, the engine should select two options:

(A) Always check the item in question (in the example: go through the array prototype chain and check each prototype to see if it has an element in this index). Suppose that the execution of this code takes 2 units of time.

(B) It is optimistic to assume that prototypes of arrays have no elements and pass the test (in the example: don't even look at prototypes, just return undefined ). Let them say that it brings runtime up to a unit of time (twice as fast, yay!). However, to be true, the engine must now closely monitor the prototype chains of all arrays, and if any elements appear anywhere, all code based on this assumption must be found and thrown away at the cost of 1000 units of time.

Given this compromise, it makes sense that the engine first follows a quick but risky strategy (B), but when it fails even once, it switches to a safer strategy (A) to avoid risking paying a fine for 1000 time units again.

You can argue whether "even once" is the best threshold, or whether the site should receive 2, 3, or even more free passes before giving up (B), but that will not change the fundamental compromise.

+4
source share

All Articles