JavaScript Engine & v8 Architecture

Photo by Gab on Unsplash

JavaScript Engine & v8 Architecture

JavaScript is a vast language with no bar on the devices it can run. It can run on browsers, servers, fans, coolers etc. But how? How can a cooler or an electric fan compile and execute javascript? Bet you thought that javascript can only run on browsers. Let's dive deep into why and how it happens and also understand the v8 architecture at the end. If you don't know what a v8 Engine is, then stick to the end of this blog.

Javascript will run anywhere where there is a javascript runtime environment available. The javascript runtime environment consists of a JS Engine, an API allocation, an event loop, a callback queue and a microtask queue. The JS Engine has a memory space and a call stack and it runs like how a regular JS code works i.e. formation of execution context with functions, variables taking up memory space and getting pushed in stack leading to the formation of other execution contexts and finally popping out of stack after being executed.

Reminder: JS engine is not a machine but the code written to run javascript.

How does a JS engine work?

The javascript engine executes the code in three important steps after the code is sent through it. They are:

  1. Parsing

  2. Compilation

  3. Execution

  • Parsing: The code sent through the engine first undergoes parsing i.e. gets broken down into well-defined pieces called tokens.
const foo = "Hello world!";
// here "const" "foo" "=" "Hello world!" are given tokens.

These tokens are defined in the AST (Abstract Syntax Tree). The AST for the above line of code is given below:

{
  "type": "Program",
  "start": 0,
  "end": 27,
  "body": [
    {
      "type": "VariableDeclaration",
      "start": 0,
      "end": 27,
      "declarations": [
        {
          "type": "VariableDeclarator",
          "start": 6,
          "end": 26,
          "id": {
            "type": "Identifier",
            "start": 6,
            "end": 9,
            "name": "foo"
          },
          "init": {
            "type": "Literal",
            "start": 12,
            "end": 26,
            "value": "Hello world!",
            "raw": "\"Hello world!\""
          }
        }
      ],
      "kind": "const"
    }
  ],
  "sourceType": "module"
}
  • Compilation & Execution: Compilation in the javascript engine works interestingly.

    Javascript is one of the few frameworks that are both interpreted and compiled simultaneously.

    Interpretation: The code is executed line by line.

    Compilation: The code is converted to an optimized version by the compiler and then sent for execution.

    So, the JS engine undergoes something known as Just-In-Time(JIT) compilation.

  • In javascript, the code uniquely undergoes execution. Javascript code written on being converted to an AST is interpreted and executed.

  • Now, here's the catch! The code while undergoing interpretation also undergoes compilation simultaneously while getting executed on the other hand making the respective executed code to be the most optimized code. The compiler follows inlining and Copy elision algorithms to optimize the code.

  • The engine also consists of a garbage collector which clears the memory heap from time to time using Mark and Sweep algorithm.

Talking about the v8 javascript engine, it has an interpreter called Ignition and a compiler known as Turbofan.

The v8 engine workflow:

Javascript Source Code -> Parser -> Abstract Syntax Tree -> Interpreter (Ignition) -> Compiler (Turbofan) <-> Machine optimized code <-> Bytecode

Right now Google has the most powerful javascript engine running on Chrome i.e. the v8.

That's it for this blog. If you like what you read, do like this blog and feedback in comments is always welcome.

Follow me on Twitter and Hashnode for more such content.

Till then signing off... Godspeed!