Commit 7539549e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[api] Accept Extensions via unique_ptr

This way we can remove them correctly and avoid leaks.

R=mstarzinger@chromium.org, ulan@chromium.org

Bug: v8:8725
Change-Id: I52cbbf34a94171aaeb581b55aecb25311465544d
Reviewed-on: https://chromium-review.googlesource.com/c/1446453Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59266}
parent f9748aeb
...@@ -6489,8 +6489,8 @@ class V8_EXPORT Extension { // NOLINT ...@@ -6489,8 +6489,8 @@ class V8_EXPORT Extension { // NOLINT
const String::ExternalOneByteStringResource* source() const { const String::ExternalOneByteStringResource* source() const {
return source_; return source_;
} }
int dependency_count() { return dep_count_; } int dependency_count() const { return dep_count_; }
const char** dependencies() { return deps_; } const char** dependencies() const { return deps_; }
void set_auto_enable(bool value) { auto_enable_ = value; } void set_auto_enable(bool value) { auto_enable_ = value; }
bool auto_enable() { return auto_enable_; } bool auto_enable() { return auto_enable_; }
...@@ -6507,9 +6507,11 @@ class V8_EXPORT Extension { // NOLINT ...@@ -6507,9 +6507,11 @@ class V8_EXPORT Extension { // NOLINT
bool auto_enable_; bool auto_enable_;
}; };
V8_DEPRECATE_SOON(
"Use unique_ptr version or stop using extension (http://crbug.com/334679).",
void V8_EXPORT RegisterExtension(Extension* extension));
void V8_EXPORT RegisterExtension(Extension* extension); void V8_EXPORT RegisterExtension(std::unique_ptr<Extension>);
// --- Statics --- // --- Statics ---
......
...@@ -895,27 +895,31 @@ void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { ...@@ -895,27 +895,31 @@ void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
RegisteredExtension* RegisteredExtension::first_extension_ = nullptr; RegisteredExtension* RegisteredExtension::first_extension_ = nullptr;
RegisteredExtension::RegisteredExtension(Extension* extension) RegisteredExtension::RegisteredExtension(Extension* extension)
: extension_(extension) { } : legacy_unowned_extension_(extension) {}
RegisteredExtension::RegisteredExtension(std::unique_ptr<Extension> extension)
: extension_(std::move(extension)) {}
void RegisteredExtension::Register(RegisteredExtension* that) { // static
that->next_ = first_extension_; void RegisteredExtension::Register(Extension* extension) {
first_extension_ = that; RegisteredExtension* new_extension = new RegisteredExtension(extension);
new_extension->next_ = first_extension_;
first_extension_ = new_extension;
} }
// static
void RegisteredExtension::Register(std::unique_ptr<Extension> extension) {
RegisteredExtension* new_extension =
new RegisteredExtension(std::move(extension));
new_extension->next_ = first_extension_;
first_extension_ = new_extension;
}
// static
void RegisteredExtension::UnregisterAll() { void RegisteredExtension::UnregisterAll() {
// Keep a list of all leaked Extension objects, to suppress ASan leak reports.
// We cannot suppress via lsan suppressions, since the objects are allocated
// at different call sites.
// TODO(clemensh): Fix this (https://crbug.com/v8/8725).
static std::vector<Extension*>* leaked_extensions =
new std::vector<Extension*>;
RegisteredExtension* re = first_extension_; RegisteredExtension* re = first_extension_;
while (re != nullptr) { while (re != nullptr) {
RegisteredExtension* next = re->next(); RegisteredExtension* next = re->next();
leaked_extensions->push_back(re->extension_);
delete re; delete re;
re = next; re = next;
} }
...@@ -938,11 +942,11 @@ class ExtensionResource : public String::ExternalOneByteStringResource { ...@@ -938,11 +942,11 @@ class ExtensionResource : public String::ExternalOneByteStringResource {
}; };
} // anonymous namespace } // anonymous namespace
void RegisterExtension(Extension* that) { void RegisterExtension(Extension* that) { RegisteredExtension::Register(that); }
RegisteredExtension* extension = new RegisteredExtension(that);
RegisteredExtension::Register(extension);
}
void RegisterExtension(std::unique_ptr<Extension> extension) {
RegisteredExtension::Register(std::move(extension));
}
Extension::Extension(const char* name, Extension::Extension(const char* name,
const char* source, const char* source,
......
...@@ -66,15 +66,22 @@ class ApiFunction { ...@@ -66,15 +66,22 @@ class ApiFunction {
class RegisteredExtension { class RegisteredExtension {
public: public:
explicit RegisteredExtension(Extension* extension); static void Register(Extension*);
static void Register(RegisteredExtension* that); static void Register(std::unique_ptr<Extension>);
static void UnregisterAll(); static void UnregisterAll();
Extension* extension() { return extension_; } Extension* extension() const {
RegisteredExtension* next() { return next_; } return legacy_unowned_extension_ ? legacy_unowned_extension_
: extension_.get();
}
RegisteredExtension* next() const { return next_; }
static RegisteredExtension* first_extension() { return first_extension_; } static RegisteredExtension* first_extension() { return first_extension_; }
private: private:
Extension* extension_; explicit RegisteredExtension(Extension*);
RegisteredExtension* next_; explicit RegisteredExtension(std::unique_ptr<Extension>);
// TODO(clemensh): Remove this after the 7.4 branch.
Extension* legacy_unowned_extension_ = nullptr;
std::unique_ptr<Extension> extension_;
RegisteredExtension* next_ = nullptr;
static RegisteredExtension* first_extension_; static RegisteredExtension* first_extension_;
}; };
......
...@@ -121,42 +121,13 @@ static const char* GCFunctionName() { ...@@ -121,42 +121,13 @@ static const char* GCFunctionName() {
return flag_given ? FLAG_expose_gc_as : "gc"; return flag_given ? FLAG_expose_gc_as : "gc";
} }
v8::Extension* Bootstrapper::free_buffer_extension_ = nullptr;
v8::Extension* Bootstrapper::gc_extension_ = nullptr;
v8::Extension* Bootstrapper::externalize_string_extension_ = nullptr;
v8::Extension* Bootstrapper::statistics_extension_ = nullptr;
v8::Extension* Bootstrapper::trigger_failure_extension_ = nullptr;
v8::Extension* Bootstrapper::ignition_statistics_extension_ = nullptr;
void Bootstrapper::InitializeOncePerProcess() { void Bootstrapper::InitializeOncePerProcess() {
free_buffer_extension_ = new FreeBufferExtension; v8::RegisterExtension(v8::base::make_unique<FreeBufferExtension>());
v8::RegisterExtension(free_buffer_extension_); v8::RegisterExtension(v8::base::make_unique<GCExtension>(GCFunctionName()));
gc_extension_ = new GCExtension(GCFunctionName()); v8::RegisterExtension(v8::base::make_unique<ExternalizeStringExtension>());
v8::RegisterExtension(gc_extension_); v8::RegisterExtension(v8::base::make_unique<StatisticsExtension>());
externalize_string_extension_ = new ExternalizeStringExtension; v8::RegisterExtension(v8::base::make_unique<TriggerFailureExtension>());
v8::RegisterExtension(externalize_string_extension_); v8::RegisterExtension(v8::base::make_unique<IgnitionStatisticsExtension>());
statistics_extension_ = new StatisticsExtension;
v8::RegisterExtension(statistics_extension_);
trigger_failure_extension_ = new TriggerFailureExtension;
v8::RegisterExtension(trigger_failure_extension_);
ignition_statistics_extension_ = new IgnitionStatisticsExtension;
v8::RegisterExtension(ignition_statistics_extension_);
}
void Bootstrapper::TearDownExtensions() {
delete free_buffer_extension_;
free_buffer_extension_ = nullptr;
delete gc_extension_;
gc_extension_ = nullptr;
delete externalize_string_extension_;
externalize_string_extension_ = nullptr;
delete statistics_extension_;
statistics_extension_ = nullptr;
delete trigger_failure_extension_;
trigger_failure_extension_ = nullptr;
delete ignition_statistics_extension_;
ignition_statistics_extension_ = nullptr;
} }
void Bootstrapper::TearDown() { void Bootstrapper::TearDown() {
......
...@@ -46,7 +46,6 @@ class SourceCodeCache final { ...@@ -46,7 +46,6 @@ class SourceCodeCache final {
class Bootstrapper final { class Bootstrapper final {
public: public:
static void InitializeOncePerProcess(); static void InitializeOncePerProcess();
static void TearDownExtensions();
// Requires: Heap::SetUp has been called. // Requires: Heap::SetUp has been called.
void Initialize(bool create_heap_objects); void Initialize(bool create_heap_objects);
...@@ -109,13 +108,6 @@ class Bootstrapper final { ...@@ -109,13 +108,6 @@ class Bootstrapper final {
explicit Bootstrapper(Isolate* isolate); explicit Bootstrapper(Isolate* isolate);
static v8::Extension* free_buffer_extension_;
static v8::Extension* gc_extension_;
static v8::Extension* externalize_string_extension_;
static v8::Extension* statistics_extension_;
static v8::Extension* trigger_failure_extension_;
static v8::Extension* ignition_statistics_extension_;
DISALLOW_COPY_AND_ASSIGN(Bootstrapper); DISALLOW_COPY_AND_ASSIGN(Bootstrapper);
}; };
......
...@@ -53,7 +53,6 @@ void V8::TearDown() { ...@@ -53,7 +53,6 @@ void V8::TearDown() {
Simulator::GlobalTearDown(); Simulator::GlobalTearDown();
#endif #endif
CallDescriptors::TearDown(); CallDescriptors::TearDown();
Bootstrapper::TearDownExtensions();
ElementsAccessor::TearDown(); ElementsAccessor::TearDown();
RegisteredExtension::UnregisterAll(); RegisteredExtension::UnregisterAll();
FlagList::ResetAllFlags(); // Frees memory held by string arguments. FlagList::ResetAllFlags(); // Frees memory held by string arguments.
......
...@@ -315,12 +315,9 @@ int main(int argc, char* argv[]) { ...@@ -315,12 +315,9 @@ int main(int argc, char* argv[]) {
CcTest::set_array_buffer_allocator( CcTest::set_array_buffer_allocator(
v8::ArrayBuffer::Allocator::NewDefaultAllocator()); v8::ArrayBuffer::Allocator::NewDefaultAllocator());
i::PrintExtension print_extension; v8::RegisterExtension(v8::base::make_unique<i::PrintExtension>());
v8::RegisterExtension(&print_extension); v8::RegisterExtension(v8::base::make_unique<i::ProfilerExtension>());
i::ProfilerExtension profiler_extension; v8::RegisterExtension(v8::base::make_unique<i::TraceExtension>());
v8::RegisterExtension(&profiler_extension);
i::TraceExtension trace_extension;
v8::RegisterExtension(&trace_extension);
int tests_run = 0; int tests_run = 0;
bool print_run_count = true; bool print_run_count = true;
......
This diff is collapsed.
...@@ -2949,8 +2949,8 @@ TEST(NoBreakWhenBootstrapping) { ...@@ -2949,8 +2949,8 @@ TEST(NoBreakWhenBootstrapping) {
{ {
// Create a context with an extension to make sure that some JavaScript // Create a context with an extension to make sure that some JavaScript
// code is executed during bootstrapping. // code is executed during bootstrapping.
v8::RegisterExtension(new v8::Extension("simpletest", v8::RegisterExtension(v8::base::make_unique<v8::Extension>(
kSimpleExtensionSource)); "simpletest", kSimpleExtensionSource));
const char* extension_names[] = { "simpletest" }; const char* extension_names[] = { "simpletest" };
v8::ExtensionConfiguration extensions(1, extension_names); v8::ExtensionConfiguration extensions(1, extension_names);
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
......
...@@ -943,25 +943,12 @@ TEST(ExtensionsRegistration) { ...@@ -943,25 +943,12 @@ TEST(ExtensionsRegistration) {
#else #else
const int kNThreads = 40; const int kNThreads = 40;
#endif #endif
v8::RegisterExtension(new v8::Extension("test0", const char* extension_names[] = {"test0", "test1", "test2", "test3",
kSimpleExtensionSource)); "test4", "test5", "test6", "test7"};
v8::RegisterExtension(new v8::Extension("test1", for (const char* name : extension_names) {
kSimpleExtensionSource)); v8::RegisterExtension(
v8::RegisterExtension(new v8::Extension("test2", v8::base::make_unique<v8::Extension>(name, kSimpleExtensionSource));
kSimpleExtensionSource)); }
v8::RegisterExtension(new v8::Extension("test3",
kSimpleExtensionSource));
v8::RegisterExtension(new v8::Extension("test4",
kSimpleExtensionSource));
v8::RegisterExtension(new v8::Extension("test5",
kSimpleExtensionSource));
v8::RegisterExtension(new v8::Extension("test6",
kSimpleExtensionSource));
v8::RegisterExtension(new v8::Extension("test7",
kSimpleExtensionSource));
const char* extension_names[] = { "test0", "test1",
"test2", "test3", "test4",
"test5", "test6", "test7" };
std::vector<JoinableThread*> threads; std::vector<JoinableThread*> threads;
threads.reserve(kNThreads); threads.reserve(kNThreads);
for (int i = 0; i < kNThreads; i++) { for (int i = 0; i < kNThreads; i++) {
......
...@@ -3554,14 +3554,15 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) { ...@@ -3554,14 +3554,15 @@ UNINITIALIZED_TEST(SnapshotCreatorIncludeGlobalProxy) {
v8::Isolate::Scope isolate_scope(isolate); v8::Isolate::Scope isolate_scope(isolate);
// We can introduce new extensions, which could override functions already // We can introduce new extensions, which could override functions already
// in the snapshot. // in the snapshot.
v8::Extension* extension = new v8::Extension("new extension", auto extension =
"function i() { return 24; }" base::make_unique<v8::Extension>("new extension",
"function j() { return 25; }" "function i() { return 24; }"
"try {" "function j() { return 25; }"
" if (o.p == 7) o.p++;" "try {"
"} catch {}"); " if (o.p == 7) o.p++;"
"} catch {}");
extension->set_auto_enable(true); extension->set_auto_enable(true);
v8::RegisterExtension(extension); v8::RegisterExtension(std::move(extension));
{ {
// Create a new context from default context snapshot. This will // Create a new context from default context snapshot. This will
// create a new global object from a new global object template // create a new global object from a new global object template
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment