How Does Chrome's V8 Engine Actually Work?
Mainak Chattopadhyay
Posted on November 29, 2023
v8 of Google has Interpreter called Ignition, a compiler called Turbo Fan and garbage collector called Orinoco
- JS runs literally everywhere from smart watch to robots to browsers because of Javascript Runtime Environment (JRE).
- JRE is like a big container which has everything which are required to run Javascript code.
- JRE consists of a JS Engine (β€οΈ of JRE), set of APIs to connect with outside environment, event loop, Callback queue, Microtask queue etc.
- Browser can execute javascript code because it has the Javascript Runtime Environment.
- ECMAScript is a governing body of JS. It has set of rules which are followed by all JS engines like Chakra(Edge), Spidermonkey(Firefox)(first javascript engine created by JS creator himself), v8(Chrome)
- Javascript Engine is not a machine. Its software written in low level languages (eg. C++) that takes in hi-level code in JS and spits out low level machine code.
- Code inside Javascript Engine passes through 3 steps : Parsing, Compilation and Execution
- Parsing - Code is broken down into tokens. In "let a = 7" -> let, a, =, 7 are all tokens. Also we have a syntax parser that takes code and converts it into an AST (Abstract Syntax Tree) which is a JSON with all key values like type, start, end, body etc (looks like package.json but for a line of code in JS. Kinda unimportant)(Check out astexplorer.net -> converts a line of code into AST).
- Compilation - JS has something called Just-in-time(JIT) Compilation - uses both interpreter & compiler. Also compilation and execution both go hand in hand. The AST from previous step goes to interpreter which converts hi-level code to byte code and moves to execeution. While interpreting, compiler also works hand in hand to compile and form optimized code during runtime. Does JavaScript really Compiles? The answer is a loud YES. More info at: Link. JS used to be only interpreter in old times, but now has both to compile and interpreter code and this make JS a JIT compiled language, its like best of both world.
- Execution - Needs 2 components ie. Memory heap(place where all memory is stored) and Call Stack. There is also a garbage collector. It uses an algo called Mark and Sweep.
Additional Information -
The Mark-and-Sweep algorithm is a garbage collection algorithm used in computer programming to automatically reclaim memory that is no longer in use or referenced by the program. It is one of the fundamental techniques for memory management in languages that do not use manual memory management like C or C++. The algorithm consists of two main phases: marking and sweeping.
-
Mark Phase:
- The algorithm begins by traversing the entire memory heap, starting from the roots (e.g., global variables, local variables, and registers), and marking all the objects that are reachable and still in use.
- It identifies and marks objects that are reachable by following references or pointers from the root set.
-
Sweep Phase:
- After the marking phase, the algorithm sweeps through the entire memory heap again, deallocating memory that was not marked in the previous phase.
- Unmarked objects are considered as garbage, meaning they are no longer accessible or needed by the program.
- The memory occupied by these unreferenced objects is then freed up and made available for future use.
The Mark-and-Sweep algorithm has some advantages and disadvantages:
Advantages:
- It can handle circular references, where a group of objects reference each other in a cycle, as it relies on reachability rather than reference counting.
- It reclaims all unreachable memory, preventing memory leaks.
Disadvantages:
- It may introduce pause times during the collection process, as it requires stopping the execution of the program temporarily to perform the collection.
- Fragmentation can occur in the memory heap as a result of the non-contiguous layout of the reclaimed memory.
While the Mark-and-Sweep algorithm is a classic garbage collection technique, there are other algorithms like generational garbage collection and incremental garbage collection, each with its own set of trade-offs and optimizations.
Inline caching is a technique used in computer programming and language runtime environments, particularly in the context of dynamic dispatch and polymorphism. It aims to optimize method or function calls by caching information about the types of objects involved in the call, reducing the overhead associated with dynamic dispatch.
Here's how inline caching typically works:
-
First Call:
- When a method or function is called with a specific set of object types, the runtime system records information about the types involved in the call.
- This information is cached or "inlined" directly in the code that performs the method dispatch.
-
Subsequent Calls:
- On subsequent calls to the same method or function with the same or compatible types, the cached information is used to skip the dynamic dispatch mechanism.
- Instead of going through the usual process of dynamic type resolution and method lookup, the cached information is directly used to determine the appropriate method to invoke.
Inline caching is particularly effective in situations where the types involved in method calls do not change frequently. It reduces the overhead associated with dynamic dispatch and can significantly improve the performance of certain code paths.
This technique is often used in object-oriented languages with dynamic dispatch, such as JavaScript, Python, or Smalltalk. In these languages, objects can have multiple types, and the correct method to call may depend on the actual runtime type of an object.
Inline caching is closely related to the concept of polymorphic inline caching (PIC), where the caching mechanism is designed to handle multiple types efficiently. Polymorphic inline caching is an extension of inline caching that allows for handling a varying number of types associated with a method call.
The effectiveness of inline caching depends on the usage patterns of the program. If the types involved in method calls are stable or change infrequently, the caching mechanism can significantly improve performance by avoiding the overhead of repeated dynamic dispatch.
Posted on November 29, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.