Frontend capability model-V8 JS engine and frontend-v8js Engine

Source: Internet
Author: User

Frontend capability model-V8 JS engine and frontend-v8js Engine
I. webkit kernel and V8
In chrome, webkit is used for html Rendering and v8 is used as the js engine. Although Chrome and Webkit are both open-source, Chrome is always at a distance from Webkit. Chrome encapsulates a layer called WebKit Glue on WebKit. In the Glue layer, most types of structures and interfaces are similar to WebKit. In Chrome, relying on WebKit components, only Webkit Glue layer interfaces are called, rather than WebKit types. According to chrome's own documents, although we use webkit to implement page rendering, the coupling with WebKit is greatly reduced through the webkit Glue middle layer, blink is a good alternative to webkit rendering engine. V8 gives full play to the knowledge gained by R & D of HotSpot and Strongtalk.
2. android webkit
Android webkit includes java layer and c layer. The two are communicated by Java Native Interface, as shown in the following figure:


Iii. WebViewWebView is a view module at the Java layer. html pages inserted in Android Native apps are usually built on WebView, including browser and request processing. This is why WebView has a higher output rate than Android Webkit. Many Native apps use WebView to render html pages when developing some modules with a higher update rate, to facilitate content updates.
There is also a WebView module in layer C. The WebView module in layer C initializes and constructs a WebView object, and assigns it to the WebView in the Java layer. Then the two can communicate.

Iv. Comparison of Safari and chrome kernels


There were some historical reasons for the early slowness of the js engine. At that time, only a few animations and interactive operations were used on webpages. browser Development gave priority to improving the rendering engine speed. js processing speed was not very important. With the emergence of rich applications, js dependencies and requirements are getting higher and higher, and performance problems are once again called the most concern of network application developers.

V. Differences between javascript and c ++ and java
1) language problems
C ++ and Java adopt static type (static typing ). When the code is compiled, the variable type is declared, but JS needs to check the data type during execution, so the static type has a performance advantage.
2) differences between object variables and methods in js, c ++, and java
It is illustrated by a legend:



C ++ and Java Process object variables and methods, and store the displacement values in the array with their names. You will know the type of the variable to be accessed in advance, so you can access the variables and methods only by array and displacement.
In js, some objects have their own attributes, methods, and other tables. Each time a program accesses a property or call method, it must check the object type and perform appropriate processing.
Many JavaScript Engines use hash tables to access attributes and find methods. In other words, each time you access a property or find a method, a string is used as the key to search for an object hash table, for example:



Internal javascript processing during attribute access in the figure: Use the string foo of the object x hash table as the keyword to search for foo content. Searching for a hash table is a continuous action, including determining the position in the array from the hashing value, and then checking whether the key value (key) of the position is equal. Then, we can compare the data array that can be directly read by displacement. It is time-consuming to use this method to access the data.
Use other dynamic languages, such as Smalltalk and Ruby. These languages are also used to search for hash tables, but they use classes to shorten the search time. However, Js does not have a class. Except for Numbers, which indicates the numeric value, Strings as a string, and other basic types, the remaining objects are of the object type. Classes cannot be declared, so explicit types cannot be used to accelerate processing.
Vi. V8 engine acceleration technology
The elasticity of js allows you to add or delete attributes and methods on objects at any time. It is generally believed that dynamic languages are more difficult to accelerate than static languages. V8 uses several technologies to achieve acceleration:
1) JIT compilation (JIT Compile): machine language generation without bytecode
From a performance perspective, V8 has four main features. First, it generates machine languages by calling just-in-time (JIT) compilation methods during execution. This is a common method to improve the speed of interpretation. This method can also be found in java. V8 implements this technology earlier than the SpiderMonkey JavaScript Engine in Firefox, or competing engines such as Safari's JavaScriptCore.
The v8 JIT compiler does not generate intermediate codes when generating machine languages. For example, the Java compiler first converts the original code into a class file represented by a virtual intermediate language (bytecode ). The Java compiler and bytecode compiler generate bytecode rather than machine languages. The Java VM interprets bytecode in sequence. This execution mode is called the bytecode interpreter ). The SpiderMonkey of Firefox has an internal bytecode compiler and a bytecode interpreter, which converts the Javascript original code into its own characteristic bytecode for execution. For example:


The program language system first converts the original code into an abstract syntax tree (AST) using a syntax analyzer ). There are several ways to deal with it. The bytecode compiler compiles the abstract syntax tree into intermediate code and then executes it in the compiler. For example, Java JIT and other mixed modes compile Part of the intermediate code into a machine language to improve processing performance. Chrome does not use intermediate code. JIT compiles machine languages directly from the abstract syntax tree. There is also an abstract syntax tree interpreter that directly parses the abstract syntax tree.
In fact, Java VM currently uses a HotSpot-based JIT compiler. It acts as a bytecode interpreter to parse code, convert frequently executed code blocks into machine languages, and then execute them. This is the hybrid mode (hybrid model ).
The bytecode interpreter and mixed mode have the advantages of simplicity and excellent portability. As long as it is the source code that the engine can compile, it can execute bytecode on any CPU architecture, which is precisely why this technology is called [Virtual Machine (VM. Even in the mixed mode of generating machine code, you can start development by writing the bytecode interpreter and then implement the machine language generator. By using simple bitwise codes, it is much easier to optimize the output of machine code.
V8 does not convert the original program into an intermediate language, but directly generates and executes the abstract syntax. There is no virtual machine, and because no intermediate representation is required, program processing starts earlier. However, it also loses the benefits of virtual machines, such as high portability and optimized simplicity through bytecode interpreters and hybrid modes.
2) garbage collection management: exquisite Implementation of Java standard features
The second key feature is that V8 uses the garbage collection management (GC *) as the [precise GC *]. On the contrary, most JS engines, Ruby, and other language compilers use conservative GC, because the conservative GC implementation is much simpler. Although accurate GC is more complex, it also has performance advantages. Oracle (Sun) Java VM uses precise GC.
Garbage collection (GC) Garbage collection management: Automatically detects and releases stored space that is stored by programs but no longer in use. Conservative GC: there is no strict management of indicator and digital value memory collection management. This method is used to view an indicator if it can become an indicator, even if it may be a numerical value. This method prevents objects from being accidentally recycled, but it cannot release possible memory. Although precise GC itself is highly efficient, advanced algorithms based on precise GC, such as Generational GC and copy) GC and mark-and-compact processing significantly improve performance. Generational GC manages [Young Generational] objects (frequently collected) and [Old Generational) objects (relatively long-lived objects) separately) the GC efficiency is improved. V8 uses a Generational GC, a lightweight (light-load) replication GC for the new Generational (Generational) processing, and a labeled and streamlined GC for the old GC, because it must move objects in the memory space. This is hard to be executed in a conservative GC. In copying objects, compaction (defrag in the hard disk) and similar actions change the object address, and for this reason, the most common method is to use handles to indirectly reference an address. However, V8 does not use a handle, but overwrites all data referenced by this object. Without handles, the implementation is more difficult, but the performance can be improved because indirect reference is missing. Java VM HotSpot also uses the same technology.
3) embedded cache: js is not available. V8 uses the hidden class technique.V8 can currently generate suitable machine languages for x86 and ARM architectures. Although traditional optimization methods in C ++ or Java are not used, V8 still has the inherent speed of dynamic languages. One good example is the inline cache, which prevents hash table searches during method calls and attribute access. It can immediately cache previous search results, so it is called "embedded ]. People know that this technology has been applied to Smalltalk, Java, Ruby and other languages for a while. Embedded cache assumes that all objects have different types, but they are not in js until V8 appears. This is why the signed js engine does not have embedded cache. To overcome this restriction, v8 analyzes program operations during execution and uses hidden classes to specify a temporary class for the object. With a hidden class, you can use nested cache even for JavaScript. However, these classes are techniques for improving execution speed, not extensions of language specifications. Therefore, they cannot be referenced in JS Code.
Different from V8, other JavaScript Engines store object attributes in hash tables, but V8 stores them in arrays. Displacement Information-specify the position of individual attributes in the array-is stored in the hidden class hash table. Objects of the same hidden class have the same property name. If you know the object class, you can use the displacement to operate the access attribute according to the array. This is much faster than searching for hash tables.
However, in dynamic languages such as js, it is difficult to know the object type in advance. For example, the object types p and q call the lengthSquared () function. The properties of object types p and q are different, and the hidden classes are different. Therefore, the parameter (arguments) type of the lengthSquared () function Code cannot be determined.
To read the object attributes in a function, you must first check the hidden classes of the object and search for the hash table of the class to find the displacement of the property. And then use the displacement to access the array. Although the attribute is accessed in an array, the need to search for a hash table first destroys the advantages of using an array. However, the situation varies from different points of view. In actual programs, there are not many cases of depending on code execution to determine the type. For example, the lengthSquared () function even assumes that most of the values passed as parameters are Point-class objects, which are generally correct.
Function lengthSquared (p) {return p. x * p. x + p. y * p. y;} function LabeledLocation (name, x, y) {this. name = name; this. x = x; this. y = y;} var p = new Point (10, 20); var q = new LabeledLocation ("hello", 10, 20); var plen = lengthSquared (p ); var qlen = lengthSquared (q );
Before execution, you cannot determine whether the parameter is the LabeledLocation type of the Point or lengthSqurared () function.
Embedded caching is an acceleration technique designed to take advantage of local classes in programs. To perform programmatic attribute access, V8 generates a command string to search for the hidden class list. This code is called premonomorphic stub. This stub is used to access attributes in the function. Premonomorphic stub has two types of information: hidden classes used for search and hidden displacement. New Code is generated to cache this information.
Object * find_x_for_p_premorphic (Object * p) {Class * klass = p-> get_class (); int offset = klass-> lookup_offset ("x"); update_cache (klass, offset ); return p-> properties [offset];}
Premonomorphic stub in pseudo-code gets the attribute displacement from the hidden class. LengthSquared () function

Permonomorphic stub calls premonomorphic stub when calling the attributes in the function.
Object * find_x_for_p_monomorphic (Object * p) {if (CACHED_KLASS = p-> get_class () {return p-> properties [CACHED_OFFSET];} else {return lookup_property_on_monomorphic (p, "x ");}}
The pseudo-code monomorphic stub process the displacement directly embedded in the code is used to access the attribute constant. Before searching for a table, hidden classes with attribute objects are compared with hidden classes in the cache. If they match, you do not need to search again, and you can use the cached displacement to access attributes. If the hidden classes do not match, the displacement is determined by hiding the hash tables.
The newly generated code is called monomorphic stub. [Embedded] This word refers to the displacement required to query hidden classes and is embedded in the generated code in the form of immediate availability. When monomorphic stub is called for the first time, it will rewrite the first address called from the pre-monomorphic stub address to the monomorphic stub address. Since then, with the high-speed monomorphic stub, attribute access can be processed by class comparison and array access alone.



When you call monomorphic stub, it will rewrite the first address called from the premonomorphic stub address to the monomorphic stub address.
If there is only one object with attributes, monomorphic stub will be highly efficient. However, if there are more types, cache errors will occur more frequently, reducing the efficiency of monomorphic stub.
When cache errors occur, V8 solves the problem by generating another code called megamorphic stub. Monomorphic stub corresponding to individual classes are written in the hash table, and stub is searched and called during execution. If there is no corresponding monomorphic stub, the system searches for the displacement from the type hash table.
Object * find_x_for_p_megamorphic (Object * p) {Class * klass = p-> get_class (); // embedded processing actual search Stub * stub = klass-> lookup_cached_stub ("x"); if (NULL! = Stub) {return (* stub) (p);} else {return lookup_property_on_megamorphic (p, "x );}} megamorphic stub in the pseudo-code processes monomorphic stub corresponding to the type and stores it in the hash table in advance, and is searched and called during execution. If the corresponding monomorphic stub cannot be found, the system searches for the displacement in the type hash table.
When a cache error occurs in monomorphic stub, monomorphic stub will rewrite the first address called by the function from the monomorphic stub address with the megamorphic stub address. In code search, megamorphic stub has lower performance than monomorphic stub, but megamorphic code is much faster than premonomorphic stubs, which uses cache updates, code generation, and other auxiliary processing.
Multiple types of embedded cache are called multi-form embedded cache (polymorphic inline cache ). The V8 embedded cache system is used to call methods and store attributes.

4) Hide class storage type conversion information
Hiding classes brings interesting challenges to js language specifications without any category, and is also the most unique technique that V8 uses to speed up. They deserve further exploration. There are two main reasons for creating a class in V8: (1) classifying objects with the same attribute name and (2) Identifying objects with different attribute names. Objects in the previous category have identical object descriptions, which can accelerate attribute access.
In V8, classes that meet the classification criteria are configured on various js objects. The class configured by the object reference. However, these classes only exist in V8 for convenience, so they are hidden.


If the object description is the same, the hidden class will also be the same. In this example, the object p and q both belong to the same hidden class. As mentioned above, you can add or delete attributes in js at any time. However, when this happens, the classification conditions will be destroyed (attributes with the same name are summarized ). V8 solves this problem by creating new classes required for attribute changes. An object with a property change is included in the new level through a program called class transition.

New configuration class: type conversion
Objects with changed attributes are classified as new classes. When object p adds a new property z, object p is classified as a new class. V8 stores the transformation information in the class to solve this problem. When the hidden class Point has the x and y attributes, the new property z will be added to the Point-level object p. When the new property z is added to the object p, V8 stores the information of the new property z and Point2 class in the Point-level internal table.
Store class transformation information in the class. When the new attribute z is added to object p, V8 records the table in the Point class [add attribute z, create a class Point2 (step 1 ). When q of the same Point class is added to the attribute z, V8 searches for the Point class table first. If it finds that the Point2 class has been added to the attribute z, it sets the object q to the Point2 class (step 2 ). For example:



When the new attribute z is added to the q object that is also a Point-level object, V8 first searches for the Point-level table and finds that the Point2 level has been added to the attribute z. When a class is found in the table, the object q will be set to this class (Point2) without creating a new class (step 2), which achieves the goal of the object with the same name as the inductive property.
However, this method means that the empty object corresponding to the hidden class has a large conversion table. V8 creates hidden classes for each construction function. If the construction function is different, even if the object statement (layout) is identical, a new hidden class will be created for it.
5) features of machine language
As described above, V8 uses built-in caching, for example, to achieve the inherent speed in dynamic languages. The machine language generation module that creates stub for Embedded caching is closely linked to the JIT compiler.
Some frequently used methods are also written into machine languages to achieve the same effect as embedded expansion, making them [inner. The V8 original code lists the candidates for internal conversion.
The shell program contained in V8 can be used to check the machine language generated by V8. The resulting command string can be compared with V8 code to show its features.
For example, when executing the js function shown in Figure 14a, an x86 machine language instruction string is generated, as shown in. This function is called in 39th commands and is an addition of [n + one. In js, the [+] operand indicates the addition of numeric variables and the continuity of strings. The compiler does not generate code to determine which type of code is used, but calls a function to determine which type of code is used.


The machine language addition processing produced by V8 from js Code is converted into the machine language (a, B) of function call ).
If the function is slightly changed, the function call will disappear, but an addition command and a branch command will be generated (JNZ jumps out if it is not zero ). When an integer is used as the operand of the [+] operator, the V8 compiler generates an instruction string with the [addition] command without calling a function. If the operand ([n] Here) is found to be a Number object or a String object indicator (pointer), a function is called. Addition occurs only when the operands of the two [+] operations are integers. In this case, execution is faster because function call can be skipped.



The machine language generated after slightly modifying js.
In addition, the [addition] command is added to 0x2, because least significant bit (LSB) is used to distinguish between INTEGER (0) and indicator (1 ). Adding 0x2 (10 in binary) is like adding 1 to this value, except for LSB. In the overflow processing of jo commands, the testing and jnz commands are used to determine the indicators and jump to downstream processing. Such tricks are everywhere in the compiler. However, the generation of machine code also reveals compiler restrictions. The traditional optimized compiler can generate the same machine language for the above two figures, because of the constant carry relationship. However, the V8 compiler generates code in the abstract syntax tree unit, so it is not optimized when processing extended nodes. This is also evident in a large number of push and pop commands.



The machine language generated by C language is displayed. The language specification is different between C and js, so the machine language generated is different and has nothing to do with compiler performance. The machine languages produced by the c compiler from the c code are much cleaner than those produced by V8 (a and B), most of which are caused by differences in the c and js language specifications. Note 1: When an overflow signal occurs, the jo command jumps to a specific address. The test command reflects the logic AND result as a zero-sum indicator. If a non-zero signal is exceeded, the jnz command jumps to a specific address.
Abstract syntax tree: Data of the program architecture is represented in the tree structure.
7. Familiar with js object-oriented
Js does not have classes, but to make it easier to get familiar with classes (Object-Oriented code), you can use the new operands to create objects, just like in java, after the new operand, a special constructor is defined. However, even if there is no constructor, you can create objects and set attributes. attributes and methods of js objects can be added and deleted at any time. In addition to using dot notation to access js attributes, you can also use parentheses. We recommend that you use hashing to access or use a variable-specific attribute name string. From these examples, it is clear that js objects are designed to use hash tables.
A) define the constructor [point] function Point (x, y) {// this refers to its own this. x = x; this. y = y ;}
B) the object var p = new Point (10, 20) created when new and call BUILD functions are added );
C) the object var p = {x: 10, y: 20} can be created without building a function };
D) The property p. z = 30 can be freely added to the object;
E) Use the dot mark to access the property var y = p. y;
F) Use hashing to access var y = p ["y"];
G) You can also use variables for hashing to access var name = "y"; p [name];



Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.