By Leszek Swirski
Translation: Crazy geek
Original text: v8. Dev/blog/v8 – rel…
Reproduced without permission
Finally. V8 comes out every six weeks, and every time we release a version, there are questions about what happens when V8 gets to version 8. Have a party? Will we provide a new compiler? Will we skip versions 8 and 9 and keep V8 stuck in some version X for eternity? After more than 10 years of work, and in our 100th blog post, we are pleased to announce the release of our latest branch, V8 Version 8.0 V8, and we can finally answer this question:
It fixes bugs and improves performance.
We’ll be working with Chrome 80 Stable in a few weeks to get a preview of some of the key points expected in this release.
performance
Pointer to the compressed
We reduced the size of the source file by 66% by changing all void * to PV.
The V8 heap contains a whole set of items, such as floating point values, strings, compiled code, and various token values (representing Pointers to the V8 heap or small integers). We examined the heap and found that the values of these markers took up a large portion of the heap!
The token values have the same data size as the system Pointers: they are 32 bits wide for 32-bit architectures and 64 bits wide for 64-bit architectures. When comparing the 32-bit version with the 64-bit version, we found that the 64-bit version used twice as much heap memory per tag value as the 32-bit version.
Fortunately, we have a trick up our sleeve. The high can be synthesized from the low. Then you only need to store the unique low value in the heap, saving precious memory resources… About 40% average heap memory savings!
Pointer compression saves an average of 40% of memory
When memory improvements are made, they often come at the expense of performance. But we are proud to report that in V8 and its garbage collector, we are seeing real site performance improvements!
V8. dev/blog/v8-rel…
If pointer compression piques your interest, feel free to follow our blog posts.
Optimize high order built-in
Recently, we removed a limitation in TurboFan’s optimization pipeline that prevented aggressive optimization of higher-order built-in programs.
const charCodeAt = Function.prototype.call.bind(String.prototype.charCodeAt);
charCodeAt(string, 8);
Copy the code
Until now, calls to charCodeAt have been completely opaque to TurboCan, resulting in generic calls to user-defined functions. With this change, you can now identify the we are in a call to the built-in String. The prototype. The charCodeAt function, which can trigger the TurboFan further optimized to improve the built-in function calls, and have the same performance with the following code:
string.charCodeAt(8);
Copy the code
This change affects a number of other built-in functions, such as function.prototype. apply, reflect.apply, and many higher-order Array built-in functions (such as array.prototype.map).
JavaScript
Optional chain
When writing property access chains, programmers often check whether the intermediate value is null (that is, null or undefined). Chains without error checking can throw errors, while chains with explicit error checking are verbose and have the undesirable consequence of needing to check for all true values instead of just non-null values.
// Error prone-version, could throw.
const nameLength = db.user.name.length;
// Less error-prone, but harder to read.
let nameLength;
if (db && db.user && db.user.name)
nameLength = db.user.name.length;
Copy the code
Optional chain (? .). Allows programmers to write more powerful property access chains to check for null intermediate values. If the intermediate value is null, the entire expression evaluates to undefined.
// Still checks for errors and is much more readable.
constnameLength = db? .user? .name?.length;Copy the code
In addition to static property access, dynamic property access and invocation are supported. For details and more examples, see our feature description.
Nullish merger
Nullish merge operator?? Is a new binary operator for short-circuiting default values. Currently used sometimes logic | | operators to deal with a default value, such as:
function Component(props) {
const enable = props.enabled || true;
/ /...
}
Copy the code
Do not recommend using | | calculating the default, because in a | | b, when a is false, will be evaluated for b. If you explicitly set props. Enabled to false, enable remains true.
Using the Nullish merge operator in a?? In b, if the value of A is null (or undefined), the evaluation result is B; otherwise, it is A. This is the ideal default behavior, using?? Overriding the above example fixes this error.
function Component(props) {
const enable = props.enabled ?? true;
/ /...
}
Copy the code
Nullish merge operators and optional chains are auxiliary features that work well together. You can further modify the example to handle the case where the props argument is not passed.
function Component(props) {
constenable = props? .enabled ??true;
/ /...
}
Copy the code
For details and more examples, see our feature description.
V8 API
Git log branch-heads/7.9.. Branch-heads /8.0 include/v8.h gets a list of API changes.
Developers with Active V8 Checkout permission can use Git checkout -b 8.0-t branch-heads/8.0 to try out the new features in V8 V8.0. Alternatively, you can subscribe to Chrome’s Beta channel and try out new features soon.