ES6 Features in New V8 Upgrade | ArangoDB Blog
ArangoDB 2.6 uses V8 engine version 3.31.74.1 for running its own and all user-defined JavaScript code. In ArangoDB 2.7 (currently in development), we have upgraded V8 to version 4.3.61.
The new V8 version in ArangoDB 2.7 provides several additional ES6 Harmony features that can be used to improve JavaScript usability and code quality. This blog post showcases strong mode and rest parameters, and also shows how to activate TurboFan, V8’s new JIT compiler for JavaScript.
ArangoDB 2.7 is in development right now, but it can be tried today by compiling it from source.
JavaScript strong mode
V8 v4 comes with an optional and experimental strong mode. This mode provides only a subset of JavaScript, with the idea of intentionally deactivating some of JavaScript’s bad parts. It is based on strict mode, but goes further.
Committing to strong mode may not only provide better and stronger semantics, but may also enable more optimization opportunities for the JavaScript compiler. For example, the strong mode disables JavaScript’s with statement and delete
! Additionally, var
cannot be used anymore but is deprecated in favor of let
and const
.
The proposal for the strong mode can be found here,and the V8 team also has a page about it.
Strong mode must be turned on explicitly. This can be done by adding the --strong-mode=true
v8 option when starting arangod or arangosh:
arangosh --javascript.v8-options="--strong_mode=true"
Note that I am using arangosh above, but the same would work for arangod, too, so the feature can be used for Foxx routes as well.
Rest parameters
How to pass a variable number of arguments to a function?
C and C++ programmers have been using and abusing the ellipsis (...
) and __VA_ARGS__
features of the C preprocessor for a long time. Then came the macros of stdarg.h
/ cstdarg
, until C++11 really improved the situation with std::initializer_list
and variadic templates.
In JavaScript, one can use the arguments
object:
function logSimple () {
for (value of arguments) {
console.log(value);
}
}
logSimple("foo", "bar", "baz");
This does the job, and the above will print something like:
2015-07-14T19:01:51Z [5245] INFO foo
2015-07-14T19:01:51Z [5245] INFO bar
2015-07-14T19:01:51Z [5245] INFO baz
This is fine as long as all arguments shall be treated the same way. But what if some arguments have a designated meaning and should be treated specially?
The solution is to use ES6 rest parameters. The last parameter in an argument list can be prefixed with ...
to capture any number of function parameters:
function logWithContext (context, ...values) {
for (value of values) {
console.log('[' + context + '] ' + value);
}
}
logWithContext("es6", "foo", "bar", "baz");
As can be seen, the logWithContext
function specially handles its context
argument, while we can still pass any number of further parameters into it. Here’s what the above will print:
2015-07-14T19:07:27Z [5245] INFO [es6]: foo
2015-07-14T19:07:27Z [5245] INFO [es6]: bar
2015-07-14T19:07:27Z [5245] INFO [es6]: baz
Note that rest parameters cannot be used with the default configuration and must be turned on explicitly in arangosh or arangod.
The startup option to turn them on is:
arangosh --javascript.v8-options="--harmony_rest_parameters=true"
TurboFan
The new V8 version comes with TurboFan, a new JIT compiler for JavaScript. According to this post it is already used in Chrome for compiling certain types of JavaScript code.
As fas as I can see, it is turned off by default in our version of V8, and the compiler also seems to be rather experimental. To get an idea of what it can already do and where its limits are, it can already be tried in ArangoDB 2.7.
By default, it seems to be turned off. Using the following startup option, it can be turned on for JavaScript functions with a certain name pattern (i.e. all function names starting with testTurboFan):
arangosh --javascript.v8-options="--turbo-filter=testTurboFan*"`
Without turning on V8 tracing, one will not be able to tell which compiler is used to compile a specific function. To turn it on and actually confirm V8 is using TurboFan, use these options:
arangosh --javascript.v8-options="--always-opt --trace_opt --turbo-filter=testTurboFan*"
This will be very verbose, but it is good to tell which internal compiler is used to compile a givenJavaScript function.
For example, after starting the ArangoShell with the above options, run the following test code to see that V8 uses TurboFan for compiling the first two functions (which match the name pattern), and Crankshaft for the third (which does not match the name pattern):
function testTurboFan1 () {
console.log("turbo-fan 1");
}
testTurboFan1();
function testTurboFan2 () {
console.log("turbo-fan 2");
}
testTurboFan2();
function testSomethingElse () {
console.log("something else");
}
testSomethingElse();
Here’s the confirmation that TurboFan is used:
...
[compiling method 0x31ca8804e351 <JS Function testTurboFan1 (SharedFunctionInfo 0x31ca8804e171)> using TurboFan]
...
[compiling method 0x31ca8804e7f9 <JS Function testTurboFan2 (SharedFunctionInfo 0x31ca8804e619)> using TurboFan]
...
[compiling method 0x31ca8804ec71 <JS Function testSomethingElse (SharedFunctionInfo 0x31ca8804ea91)> using Crankshaft]
...
Have fun!
4 Comments
Leave a Comment
Get the latest tutorials, blog posts and news:
Cool that you’re exposing the new V8 features already but they’re definitely not ready for general consumption yet, for most code turbofan is about 2x – 5x slower than crankshaft, strong mode is currently 30x slower than strict mode 🙂
I experienced in a few quick tests that using TurboFan was literally starting the laptop fan and executing my test code took longer. AFAIK it’s still rather experimental, but luckily it only gets activated by explicit user control. (I think Chrome already turns it on for *some* code by default, but only when relatively sure that the compiled code will run fast).
Seems it has some way to go, but it looks very promising. Same for strong mode: looks very promising, too, as it allows compilers to ignore certain JS features that would render some optimizations impossible.
A lot of performance-increasing features/restrictions implemented in Crankshaft are not yet implemented in TurboFan. I wouldn’t expect faster code before a first completed implementation. I’m really curios how much the speed gain will ultimately be. And SoundScript (typed JS) looks promising as well!
Spread (call and array) landed in V8 recently: https://www.chromestatus.com/features/6031334694715392 I hope this will make it into ArangoDB 2.7 too!