Wednesday, February 17, 2010

Lessons to take from V8 javascript engine

V8 is Google's open source JavaScript engine it's written in C++ and is used in Google Chrome, the open source browser from Google.

It's very interesting to discover how this engine is implemented and what lessons we can take when analyzing it.

here's some remarks about this engine:

Optimization is also a design issue

When I hear that google chromium browser use fast javascript engine, I was sure that it was developed with “C” language like almost all known languages and interpreters (Perl, Python, PHP, Spider Monkey), but when I got the source code, I was very surprised that‘s developed with C++.

The goal of this engine is to be very fast and the decision of V8 team to choose C++ proof that performance depends also on design choices more than language choice.

There’s some V8 Design Choices:

Hidden Class:

JavaScript is a dynamic programming language: properties can be added to, and deleted from, objects on the fly. This means an object's properties are likely to change.
Javascript has a class concept but there’s a class representing it in source code?

To answer to this question let’s search in V8 source code all objects kind treated, for that we can execute the following request:

SELECT TYPES WHERE DeriveFrom "v8.internal.JSObject"






as we can observe there's no class inheriting from JSObject representing a Class like Function or Value, it's normal because in any dynamic langage the idea is to create a class in the real time and most JavaScript engines use a dictionary-like data structure as storage for object properties,each property access requires a dynamic lookup to resolve the property's location in memory.

This approach makes accessing properties in JavaScript typically much slower than accessing instance variables in programming languages like Java and Smalltalk. In these languages, instance variables are located at fixed offsets determined by the compiler due to the fixed object layout defined by the object's class. Access is simply a matter of a memory load or store, often requiring only a single instruction.

V8 use hidden class concept to reduce the time required to access JavaScript properties. V8 does not use dynamic lookup to access properties. Instead, V8 dynamically creates hidden classes behind the scenes as detailled in this post.

Dynamic machine code generation:

V8 compiles JavaScript source code directly into machine code when it is first executed. There are no intermediate byte codes, no interpreter. Property access is handled by inline cache code that may be patched with other machine instructions as V8 executes.

let's discover the dependency graph for MakeCode function.




Garbage collector:


V8 use an efficient garbage collector to manage memory, and I was very interested to know if I can use it easily in other C++ projects, for that I have to look if the garbage collector classes are highly coupled with other V8 classes or not.

An interesting question is to know if we can use MarkCompactCollector in other C++ projects.

for that let’s search for indirect dependencies for this class:

SELECT TYPES WHERE IsUsedBy "v8.internal.MarkCompactCollector"




Unfortunately this class is highly coupled with a lot of other V8 classes.

V8 is optimized and use design patterns:

I dont know why many developpers think that using OOP and design patterns can impact a lot the optimization.

V8 is an example of project that use OOP and patterns and in the same time very optimized.

here's for example two patterns used:

Factory:

The factoy class create many objects needed and do abstraction of garbage collector invocation, for example let's search for methods invoked by Factory::NewJsObject

SELECT METHODS WHERE IsDirectlyUsedBy "v8.internal.Factory.NewJSObject(Handle,PretenureFlag)"



as we can observe this method do some abstraction of memory allocation.

Visitor:

V8 contains many classes implementing visitor pattern.





Make C++ easy to use:

Memory allocation simplified

Managing memory and allocating pointers is complicated in C++ Using garbage collector can simplify this task.

Avoid multiple inheritance

Let's search for classes with multiple base classes:

SELECT TYPES WHERE NbBaseClass >1

and the result of this query is empty so V8 dont use multiple inheritance, it simplify a lot the developement and evolution of application.

Use RTTI carefully

Using RTTI resolve some problems but can be an indicator of a bad design, be sure to no overuse this technique.

Let's search if V8 use dynamic_cast:

SELECT METHODS WHERE IsDirectlyUsing "Keywords.dynamic_cast"

the result is empty and it's an indicator from others that V8 is well designed.

Exceptions

Using exceptions is interesting but is not easy that a code be exception safe.
V8 team choose to not use exceptions to simplify the implementation.

we can execute the following CQL request to know if exception is used:

SELECT METHODS WHERE IsDirectlyUsing "Keywords.throw"

No comments:

Post a Comment