search
HomeWeb Front-endJS TutorialUnderstand how JavaScript works, dive into the V8 engine and write optimized code

javascriptThe column introduces in-depth V8 engine and writing optimized code

Understand how JavaScript works, dive into the V8 engine and write optimized code

Related free learning recommendations: javascript( Video)

Overview

A JavaScript engine is a program or interpreter that executes JavaScript code. A JavaScript engine can be implemented as a standard interpreter, or as some form of just-in-time compiler that compiles JavaScript into bytecode.

List of popular projects that implement JavaScript engines:

  • V8 — Open source, developed by Google, written in C
  • Rhino — Managed by the Mozilla Foundation, open source, developed entirely in Java
  • SpiderMonkey — It is the first JavaScript engine to support Netscape Navigator and is currently used by Firefox
  • JavaScriptCore — Open source, sold as Nitro, developed by Apple for Safari
  • KJS — An engine for KDE, originally developed by Harri Porten for the KDE project Konqueror web browser development
  • Chakra (JScript9) — Internet Explorer
  • Chakra (JavaScript) Microsoft Edge
  • Nashorn, as part of OpenJDK, written by Oracle Java Language and Tools Group
  • JerryScript — A lightweight engine for the Internet of Things

Why was the V8 engine created?

The V8 engine built by Google is open source and written in c. This engine is used in Google Chrome, however, unlike other engines V8 is also used in the popular Node.js.
Understand how JavaScript works, dive into the V8 engine and write optimized code

V8 was originally designed to improve the performance of JavaScript execution in web browsers. To gain speed, V8 converts JavaScript code into more efficient machine code instead of using an interpreter. It compiles JavaScript code into execution-time machine code by implementing a JIT (Just-In-Time) compiler, just like many modern JavaScript engines such as SpiderMonkey or Rhino (Mozilla) do. The main difference here is that V8 does not generate bytecode or any intermediate code.

V8 had two compilers

Before the 5.9 version of V8 came out, the V8 engine used two compilers:

  • full-codegen — one Simple and very fast compiler that produces simple and relatively slow machine code.
  • Crankshaft - A more sophisticated (Just-In-Time) optimizing compiler that generates highly optimized code.

The V8 engine also uses multiple threads internally:

  • The main thread does what you would expect: gets the code, compiles it and executes it
  • There is also a separate thread for compilation, so the main thread can continue executing while the former optimizes the code
  • A Profiler thread that tells the runtime we spent a lot of time so Crankshaft can optimize them
  • Some threads handle the garbage collector

When JavaScript code is executed for the first time, V8 uses the full-codegen compiler to directly translate the parsed JavaScript into machine code without any Convert. This allows it to start executing machine code very quickly. Note that V8 does not use intermediate bytecode, eliminating the need for an interpreter.

When the code has been running for a while, the analysis thread has collected enough data to determine which method should be optimized.

Next, Crankshaft starts optimization from another thread. It converts JavaScript abstract syntax trees into a high-level static single allocation (SSA) representation called Hydrogen and attempts to optimize the Hydrogen graph, most optimizations are done at this level.

Inline code

The first optimization is to inline as much code as possible ahead of time. Inlining is the process of replacing the call site (the line of code that calls the function) with the body of the called function. This simple step allows the following optimizations to make more sense.

Understand how JavaScript works, dive into the V8 engine and write optimized code

Hidden Classes

JavaScript is a prototype-based language: classes and objects are not created using a cloning process. JavaScript is also a dynamic programming language, which means that properties can be easily added or removed from an object after instantiation.

Most JavaScript interpreters use a dictionary-like structure (based on a hash function) to store the location in memory of object property values. This structure makes retrieving property values ​​in JavaScript faster than in Java or C# Computational costs are higher in non-dynamic programming languages.

In Java, all object properties are determined by a fixed object layout before compilation, and cannot be added or removed dynamically at runtime (of course, C# has dynamic typing, which is another topic).

Thus, attribute values ​​(or pointers to these attributes) can be stored in memory as contiguous buffers, with fixed offsets between each buffer. The length of the offset can be easily determined based on the attribute type, while in You can change property types at runtime which is not possible in JavaScript.

Because using a dictionary to find the location of an object's properties in memory is very inefficient, V8 uses a different approach: hidden classes. Hidden classes work similarly to fixed objects (classes) used in languages ​​like Java, except that they are created at runtime. Now, let's look at their actual example:

Understand how JavaScript works, dive into the V8 engine and write optimized code

Once the "new Point(1,2)" call occurs, V8 will create a hidden named "C0" kind.

Understand how JavaScript works, dive into the V8 engine and write optimized code

No properties have been defined for Point, so "C0" is empty.

Once the first statement "this.x = x" is executed (within the "Point" function), V8 will create a second hidden class named "C1", which is based on "C0" . "C1" describes the location in memory (relative to the object pointer) where property x can be found.

In this case, "x" is stored at offset 0, which means when considering the point object in memory as a contiguous buffer, the first offset will correspond to the attribute "x" . V8 will also update "C0" with a "class transformation" which states that if the attribute "x" is added to the point object, the hidden class should switch from "C0" to "C1". The hidden class of the point object below is now "C1".

Understand how JavaScript works, dive into the V8 engine and write optimized code

#Every time a new property is added to an object, the old hidden class is updated with a transformation path pointing to the new hidden class. Hidden class casts are important because they allow hidden classes to be shared between objects created in the same way. If two objects share a hidden class and the same property is added to them, the transformation will ensure that both objects receive the same new hidden class and all the optimization code that comes with it.

The same process is repeated when the statement "this.y = y" is executed (inside the "Point" function, after the "this.x = x" statement).

A new hidden class named "C2" will be created. If a property "y" is added to a Point object (which already contains the property "x"), a class transformation will be added to "C1" , then the hidden class should be changed to "C2", and the hidden class of the point object should be updated to "C2".

Understand how JavaScript works, dive into the V8 engine and write optimized code

Hidden class conversion depends on the order in which properties are added to the object. Take a look at the following code snippet:

Understand how JavaScript works, dive into the V8 engine and write optimized code

Now, assume that for p1 and p2, the same hidden class and transformation will be used. So, for "p1", first add attribute "a", then add attribute "b". However, "p2" is assigned "b" first, then "a". Therefore, "p1" and "p2" end up with different hidden categories due to different transformation paths. In this case it is much better to initialize the dynamic properties in the same order so that the hidden class can be reused.

Inline caching

V8 utilizes another technique for optimizing dynamically typed languages ​​called inline caching. Inline caching relies on the observation that repeated calls to the same method tend to occur on the same type of object. An in-depth explanation of inline caching can be found here.

The general concept of inline caching will be discussed next (if you don’t have time to go through the in-depth understanding above).

So how does it work? V8 maintains a cache of object types passed as arguments in recent method calls and uses this information to predict object types passed as arguments in the future. If V8 could predict the type of object passed to a method well enough, it could bypass the process of how to access the object's properties and instead use stored information from previous lookups to the object's hidden class.

So how are the concepts of hidden classes and inline caching related? Whenever a method is called on a specific object, the V8 engine must perform a lookup of that object's hidden class to determine the offset at which to access the specific property. After two successful calls to the same hidden class, V8 omits the lookup of the hidden class and simply adds the property's offset to the object pointer itself. For all next calls to this method, the V8 engine assumes that the hidden class has not changed and jumps directly to the memory address of the specific property using the offset stored from the previous lookup. This greatly improves execution speed.

Inline caching is also why it is important for objects of the same type to share hidden classes. If you create two objects of the same type and different hidden classes (as we did in our previous example), V8 will not be able to use inline caching because even though the two objects are of the same type, their corresponding hidden classes are Its properties are assigned different offsets.

Understand how JavaScript works, dive into the V8 engine and write optimized code

The two objects are basically the same, but the "a" and "b" properties are created in a different order.

Compile to machine code

Once the Hydrogen graph is optimized, Crankshaft reduces it to a lower-level representation called Lithium. Most Lithium implementations are architecture specific. Register allocation often occurs at this level.

Finally, Lithium is compiled into machine code. Then there is OSR: on-stack replacement. Before we start compiling and optimizing an explicit long-running method, we might run stack replacement. V8 doesn't just slowly perform stack replacement and start optimizing again. Instead, it converts all the context we have (stack, registers) to switch to the optimized version during execution. This is a very complex task, considering that among other optimizations, V8 initially inlines the code. The V8 isn't the only engine that can do it.

There is a safety measure called deoptimization that does the opposite conversion and returns unoptimized code assuming the engine is invalid.

Garbage Collection

For garbage collection, V8 uses the traditional mark-and-sweep algorithm to clean up the old generation. The marking phase should stop JavaScript execution. To control GC costs and make execution more stable, V8 uses incremental marking: instead of walking the entire heap and trying to mark every possible object, it just walks a portion of the heap and then resumes normal execution. The next GC stop will continue where the previous heap walk left off, which allows for a very brief pause during normal execution, as previously mentioned the scan phase is handled by a separate thread.

How to write optimized JavaScript

  1. Order of object properties: Always instantiate object properties in the same order so that hidden classes and subsequent optimizations can be shared code.
  2. Dynamic properties: Because adding properties to an object after instantiation will force a hidden class change and slow down the execution of all methods optimized by the previously hidden class, it is important to All object properties are assigned in the constructor.
  3. Method: Code that executes the same method repeatedly will run faster than code that only executes multiple different methods once (due to inline caching).
  4. Array: Avoid sparse arrays, where the key values ​​are not self-increasing numbers, and sparse arrays that do not store all elements are hash tables. Accessing elements in such arrays is expensive. Also, try to avoid preallocating large arrays. Better to grow on demand. Finally, don't delete elements from the array, as this will make the keys sparse.
  5. Tag Value: V8 uses 32 bits to represent objects and values. Since the value is 31 bits, it uses one bit to distinguish whether it is an object (flag = 1) or an integer called SMI (SMall Integer) (flag = 0). Then, if a number is larger than 31 digits, V8 will box the number, turn it into a double, and create a new object to hold the number. Use 31-bit signed numbers whenever possible to avoid expensive boxing operations on JS objects.

Ignition and TurboFan

With the release of V8 5.9 earlier in 2017, a new execution pipeline was introduced. This new pipeline enables greater performance gains and significant memory savings in real JavaScript applications.

The new execution flow is built on Ignition (V8's interpreter) and TurboFan (V8's latest optimizing compiler).

Since the release of V8 5.9, as the V8 team has struggled to keep up with new JavaScript language features and the optimizations these features require, the V8 team has no longer used full-codegen and Crankshaft (since 2010) Serviced by V8 Technology).

This means that V8 will have a simpler and more maintainable architecture overall.

Understand how JavaScript works, dive into the V8 engine and write optimized code

These improvements are just the beginning. The new Ignition and TurboFan pipelines pave the way for further optimizations that will improve JavaScript performance and shrink V8’s footprint in Chrome and Node.js for years to come.

Related free learning recommendations: php programming (video)

The above is the detailed content of Understand how JavaScript works, dive into the V8 engine and write optimized code. For more information, please follow other related articles on the PHP Chinese website!

Statement
This article is reproduced at:segmentfault. If there is any infringement, please contact admin@php.cn delete
Python vs. JavaScript: The Learning Curve and Ease of UsePython vs. JavaScript: The Learning Curve and Ease of UseApr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python vs. JavaScript: Community, Libraries, and ResourcesPython vs. JavaScript: Community, Libraries, and ResourcesApr 15, 2025 am 12:16 AM

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.

From C/C   to JavaScript: How It All WorksFrom C/C to JavaScript: How It All WorksApr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

JavaScript Engines: Comparing ImplementationsJavaScript Engines: Comparing ImplementationsApr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

Beyond the Browser: JavaScript in the Real WorldBeyond the Browser: JavaScript in the Real WorldApr 12, 2025 am 12:06 AM

JavaScript's applications in the real world include server-side programming, mobile application development and Internet of Things control: 1. Server-side programming is realized through Node.js, suitable for high concurrent request processing. 2. Mobile application development is carried out through ReactNative and supports cross-platform deployment. 3. Used for IoT device control through Johnny-Five library, suitable for hardware interaction.

Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Building a Multi-Tenant SaaS Application with Next.js (Backend Integration)Apr 11, 2025 am 08:23 AM

I built a functional multi-tenant SaaS application (an EdTech app) with your everyday tech tool and you can do the same. First, what’s a multi-tenant SaaS application? Multi-tenant SaaS applications let you serve multiple customers from a sing

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration)Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

JavaScript: Exploring the Versatility of a Web LanguageJavaScript: Exploring the Versatility of a Web LanguageApr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
1 months agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

Dreamweaver Mac version

Dreamweaver Mac version

Visual web development tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor