// Copyright 2013 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/command_line.h" #include "base/memory/raw_ptr.h" #include "content/public/test/render_view_test.h" #include "gin/handle.h" #include "gin/per_isolate_data.h" #include "gin/wrappable.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/switches.h" #include "third_party/blink/public/web/web_local_frame.h" #include "third_party/blink/public/web/web_view.h" #include "v8/include/v8-context.h" namespace content { namespace { class TestGinObject : public gin::Wrappable { public: static gin::WrapperInfo kWrapperInfo; static gin::Handle Create(v8::Isolate* isolate, bool* alive) { return gin::CreateHandle(isolate, new TestGinObject(alive)); } TestGinObject(const TestGinObject&) = delete; TestGinObject& operator=(const TestGinObject&) = delete; private: TestGinObject(bool* alive) : alive_(alive) { *alive_ = true; } ~TestGinObject() override { *alive_ = false; } raw_ptr alive_; }; gin::WrapperInfo TestGinObject::kWrapperInfo = { gin::kEmbedderNativeGin }; class GinBrowserTest : public RenderViewTest { public: GinBrowserTest() {} GinBrowserTest(const GinBrowserTest&) = delete; GinBrowserTest& operator=(const GinBrowserTest&) = delete; ~GinBrowserTest() override {} void SetUp() override { base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( blink::switches::kJavaScriptFlags, "--expose_gc"); RenderViewTest::SetUp(); } }; // Test that garbage collection doesn't crash if a gin-wrapped object is // present. TEST_F(GinBrowserTest, GinAndGarbageCollection) { LoadHTML(""); bool alive = false; { v8::Isolate* isolate = Isolate(); v8::HandleScope handle_scope(isolate); v8::Context::Scope context_scope(GetMainFrame()->MainWorldScriptContext()); // We create the object inside a scope so it's not kept alive by a handle // on the stack. TestGinObject::Create(isolate, &alive); } CHECK(alive); // Should not crash. Isolate()->LowMemoryNotification(); CHECK(!alive); } } // namespace } // namespace content