11. JavaScript Engines
Tags: javascript, webdev, beginners, programming
Published: 2022-01-31 06:33:47

## **Articles**

- [JavaScript Engines — Jen Looper](http://www.softwaremag.com/javascript-engines/) Done
- [Understanding V8’s Bytecode — Franziska Hinkelmann](https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775) bytecode
- [JavaScript essentials: why you should know how the engine works - Rainer Hahnekamp](https://medium.freecodecamp.org/javascript-essentials-why-you-should-know-how-the-engine-works-c2cc0d321553)
- [JavaScript engine fundamentals: Shapes and Inline Caches](https://mathiasbynens.be/notes/shapes-ics) Done
- [JavaScript engine fundamentals: optimizing prototypes](https://mathiasbynens.be/notes/prototypes) Done

---
## JS Engine
JS engine is a program that converts JS code into lower level or machine code that microprocessors can understand. **The goal of JS engine is to generate the most optimzied code in shortest time possible.**
### Uniqueness of JS engine
One interesting feature of Javascript is that JS is dynamic typing. It means that we don't have to specify the type of variable when we declare it.
``` jsx
let number = 17;
```
We didn't declared the variable `number` as an integer or number type. But JS engine dynamically converts it as a number as a machine code. So how does JS engine work?

---
## How it works
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/js-engine-pipeline.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>

- First, JS engine parses the source code, and generates the Abstract Syntax Tree(AST). 

- Then, based on AST, interpreter generates the bytecode and executes it. 
- While it executes the bytecode, if the function is 'hot', which means that it is used multiple times, it sends the profiling data to the optimizing compiler. 
- Based on the data from previous executions, optimizing compiler generates the optimized code which is executed faster than bytecode. 

- If the assumption is changed, it de-optimizes and goes back to interpreter.

### JIT(Just in time) Compilation

Often we call the JS engine does JIT compilation. It means that JS engine generates machine code during the run time, not ahead of time(AOT). So because of this, JS engine understands even we don't specify the type of variablesor objects. As I mentioned, JS engine compiles and executes together with the help of interpreter & optimizing compiler. 

On the other hand, in C++, C++ engine compiles and then executes. Which means that we should specify the type of varible, like this.
``` java
int number = 17;
```
### V8
In V8, interpreter is called 'ignition' and optimizing compiler is called 'turbofan'. This is an example of how V8 engine works in given source code.
``` jsx
let result = 0;
for (let i = 0; i < 4242424242; ++i) {
	result += i;
}
console.log(result);
```
V8 starts to run the soruce code with ignition and starts to generate and execute the bytecode. When the engine notice its 'hot'(because the same function is repeated over time), turbofan frontend starts to generate profiling data of given function and sends it to the turbofan. Turbofan starts to generate optimized code.

<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/pipeline-detail-v8.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>


---

## Different types of JS engines
There are lots of different types of JS engines according to browsers. 
<p align="center" style="color:gray">
  <img src="https://image.slidesharecdn.com/stateoftheartserver-sidejavascript-parisjs-110901091438-phpapp01/95/state-of-the-art-serverside-javascript-parisjs-12-728.jpg?cb=1317099335" style="padding: 0;margin:0; width: 600px">
  <a href= ""> </a>
</p>
It's good to have numerous JS engines because these engines would compete and eventually become better as time goes.

### Why do they differ?

But why are engines different each other? Because there isn't   a sole best solution. As I said earlier, the ultimate goal of JS engine is to generate the most optimized code as fast it can. In fact, there is **trade-off between generating code quickly, and executing code quickly**. 
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/tradeoff-startup-speed.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>
So some engines with more optimzing tiers, tend to focus on executing fast, while it takes long time to generate it. And engines with less optimizing tiers focuses on generating code quickly, while it takes more time to execute because it is less optimized

There's another trade-off that JS engines consider. 
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/tradeoff-memory.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>
More optimization takes more memory. So, trade-off between optimization and memory usage should be also considered.

---
## Object Optimization 
Objects are just dictionaries which key is string type. String kyes are mapped to something called "**property attributes**".
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/object-model.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>

### Property attributes

- Value: the value retuned by accessing property ex) object.x

- Writable: whether it can be reassigned

- Ennumerable: whether it can be used in loops
- Configurable: whether it is deleteable

We can get Property attributes by `Object.getownPropertydescript` API.

#### Problem
The problem of storing object this way is that if there are lots of objects, we should allocate memories for each objects, which is wasteful. So, JS engine uses unique mechanism for handling objects.

---

### Shapes
If objects has same properties, we call that objects have same 'shapes'.(`shapes` is synonym to `hidden clases`, `map`, `structure`.)
``` jsx
let object1 = {
  x: 1,
  y: 2
}

let object2 = {
  x: 5,
  y: 6
}
```
Object1 and object2 has same shape. 

JS engine uses this concept called `shape` internally, to handle objects in more optimized way.

#### Object <-> Shape
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/shape-1.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>

In object, only the values are stored and other property attributes are stored in shape. In shape, instead of the value, `offset` property is mapped to property of object. `offset` is the index where we can find the value according to the property. For example, for property `x`, we can find the value is the 0th place in object.

#### Same shape objects
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/shape-2.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>

In above exmaple, `a` and `b` has same shape. Instead of storing each property attributes to each objects, we store property attributes except value into shape. Using this mechanism, for 1000 objects for same shape, we need only one shape.which can save memory space.

---

### Adding property to object
What happens when we start with certain shape and add properties?
``` jsx
let object = {};
object.x = 5;
object.y = 6;
```
Something called transition chain occurs.
#### transition chain
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/shape-chain-2.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>

New shapes are introduced when we add new properties. If we want to find the value of propert `x`, we walk through the chain until we find the shape that has property `x`. Then we look for the offset, which is `0`. 0th value of Object `o` is 5. So, o.x = 5.

#### Still slow...
However, transition chain is still slow if there are multiple shapes included in chain. Time to find the value of property is O(n). So, to make it faster, we introduce `ShapeTable`. Shapetable is a dictionary which property maps to the corresponding shape. 
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/shapetable-2.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>
So, we are back to dictionaries. So why use shape if it's just more abstract?

---
### IC, Inline Caches
Here comes the IC. Ic is ingredient to make JS run fast and the main motivation for having shapes. 
#### How ICs work?
JS engine use ICs to memorize information on where to find properties on objects which can reduce the number of lookups.
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/ic-1.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>
As we run the above code, interpreter generates the bytecode. Inline Caches are stored in `get_by_id` and has two slots which are uninitialized. 
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/ic-2.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>
As we execute the code with the given object, `get_by_id` looks up the property `x` and finds the offset 0 and looks for the value. 
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/ic-3.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>
After we execute, IC stores and maps the shape and offset which the property was found.
<p align="center" style="color:gray">
  <img src="https://mathiasbynens.be/_img/js-engines/ic-4.svg" style="padding: 0;margin:0; width: 700px">
  <a href= ""> </a>
</p>

For same shape objects, with ICs, JS engine just first compares the shape, and load the value from memorized offset.

---
## Takeaways

1. Always initialize your object same shape as possible as you can. It boosts the optimization

2. JS engine generates machine code in runtime.