📜 ⬆️ ⬇️

Basics of JavaScript engines: common forms and inline caching. Part 2

Hello! The course “Security of Information Systems” starts in 2 weeks, so today we want to publish the second part of the article, the publication of which is dedicated to its launch. Read the first part here . So, let's begin.

Inline Caches (ICs)

The basic idea behind the forms is the concept of inline caches or ICs. They are a key component of fast javascript! JavaScript engines use ICs to remember information about where to find properties of objects in order to reduce the amount of costly searches.
')


We have a getX function that accepts an object as input and loads the x property from it:

 function getX(o) { return ox; } 

If we run this function in the JSC, we get the following bytecode:



The first get_by_id instruction loads the 'x' property from the first argument (arg1) and stores the result in loc0 . The following statement returns what we stored in loc0 .
The JSC also embeds inline cache into the get_by_id instruction, which consists of two uninitialized slots.



Now let's assume that we call getX along with the object { x: 'a' } . We already know that this object has the 'x' property, and its form stores the offset and attributes of the property. When you execute a function for the first time, the get_by_id instruction get_by_id for the 'x' property and finds that its value is stored at offset 0.



The IC embedded in the get_by_id instruction remembers the form and offset where the property was found.



For subsequent launches, IC only needs to compare the form, and if it is the same as before, simply load the value from the memorized offset. In particular, if the JavaScript engine sees objects with a form that it recorded earlier, it no longer needs to ask for information about these properties at all - instead, you can completely skip the expensive search for information about properties. This is much faster than spending time searching for properties each time.

Efficient storage of arrays

For arrays, it is common practice to store array indices. The values ​​of such properties are called array elements. It would be wasteful to store property attributes for each element of an array in a separate array. Instead, JavaScript engines rely on the fact that properties indexed in an array are writable (writable), enumerable and default settings (configurable), and also store the elements of the array separately from other named properties.

Consider the given array:

 const array = [ '#jsconfeu', ]; 

The engine stores an array of unit length and points to a form that contains an offset and attributes for the 'length' property.



This is similar to what we have seen before ... But where are the values ​​of the elements of the array stored?



Each array has a separate storage of backup elements (elements backing store), which contains all the values ​​of the properties indexed by the array. The JavaScript engine does not need to store any property attributes for array elements, since they are usually available for writing (writable), enumerating (enumerable) and customizing (configurable).

And what will happen if they suddenly turn out to be inaccessible for configuration? What if you change the attributes of an array element property?

 // Please don't ever do this! const array = Object.defineProperty( [], '0', { value: 'Oh noes!!1', writable: false, enumerable: false, configurable: false, } ); 

The code snippet at the top defines a property called '0' (it turns out to be the array index), it changes the attribute values ​​to non-fixed ones.

In such extreme cases, the JavaScript engine represents all of the backup element storage as a dictionary that matches array indices with property attributes.



Even if only one element of the array has non-default attributes, all the backup item storage goes into a slow and inefficient mode of operation. Avoid Object.defineProperty in array indices! (I don’t even know why you should use it in principle. It seems strange and irrational.)

findings

We learned how JavaScript engines store objects and arrays, and how forms and inline caches help optimize various operations. Also in this article we want to give some practical tips for javascript that can help increase the performance of your code:


Now the article can be considered complete. According to the established tradition, we are waiting for your comments and invite you to sign up for an open webinar on the course “Security of Information Systems”, which already today will be conducted by a well-known virus analyst and part-time teacher - Alexander Kolesnikov .

Read the first part.

Source: https://habr.com/ru/post/447220/


All Articles