blob: 9224725a1d9452a723f7594bc52b4747641b605a [file] [log] [blame]
[email protected]41fba0e2014-01-16 18:19:421// Copyright 2014 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
Scott Violetfdda96d2018-07-27 20:17:235#include "content/shell/test_runner/gc_controller.h"
[email protected]41fba0e2014-01-16 18:19:426
Sebastien Marchandf8cbfab2019-01-25 16:02:307#include "base/bind.h"
Michael Lippautz5b64e892018-09-24 11:10:008#include "content/shell/test_runner/test_interfaces.h"
9#include "content/shell/test_runner/web_test_delegate.h"
[email protected]41fba0e2014-01-16 18:19:4210#include "gin/arguments.h"
11#include "gin/handle.h"
12#include "gin/object_template_builder.h"
Blink Reformata30d4232018-04-07 15:31:0613#include "third_party/blink/public/web/blink.h"
14#include "third_party/blink/public/web/web_local_frame.h"
[email protected]41fba0e2014-01-16 18:19:4215#include "v8/include/v8.h"
16
danakj741848a2020-04-07 22:48:0617namespace content {
[email protected]41fba0e2014-01-16 18:19:4218
19gin::WrapperInfo GCController::kWrapperInfo = {gin::kEmbedderNativeGin};
20
21// static
Michael Lippautz5b64e892018-09-24 11:10:0022void GCController::Install(TestInterfaces* interfaces,
23 blink::WebLocalFrame* frame) {
Blink Reformat1c4d759e2017-04-09 16:34:5424 v8::Isolate* isolate = blink::MainThreadIsolate();
[email protected]41fba0e2014-01-16 18:19:4225 v8::HandleScope handle_scope(isolate);
Blink Reformat1c4d759e2017-04-09 16:34:5426 v8::Local<v8::Context> context = frame->MainWorldScriptContext();
[email protected]41fba0e2014-01-16 18:19:4227 if (context.IsEmpty())
28 return;
29
30 v8::Context::Scope context_scope(context);
31
32 gin::Handle<GCController> controller =
Michael Lippautz5b64e892018-09-24 11:10:0033 gin::CreateHandle(isolate, new GCController(interfaces));
[email protected]ad4d2032014-04-28 13:50:5934 if (controller.IsEmpty())
35 return;
deepak.s750d68f2015-04-30 07:32:4136 v8::Local<v8::Object> global = context->Global();
Dan Elphicka83be512019-02-05 15:57:2337 global
38 ->Set(context, gin::StringToV8(isolate, "GCController"),
39 controller.ToV8())
40 .Check();
[email protected]41fba0e2014-01-16 18:19:4241}
42
Michael Lippautz5b64e892018-09-24 11:10:0043GCController::GCController(TestInterfaces* interfaces)
44 : interfaces_(interfaces) {}
[email protected]41fba0e2014-01-16 18:19:4245
Michael Lippautz5b64e892018-09-24 11:10:0046GCController::~GCController() = default;
[email protected]41fba0e2014-01-16 18:19:4247
48gin::ObjectTemplateBuilder GCController::GetObjectTemplateBuilder(
49 v8::Isolate* isolate) {
50 return gin::Wrappable<GCController>::GetObjectTemplateBuilder(isolate)
51 .SetMethod("collect", &GCController::Collect)
[email protected]c7d90042014-02-05 08:25:1552 .SetMethod("collectAll", &GCController::CollectAll)
Michael Lippautz5b64e892018-09-24 11:10:0053 .SetMethod("minorCollect", &GCController::MinorCollect)
54 .SetMethod("asyncCollectAll", &GCController::AsyncCollectAll);
[email protected]41fba0e2014-01-16 18:19:4255}
56
57void GCController::Collect(const gin::Arguments& args) {
58 args.isolate()->RequestGarbageCollectionForTesting(
59 v8::Isolate::kFullGarbageCollection);
60}
61
[email protected]c7d90042014-02-05 08:25:1562void GCController::CollectAll(const gin::Arguments& args) {
Michael Lippautz5b64e892018-09-24 11:10:0063 for (int i = 0; i < kNumberOfGCsForFullCollection; i++) {
[email protected]c7d90042014-02-05 08:25:1564 args.isolate()->RequestGarbageCollectionForTesting(
65 v8::Isolate::kFullGarbageCollection);
66 }
67}
68
Michael Lippautz5b64e892018-09-24 11:10:0069void GCController::AsyncCollectAll(const gin::Arguments& args) {
Michael Lippautz584c69a82018-09-25 15:22:5170 v8::HandleScope scope(args.isolate());
71
72 if (args.PeekNext().IsEmpty() || !args.PeekNext()->IsFunction()) {
73 args.ThrowTypeError(
74 "asyncCollectAll should be called with a callback argument being a "
75 "v8::Function.");
76 return;
Michael Lippautz5b64e892018-09-24 11:10:0077 }
78
Michael Lippautz5b64e892018-09-24 11:10:0079 v8::UniquePersistent<v8::Function> func(
80 args.isolate(), v8::Local<v8::Function>::Cast(args.PeekNext()));
81
82 CHECK(interfaces_->GetDelegate());
83 CHECK(!func.IsEmpty());
84 interfaces_->GetDelegate()->PostTask(
85 base::BindOnce(&GCController::AsyncCollectAllWithEmptyStack,
86 base::Unretained(this), std::move(func)));
87}
88
89void GCController::AsyncCollectAllWithEmptyStack(
90 v8::UniquePersistent<v8::Function> callback) {
91 v8::Isolate* const isolate = blink::MainThreadIsolate();
92
93 for (int i = 0; i < kNumberOfGCsForFullCollection; i++) {
94 isolate->GetEmbedderHeapTracer()->GarbageCollectionForTesting(
95 v8::EmbedderHeapTracer::kEmpty);
96 }
97
98 v8::HandleScope scope(isolate);
99 v8::Local<v8::Function> func = callback.Get(isolate);
100 v8::Local<v8::Context> context = func->CreationContext();
101 v8::Context::Scope context_scope(context);
Michael Lippautz54f67af22019-01-08 15:41:57102 v8::TryCatch try_catch(isolate);
103 auto result = func->Call(context, context->Global(), 0, nullptr);
104 // Swallow potential exception.
105 ignore_result(result);
Michael Lippautz5b64e892018-09-24 11:10:00106}
107
[email protected]41fba0e2014-01-16 18:19:42108void GCController::MinorCollect(const gin::Arguments& args) {
109 args.isolate()->RequestGarbageCollectionForTesting(
110 v8::Isolate::kMinorGarbageCollection);
111}
112
danakj741848a2020-04-07 22:48:06113} // namespace content