blob: c9b46e25a865c63791582ff8cb87d0dd26bb2893 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2014 The Chromium Authors
[email protected]41fba0e2014-01-16 18:19:422// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
danakj89f47082020-09-02 17:53:435#include "content/web_test/renderer/gc_controller.h"
[email protected]41fba0e2014-01-16 18:19:426
Avi Drissman5d5d48d62022-01-07 20:23:587#include <tuple>
8
Sebastien Marchandf8cbfab2019-01-25 16:02:309#include "base/bind.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
danakjc989ac72020-04-15 20:31:2322void GCController::Install(blink::WebLocalFrame* frame) {
Blink Reformat1c4d759e2017-04-09 16:34:5423 v8::Isolate* isolate = blink::MainThreadIsolate();
[email protected]41fba0e2014-01-16 18:19:4224 v8::HandleScope handle_scope(isolate);
Blink Reformat1c4d759e2017-04-09 16:34:5425 v8::Local<v8::Context> context = frame->MainWorldScriptContext();
[email protected]41fba0e2014-01-16 18:19:4226 if (context.IsEmpty())
27 return;
28
29 v8::Context::Scope context_scope(context);
30
31 gin::Handle<GCController> controller =
danakjc989ac72020-04-15 20:31:2332 gin::CreateHandle(isolate, new GCController(frame));
[email protected]ad4d2032014-04-28 13:50:5933 if (controller.IsEmpty())
34 return;
deepak.s750d68f2015-04-30 07:32:4135 v8::Local<v8::Object> global = context->Global();
Dan Elphicka83be512019-02-05 15:57:2336 global
37 ->Set(context, gin::StringToV8(isolate, "GCController"),
38 controller.ToV8())
39 .Check();
[email protected]41fba0e2014-01-16 18:19:4240}
41
danakjc989ac72020-04-15 20:31:2342GCController::GCController(blink::WebLocalFrame* frame) : frame_(frame) {}
[email protected]41fba0e2014-01-16 18:19:4243
Michael Lippautz5b64e892018-09-24 11:10:0044GCController::~GCController() = default;
[email protected]41fba0e2014-01-16 18:19:4245
46gin::ObjectTemplateBuilder GCController::GetObjectTemplateBuilder(
47 v8::Isolate* isolate) {
48 return gin::Wrappable<GCController>::GetObjectTemplateBuilder(isolate)
49 .SetMethod("collect", &GCController::Collect)
[email protected]c7d90042014-02-05 08:25:1550 .SetMethod("collectAll", &GCController::CollectAll)
Michael Lippautz5b64e892018-09-24 11:10:0051 .SetMethod("minorCollect", &GCController::MinorCollect)
52 .SetMethod("asyncCollectAll", &GCController::AsyncCollectAll);
[email protected]41fba0e2014-01-16 18:19:4253}
54
55void GCController::Collect(const gin::Arguments& args) {
56 args.isolate()->RequestGarbageCollectionForTesting(
57 v8::Isolate::kFullGarbageCollection);
58}
59
[email protected]c7d90042014-02-05 08:25:1560void GCController::CollectAll(const gin::Arguments& args) {
Michael Lippautz5b64e892018-09-24 11:10:0061 for (int i = 0; i < kNumberOfGCsForFullCollection; i++) {
[email protected]c7d90042014-02-05 08:25:1562 args.isolate()->RequestGarbageCollectionForTesting(
63 v8::Isolate::kFullGarbageCollection);
64 }
65}
66
Michael Lippautz5b64e892018-09-24 11:10:0067void GCController::AsyncCollectAll(const gin::Arguments& args) {
Michael Lippautz584c69a82018-09-25 15:22:5168 v8::HandleScope scope(args.isolate());
69
70 if (args.PeekNext().IsEmpty() || !args.PeekNext()->IsFunction()) {
71 args.ThrowTypeError(
72 "asyncCollectAll should be called with a callback argument being a "
73 "v8::Function.");
74 return;
Michael Lippautz5b64e892018-09-24 11:10:0075 }
danakjc989ac72020-04-15 20:31:2376 v8::UniquePersistent<v8::Function> js_callback(
Michael Lippautz5b64e892018-09-24 11:10:0077 args.isolate(), v8::Local<v8::Function>::Cast(args.PeekNext()));
78
danakjc989ac72020-04-15 20:31:2379 // Bind the js callback into a OnceClosure that will be run asynchronously in
80 // a fresh call stack.
81 base::OnceClosure run_async =
Michael Lippautz5b64e892018-09-24 11:10:0082 base::BindOnce(&GCController::AsyncCollectAllWithEmptyStack,
danakjc989ac72020-04-15 20:31:2383 weak_ptr_factory_.GetWeakPtr(), std::move(js_callback));
84 frame_->GetTaskRunner(blink::TaskType::kInternalTest)
85 ->PostTask(FROM_HERE, std::move(run_async));
Michael Lippautz5b64e892018-09-24 11:10:0086}
87
88void GCController::AsyncCollectAllWithEmptyStack(
89 v8::UniquePersistent<v8::Function> callback) {
90 v8::Isolate* const isolate = blink::MainThreadIsolate();
91
92 for (int i = 0; i < kNumberOfGCsForFullCollection; i++) {
Omer Katzb65361a42021-11-22 21:46:4993 isolate->RequestGarbageCollectionForTesting(
94 v8::Isolate::kFullGarbageCollection,
Michael Lippautzac8bee72020-12-14 11:31:4295 v8::EmbedderHeapTracer::EmbedderStackState::kNoHeapPointers);
Michael Lippautz5b64e892018-09-24 11:10:0096 }
97
98 v8::HandleScope scope(isolate);
99 v8::Local<v8::Function> func = callback.Get(isolate);
Camillo Bruni1109e282021-12-14 15:53:13100 v8::Local<v8::Context> context = func->GetCreationContextChecked();
Michael Lippautz5b64e892018-09-24 11:10:00101 v8::Context::Scope context_scope(context);
Michael Lippautz54f67af22019-01-08 15:41:57102 v8::TryCatch try_catch(isolate);
Jochen Eisinger68f332862021-04-29 08:19:20103 v8::MicrotasksScope microtasks_scope(
104 isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
Michael Lippautz54f67af22019-01-08 15:41:57105 auto result = func->Call(context, context->Global(), 0, nullptr);
106 // Swallow potential exception.
Avi Drissman5d5d48d62022-01-07 20:23:58107 std::ignore = result;
Michael Lippautz5b64e892018-09-24 11:10:00108}
109
[email protected]41fba0e2014-01-16 18:19:42110void GCController::MinorCollect(const gin::Arguments& args) {
111 args.isolate()->RequestGarbageCollectionForTesting(
112 v8::Isolate::kMinorGarbageCollection);
113}
114
danakj741848a2020-04-07 22:48:06115} // namespace content