All About JS Engine and The Full Architecture of Google's v8

All About JS Engine and The Full Architecture of Google's v8

Table of Content

  • Basics

  • Architecture of v8

  • Some of Inbuilt Application Programming Interfaces in v8

Basics As we know that to run any JavaScript code a run time environment is always required without this runtime environment we can't run the JavaScript code. So every browser contains run time environment.

runtime.jpg

As we can see in the picture that we have multiple components in runtime environment as like JS Engine, Web API's, Event Loop, Call Back Queue, Micro Task Queue etc. JS Engine is known as the heart of JavaScript RunTime Environment.

JS Engine As the name pronouns JS Engine it's not a machine. It is a code which is written in low level language. The very first JS Engine was created in 1995 by Brendan Eich who was a developer at Netscape.This Engine was rudimentary interpreter.Now a days this JS Engine is known as Spider Monkey.

Different type of JS Engines Now a days here are many type of JS Engine which are Chrome v8, Deno, Spider Monkey, Chakra, Nitro etc. Chrome v8 is the most used JS Engine these days because it uses JIT(Just In Time) means it uses both interpretor and compiler at same time to optimize and run the code. Node.js also includes these v8 features in itself. So now we can say that In these days Javascript can be interpreted and compiled both at same time, it depends on the browser.

Architecture of v8

v8Engine.jpg

When a JS code is run through v8 Engine it is processed from three steps which are

  1. Parsing

  2. Compilation

  3. Execution

From above diagram we can understand that when JS Code goes to Parsing so before Parsing it will be converted into tokens.After that syntax parser will convert these tokens into AST(Abstract Syntax Tree). After this process AST will go to interpreter, interpreter will convert the code into byte code line by line. At that same time compiler will optimize the code which is required to be optimized. This process in which interpreter and compiler both works at same time is known as JIT(Just in time) Compilation, v8 uses Ignition as interpreter and Turbo fan as compiler at the same time so that the code execution process can be fastest. After this process code will be converted into Optimized Machine Code which will go into execution process and finally the code will be executed. Here are some forms of Optimization by compiler.

1.Inline Caching

2.Copy Elision

3.Inlining

Components of JS Engine JS Engine contains many components like Compiler,Interpreter,Garbage Collecter,Memory Heap and Call Stack etc.

Memory Heap Memory Heap is the place in which memory is assigned to all Javascript elements as like variables,functions etc.

Garbage Collector Garbage Collector Basically tries to free up memory space whenever it is possible. It uses the Mark & Sweep Algorithm to free up the space.

Call Stack Call Stack is used to manage execution of different type of execution context.Call Stack is also known as Execution Context Stack/Program Stack/Control Stack/Runtime Stack/Machine Stack etc.

Some of Inbuilt Application Programming Interfaces in v8

1. v8.cachedDataVersionTag() Method This is an inbuilt application programming interface of the v8 module which is used to get the version tag derived from the v8 version.This method does not have any parameter.

// accessing v8 module
const v8 = require('v8');

// Calling v8.cachedDataVersionTag()
tag = v8.cachedDataVersionTag();
console.log("Cache data version tag is "+ tag);

Output

Cache data version tag is 3525580503

2. v8.getHeapStatistics() Method This method is used to get statics about heap derived from the v8 version.This method also does not have any parameters.

// accessing v8 module
const v8 = require('v8');

// Calling v8.getHeapStatistics()
console.log(v8.getHeapStatistics());

Output

total_heap_size: 5001216,
  total_heap_size_executable: 524288,
  total_physical_size: 5001216,      
  total_available_size: 2194523824,  
  used_heap_size: 4195368,
  heap_size_limit: 2197815296,       
  malloced_memory: 254064,
  peak_malloced_memory: 100384,
  does_zap_garbage: 0,
  number_of_native_contexts: 1,
  number_of_detached_contexts: 0,
  total_global_handles_size: 8192,
  used_global_handles_size: 3040,
  external_memory: 325499

3. v8.getHeapSpaceStatistics() This method is used to get the statics about heap space derived from v8 module.This method also does not have any parameters.

// accessing v8 module
const v8 = require('v8');

// Calling v8.getHeapSpaceStatistics()
console.log(v8.getHeapSpaceStatistics());

Output

[
  {
    space_name: 'read_only_space',
    space_size: 176128,
    space_used_size: 170944,      
    space_available_size: 0,      
    physical_space_size: 176128   
  },
  {
    space_name: 'old_space',      
    space_size: 3137536,
    space_used_size: 3080976,     
    space_available_size: 80,     
    physical_space_size: 3137536  
  },
  {
    space_name: 'code_space',
    space_size: 368640,
    space_used_size: 333056,
    space_available_size: 0,
    physical_space_size: 368640
  },
  {
    space_name: 'map_space',
    space_size: 270336,
    space_used_size: 257912,
    space_available_size: 0,
    physical_space_size: 270336
  },
  {
    space_name: 'large_object_space',
    space_size: 0,
    space_used_size: 0,
    space_available_size: 0,
    physical_space_size: 0
  },
  {
    space_name: 'code_large_object_space',
    space_size: 0,
    space_used_size: 0,
    space_available_size: 0,
    physical_space_size: 0
  },
  {
    space_name: 'new_large_object_space',
    space_size: 0,
    space_used_size: 0,
    space_available_size: 1031072,
    physical_space_size: 0
  },
  {
    space_name: 'new_space',
    space_size: 1048576,
    space_used_size: 355224,
    space_available_size: 675848,
    physical_space_size: 1048576
  }
]

4.v8.serialize(value) Method This method is used to serialize any type of data into a buffer using default serializer.This method requires one parameter.

// accessing v8 module
const v8 = require('v8');

// Calling v8.serialize(value)
console.log(v8.serialize("Ved Dadhich"));

Output

<Buffer ff 0d 22 0b 56 65 64 20 44 61 64 68 69 63 68>

5. v8.deserialize(buffer) Method This method is used to deserialize a buffered value into JS value using default deserializer. This method also accepts one parameter.

// accessing v8 module
const v8 = require('v8');

// Calling v8.deserialize(value)
console.log(v8.deserialize(v8.serialize("Ved Dadhich")));

Output

Ved Dadhich