isolate_holder.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "gin/public/isolate_holder.h"
  5. #include <stddef.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <memory>
  9. #include <utility>
  10. #include "base/check_op.h"
  11. #include "base/system/sys_info.h"
  12. #include "base/task/current_thread.h"
  13. #include "base/task/single_thread_task_runner.h"
  14. #include "base/threading/thread_task_runner_handle.h"
  15. #include "build/build_config.h"
  16. #include "gin/debug_impl.h"
  17. #include "gin/function_template.h"
  18. #include "gin/per_isolate_data.h"
  19. #include "gin/v8_initializer.h"
  20. #include "gin/v8_isolate_memory_dump_provider.h"
  21. #include "gin/v8_shared_memory_dump_provider.h"
  22. #include "v8/include/v8-isolate.h"
  23. #include "v8/include/v8-snapshot.h"
  24. namespace gin {
  25. namespace {
  26. v8::ArrayBuffer::Allocator* g_array_buffer_allocator = nullptr;
  27. const intptr_t* g_reference_table = nullptr;
  28. v8::FatalErrorCallback g_fatal_error_callback = nullptr;
  29. v8::OOMErrorCallback g_oom_error_callback = nullptr;
  30. std::unique_ptr<v8::Isolate::CreateParams> getModifiedIsolateParams(
  31. std::unique_ptr<v8::Isolate::CreateParams> params,
  32. IsolateHolder::AllowAtomicsWaitMode atomics_wait_mode,
  33. v8::CreateHistogramCallback create_histogram_callback,
  34. v8::AddHistogramSampleCallback add_histogram_sample_callback) {
  35. params->create_histogram_callback = create_histogram_callback;
  36. params->add_histogram_sample_callback = add_histogram_sample_callback;
  37. params->allow_atomics_wait =
  38. atomics_wait_mode ==
  39. IsolateHolder::AllowAtomicsWaitMode::kAllowAtomicsWait;
  40. params->array_buffer_allocator = g_array_buffer_allocator;
  41. return params;
  42. }
  43. } // namespace
  44. IsolateHolder::IsolateHolder(
  45. scoped_refptr<base::SingleThreadTaskRunner> task_runner,
  46. IsolateType isolate_type)
  47. : IsolateHolder(std::move(task_runner),
  48. AccessMode::kSingleThread,
  49. isolate_type) {}
  50. IsolateHolder::IsolateHolder(
  51. scoped_refptr<base::SingleThreadTaskRunner> task_runner,
  52. AccessMode access_mode,
  53. IsolateType isolate_type)
  54. : IsolateHolder(std::move(task_runner),
  55. access_mode,
  56. kAllowAtomicsWait,
  57. isolate_type,
  58. IsolateCreationMode::kNormal) {}
  59. IsolateHolder::IsolateHolder(
  60. scoped_refptr<base::SingleThreadTaskRunner> task_runner,
  61. AccessMode access_mode,
  62. AllowAtomicsWaitMode atomics_wait_mode,
  63. IsolateType isolate_type,
  64. IsolateCreationMode isolate_creation_mode,
  65. v8::CreateHistogramCallback create_histogram_callback,
  66. v8::AddHistogramSampleCallback add_histogram_sample_callback)
  67. : IsolateHolder(task_runner,
  68. access_mode,
  69. isolate_type,
  70. getModifiedIsolateParams(getDefaultIsolateParams(),
  71. atomics_wait_mode,
  72. create_histogram_callback,
  73. add_histogram_sample_callback),
  74. isolate_creation_mode) {}
  75. IsolateHolder::IsolateHolder(
  76. scoped_refptr<base::SingleThreadTaskRunner> task_runner,
  77. AccessMode access_mode,
  78. IsolateType isolate_type,
  79. std::unique_ptr<v8::Isolate::CreateParams> params,
  80. IsolateCreationMode isolate_creation_mode)
  81. : access_mode_(access_mode), isolate_type_(isolate_type) {
  82. CHECK(Initialized())
  83. << "You need to invoke gin::IsolateHolder::Initialize first";
  84. DCHECK(task_runner);
  85. DCHECK(task_runner->BelongsToCurrentThread());
  86. v8::ArrayBuffer::Allocator* allocator = params->array_buffer_allocator;
  87. DCHECK(allocator);
  88. isolate_ = v8::Isolate::Allocate();
  89. isolate_data_ = std::make_unique<PerIsolateData>(isolate_, allocator,
  90. access_mode_, task_runner);
  91. // TODO(https://crbug.com/1347092): Refactor such that caller need not
  92. // provide params when creating a snapshot.
  93. if (isolate_creation_mode == IsolateCreationMode::kCreateSnapshot) {
  94. // This branch is called when creating a V8 snapshot for Blink.
  95. // Note SnapshotCreator calls isolate->Enter() in its construction.
  96. snapshot_creator_ =
  97. std::make_unique<v8::SnapshotCreator>(isolate_, g_reference_table);
  98. DCHECK_EQ(isolate_, snapshot_creator_->GetIsolate());
  99. } else {
  100. v8::Isolate::Initialize(isolate_, *params);
  101. }
  102. // This will attempt register the shared memory dump provider for every
  103. // IsolateHolder, but only the first registration will have any effect.
  104. gin::V8SharedMemoryDumpProvider::Register();
  105. isolate_memory_dump_provider_ =
  106. std::make_unique<V8IsolateMemoryDumpProvider>(this, task_runner);
  107. }
  108. IsolateHolder::~IsolateHolder() {
  109. isolate_memory_dump_provider_.reset();
  110. // Calling Isolate::Dispose makes sure all threads which might access
  111. // PerIsolateData are finished.
  112. isolate_->Dispose();
  113. isolate_data_.reset();
  114. isolate_ = nullptr;
  115. }
  116. // static
  117. void IsolateHolder::Initialize(ScriptMode mode,
  118. v8::ArrayBuffer::Allocator* allocator,
  119. const intptr_t* reference_table,
  120. const std::string js_command_line_flags,
  121. v8::FatalErrorCallback fatal_error_callback,
  122. v8::OOMErrorCallback oom_error_callback) {
  123. CHECK(allocator);
  124. V8Initializer::Initialize(mode, js_command_line_flags, oom_error_callback);
  125. g_array_buffer_allocator = allocator;
  126. g_reference_table = reference_table;
  127. g_fatal_error_callback = fatal_error_callback;
  128. g_oom_error_callback = oom_error_callback;
  129. }
  130. // static
  131. bool IsolateHolder::Initialized() {
  132. return g_array_buffer_allocator;
  133. }
  134. // static
  135. std::unique_ptr<v8::Isolate::CreateParams>
  136. IsolateHolder::getDefaultIsolateParams() {
  137. CHECK(Initialized())
  138. << "You need to invoke gin::IsolateHolder::Initialize first";
  139. // TODO(https://crbug.com/v8/13092): Remove usage of unique_ptr once V8
  140. // supports the move constructor on CreateParams.
  141. std::unique_ptr<v8::Isolate::CreateParams> params =
  142. std::make_unique<v8::Isolate::CreateParams>();
  143. params->code_event_handler = DebugImpl::GetJitCodeEventHandler();
  144. params->constraints.ConfigureDefaults(base::SysInfo::AmountOfPhysicalMemory(),
  145. base::SysInfo::AmountOfVirtualMemory());
  146. params->array_buffer_allocator = g_array_buffer_allocator;
  147. params->allow_atomics_wait = true;
  148. params->external_references = g_reference_table;
  149. params->only_terminate_in_safe_scope = true;
  150. params->embedder_wrapper_type_index = kWrapperInfoIndex;
  151. params->embedder_wrapper_object_index = kEncodedValueIndex;
  152. params->fatal_error_callback = g_fatal_error_callback;
  153. params->oom_error_callback = g_oom_error_callback;
  154. return params;
  155. }
  156. void IsolateHolder::EnableIdleTasks(
  157. std::unique_ptr<V8IdleTaskRunner> idle_task_runner) {
  158. DCHECK(isolate_data_.get());
  159. isolate_data_->EnableIdleTasks(std::move(idle_task_runner));
  160. }
  161. } // namespace gin