Hello everyone and Today we will look into how JavaScript Code is executed by the browser such as Google Chrome that you use and how those lines of code that you write are understood by the machine that is running them. So what are we waiting for? Let's get straight into it. 

What is Javascript?


Javascript is a Client-side Scripting Language used For in Page validation or performing onclick events. Javascript is executed on the browser. Javascript is Simple and easy to learn

First of all let us ask yourself a question: what is a JavaScript engine? in fact what classifies to be called an engine. Well, when we write code we write it using a  human-readable syntax using alphabets and numbers. but that is the kind of language that we Humans understand. the machine has no idea how to interpret that line of Javascript which we write. This is where the engine comes into the picture. The Javascript engine is that piece of software that makes this human-readable Javascript code and converts it to a low-level machine-understandable representation, which then gets executed by the CPU of the machine. 

All the popular browsers that we know have their own Javascript engines that are the component that converts the javascript code into machine-executable code. Here is a list of all the popular ones. The engine that chrome uses is named as the V8 Engine. The one inside Firefox is called Spider Monkey. Safari has Javascript Core and Edge has Chakra. all of these are more or less the same in the way in which they convert javascript code into machine understandable code. With only slight differences. In this article, we will be looking specifically into the Javascript engine behind Google chrome which is V8.

 First things first when we say Javascript engine it is not some spooky out of the world stuff that we are talking about. All engines are basically programs. V8 is one that is written in C++. This C++  code has one core functionality. To convert the Javascript code fed into it, into optimized machine code so that it runs on the host machine in the most efficient way. Now earlier, the Javascript engines were basically interpreters. which worked on the code line by line, passing and interpreting each of them requiring no compilation to a lower level. But V8 employs something called Just in time compilation or JIT Compilation. 

Fun fact, V8 is the same engine that gets shipped with Node runtime as well. meaning V. 8 is the engine at the core of Node JS as well. Let us get into the history of things for a while. When Javascript initially came into existence all of it wasn't interpreted. that means there was no compiling process, where a compiler converted a Javascript code into machine efficient code. It was just interpreted line by line by a Javascript Compiler. This was a very bad way of doing things. When V8 came along, the V8 Team At Google Thought about this problem and solved it in their own unique way. 
First of all, they dedicated  2 separate threads, for performing the compiler related operations. There are several other threads that help the compilation process but these 2 are the main ones. They were named full-codegen and crankshaft. The function of full code-gen was to consume Javascript and compile it just before execution. Google called this just in time or the JIT compiler method. When full code-gen worked on the lines of code and converted it into machine code, another monitoring thread in the browser monitored the code being compiled for hot segments. that this segment of code that was being hit multiple times. 

The code inside the loop, for instance, classifies as a hot code segment. As and when the monitoring threads got to know about these segments they marked them. Now, this is where the crankshaft came into the picture. Crankshaft took the code segments marked as hot and then compiled them in a more optimal way. So that the next time that portion of code was hit, this new optimized machine code executed leading to better efficiency. This resulted in a better execution efficiency for that piece of code as well as for the entire program. 

Here is the summary of all the threads that are in one of the other ways of helping Chrome to execute the javascript code. There’s the Main Thread which, as the name suggests, performs the main task of fetching the code making sure it compiles and then executing it. Then there are the 2 compiler Threads that we discussed earlier. Full code-gen and crankshaft. Then there's the profiler thread that we learned about those profiles and marks the portions of code that are hot. And then there are the garbage collector threads which you might have guessed manage garbage collection for the memory.

At this point in time, you might be wondering. If full code-gen already compiles the code to machine level, what are the kind of optimizations that crankshaft applies so that we get an even more efficient compilation right, Here are some of them? First of all, there is in-lining. What this means is all the calls to different functions in the code are replaced by the actual code from those functions. This definitely results in increased efficiency. 

Second, there is the concept of hidden classes. Now Javascript is a loosely typed language and any property could be added to any object at any point of time keeping a track of all the properties of an object becomes very costly. To overcome this difficulty the engine maintains something called hidden classes which are Dynamic. In due time this leads to a kind of tree structure that holds several classes for which a new instance is created every time any new property is added to an object. This topic is a little complex. Let's just assume that this leads to a more optimal execution. 

Thirdly inline caching is done. This caches the object type of the parameters that are most likely to be passed to a function. as the type of parameters that are passed to a function do not change over the course of execution of the entire program. Thus we get a more optimal execution. As we do not have to fetch the object type and properties of parameters passed to a function as we have already cached them. Let us just recall what happened to this point in time. The Javascript code was compiled and full code-gen transformed the Javascript abstract syntax tree into what is called a static single state assignment also known as the hydrogen Graph. 

The hydrogen graph is then optimized and converted to a lower level by a crankshaft which is known as lithium. This is where the minute intricacies like register allocation take place and finally, this lithium code is converted into machine code. Now as the CPU of the host computer is already processing instructions that were generated from the earlier from the non optimally combined code the Javascript engine has to do an on stack replacement which is the stack registers are swapped right in the middle of execution which is another mammoth task. In the end, after all, this is done we have optimally compiled javascript code running on the host computer. By the way, all the details that we until now was what chrome script engine used to do versions earlier than 5.9.  What happens currently is a little bit different. Google needs to keep evolving engines with new requirements that are added to the Javascript language.and that is somehow becoming difficult while maintaining the old way of doing things so Google changed the way it does things.

 Anyways in the new way of doing things, full code-gen got replaced by ignition, and the work of crankshaft is now taken up by Turbo Fan. We will talk about these differences in the future. for now, it is important to note that as of today the chrome browser that you use is being powered by the optimal code compilation, made possible by ignition and turbo Fan. So that's It. 

If you have any queries or doubts please put it up in the comments section I'll be happy to answer those. 

See you next time until then, happy learning!

0 Comments: