Skip to content

EdgenDy/Learning-V8-Javascript-Engine

main
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
October 13, 2021 22:35
November 1, 2021 07:37
October 13, 2021 22:13

A Detailed View inside V8 Javascript Engine

In this tutorial we will find out how exactly V8 executes the js code 'hello' + 'world', by analyzing and examining every line in hello-world.cc file in v8/samples directory.

Note : The version of v8 that we will used here is v8-7.9.2.

What are we waiting for, lets get started!

Initializing The Platform

If we look at the line 16 of the v8/samples/hello-world.cc we will see the following code:

16 | std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();

You will notice that we create a v8::Platform object that wraps in a std::unique_ptr object by using NewDefaultPlatform() method of the namespace v8::platform, the definition of this method is in the line 34 of v8/src/libplatform/default-platform.cc, while the declaration is in the v8/include/libplatform/libplatform.h at line 37.

// src/libplatform/libplatform.h 

37 | V8_PLATFORM_EXPORT std::unique_ptr<v8::Platform> NewDefaultPlatform(
38 | /* 1 */    int thread_pool_size = 0,
39 | /* 2 */    IdleTaskSupport idle_task_support = IdleTaskSupport::kDisabled,
40 | /* 3 */    InProcessStackDumping in_process_stack_dumping =
41 |        		InProcessStackDumping::kDisabled,
42 | /* 4 */    std::unique_ptr<v8::TracingController> tracing_controller = {});

The first parameters is thread_pool_size which is an integer with an initial value of zero. We will discussed it later.

The second is idle_task_support which is a key of enum class IdleTaskSupport with an initial value IdleTaskSupportkDisabled::kDisabled.

// src/libplatform/libplatform.h

16 | enum class IdleTaskSupport { kDisabled, kEnabled };

The third is in_process_stack_dumping which is a key of enum class InProcessStackDumpingInProcessStackDumping::kDisabled with an initial value kDisabled.

// src/libplatform/libplatform.h

17 | enum class InProcessStackDumping { kDisabled, kEnabled };

And the last is v8::TracingController that wraps in an empty std::unique_ptr object.

// include/v8-platform.h

137 | class TracingController {
138 |  ...
199 | }

Inside this method there is a checking on our parameter.

// src/libplatform/default-platform.cc

38 | if (in_process_stack_dumping == InProcessStackDumping::kEnabled) {
39 |     v8::base::debug::EnableInProcessStackDumping();
40 | }

In the code above it checked if the in_process_stack_dumping argument is kEnabled so we can call EnableInProcessStackDumping method, but in our case our in_process_stack_dumping is kDisabled so we will proceed on creation of platform.

// src/libplatform/default-platform.cc

41 | std::unique_ptr<DefaultPlatform> platform(
42 |      new DefaultPlatform(idle_task_support, std::move(tracing_controller)));

In this line of code we allocate DefaultPlatform object instance on the heap by using new operator and wraps it in std::unique_ptr object. DefaultPlatform is a child class of v8::Platform and we used it as our default platform.

Declaration:

// src/libplatform/default-platform.h

32 | class V8_PLATFORM_EXPORT DefaultPlatform : public NON_EXPORTED_BASE(Platform) {
      ...
90 | } 

Implementation:

// src/libplatform/default-platform.cc

69 | DefaultPlatform::DefaultPlatform(
70 |     IdleTaskSupport idle_task_support,
71 |     std::unique_ptr<v8::TracingController> tracing_controller)
72 |     : thread_pool_size_(0),
73 |       idle_task_support_(idle_task_support),
74 |       tracing_controller_(std::move(tracing_controller)),
75 |       page_allocator_(new v8::base::PageAllocator()),
76 |       time_function_for_testing_(nullptr) {
77 |   if (!tracing_controller_) {
78 |     tracing::TracingController* controller = new tracing::TracingController();
79 |     controller->Initialize(nullptr);
80 |    tracing_controller_.reset(controller);
81 |  }
82 | }

Inside this constructor it only check if tracing_controller_ is empty and then it will create a new v8::platform::tracing::TracingController object instance and it will Initialize as you've seen on the code above. TracingController extends the public base class v8::TracingController.

Declaration

// include/libplatform/v8-tracing.h

229 | class V8_PLATFORM_EXPORT TracingController
230 |     : public V8_PLATFORM_NON_EXPORTED_BASE(v8::TracingController) {
231 |  public:
    |   ...
249 |   void Initialize(TraceBuffer* trace_buffer);
    |   ... 
310 | }; 

Implementation

// src/libplatform/tracing/tracing-controller.cc

64 | TracingController::TracingController() = default;
   | ... 
81 | void TracingController::Initialize(TraceBuffer* trace_buffer) {
82 |   trace_buffer_.reset(trace_buffer);
83 |   mutex_.reset(new base::Mutex());
84 | }

About

A project that helps me and others to better understand how V8 actually works.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages