javascriptprototypev8javascript-engine

Why is an inline cache for retrieving property from an object invalidated whenever someone changes any prototype above it, not below it?


I'm reading Mathias and Benedikt's article JavaScript engine fundamentals: optimizing prototypes. The article says:

This ValidityCell is invalidated whenever someone changes the associated prototype or any prototype above it.

I can't understand why the cache was invalidated when the prototypes above were changed.

For example, given a prototype chain:

kitty ---> Cat.prototype ---> Animal.prototype ---> Object.prototype

And a method eat stored in Animal.prototype.eat.

If the code tries to retrieve a method kitty.eat(), why will its cache be invalidated when the Object.prototype is mutated, not when Cat.prototype is mutated?

kitty.eat(); // While executing, the engine makes an IC for Animal.prototype.eat

Object.prototype.x = 0; // Should not have any effect on the chain from kitty to Animal.prototype?

kitty.eat(); // But the cache is invalidated so we need to traverse the chain to find `eat` again?

Solution

  • The ValidityCell represents the validity of the entire inherited shape, of the associated prototype and any prototype above it, not just for a single specific property. It doesn't matter that kitty.eat still refers to the same method: kitty.x now needs to resolve to a different value than before you messed with Object.prototype, and they share the same prototype validity (of kitty's shape).