| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 1 | // 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 Violet | fdda96d | 2018-07-27 20:17:23 | [diff] [blame] | 5 | #include "content/shell/test_runner/gc_controller.h" |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 6 | |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 7 | #include "content/shell/test_runner/test_interfaces.h" |
| 8 | #include "content/shell/test_runner/web_test_delegate.h" |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 9 | #include "gin/arguments.h" |
| 10 | #include "gin/handle.h" |
| 11 | #include "gin/object_template_builder.h" |
| Blink Reformat | a30d423 | 2018-04-07 15:31:06 | [diff] [blame] | 12 | #include "third_party/blink/public/web/blink.h" |
| 13 | #include "third_party/blink/public/web/web_local_frame.h" |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 14 | #include "v8/include/v8.h" |
| 15 | |
| sadrul | 4340577 | 2015-10-15 23:12:37 | [diff] [blame] | 16 | namespace test_runner { |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 17 | |
| 18 | gin::WrapperInfo GCController::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| 19 | |
| 20 | // static |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 21 | void GCController::Install(TestInterfaces* interfaces, |
| 22 | blink::WebLocalFrame* frame) { |
| Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 23 | v8::Isolate* isolate = blink::MainThreadIsolate(); |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 24 | v8::HandleScope handle_scope(isolate); |
| Blink Reformat | 1c4d759e | 2017-04-09 16:34:54 | [diff] [blame] | 25 | v8::Local<v8::Context> context = frame->MainWorldScriptContext(); |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 26 | if (context.IsEmpty()) |
| 27 | return; |
| 28 | |
| 29 | v8::Context::Scope context_scope(context); |
| 30 | |
| 31 | gin::Handle<GCController> controller = |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 32 | gin::CreateHandle(isolate, new GCController(interfaces)); |
| [email protected] | ad4d203 | 2014-04-28 13:50:59 | [diff] [blame] | 33 | if (controller.IsEmpty()) |
| 34 | return; |
| deepak.s | 750d68f | 2015-04-30 07:32:41 | [diff] [blame] | 35 | v8::Local<v8::Object> global = context->Global(); |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 36 | global->Set(gin::StringToV8(isolate, "GCController"), controller.ToV8()); |
| 37 | } |
| 38 | |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 39 | GCController::GCController(TestInterfaces* interfaces) |
| 40 | : interfaces_(interfaces) {} |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 41 | |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 42 | GCController::~GCController() = default; |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 43 | |
| 44 | gin::ObjectTemplateBuilder GCController::GetObjectTemplateBuilder( |
| 45 | v8::Isolate* isolate) { |
| 46 | return gin::Wrappable<GCController>::GetObjectTemplateBuilder(isolate) |
| 47 | .SetMethod("collect", &GCController::Collect) |
| [email protected] | c7d9004 | 2014-02-05 08:25:15 | [diff] [blame] | 48 | .SetMethod("collectAll", &GCController::CollectAll) |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 49 | .SetMethod("minorCollect", &GCController::MinorCollect) |
| 50 | .SetMethod("asyncCollectAll", &GCController::AsyncCollectAll); |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 51 | } |
| 52 | |
| 53 | void GCController::Collect(const gin::Arguments& args) { |
| 54 | args.isolate()->RequestGarbageCollectionForTesting( |
| 55 | v8::Isolate::kFullGarbageCollection); |
| 56 | } |
| 57 | |
| [email protected] | c7d9004 | 2014-02-05 08:25:15 | [diff] [blame] | 58 | void GCController::CollectAll(const gin::Arguments& args) { |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 59 | for (int i = 0; i < kNumberOfGCsForFullCollection; i++) { |
| [email protected] | c7d9004 | 2014-02-05 08:25:15 | [diff] [blame] | 60 | args.isolate()->RequestGarbageCollectionForTesting( |
| 61 | v8::Isolate::kFullGarbageCollection); |
| 62 | } |
| 63 | } |
| 64 | |
| Michael Lippautz | 5b64e89 | 2018-09-24 11:10:00 | [diff] [blame^] | 65 | void GCController::AsyncCollectAll(const gin::Arguments& args) { |
| 66 | if (args.PeekNext().IsEmpty()) { |
| 67 | NOTREACHED() << "AsyncCollectAll should be called with callback argument."; |
| 68 | } |
| 69 | |
| 70 | v8::HandleScope scope(args.isolate()); |
| 71 | v8::UniquePersistent<v8::Function> func( |
| 72 | args.isolate(), v8::Local<v8::Function>::Cast(args.PeekNext())); |
| 73 | |
| 74 | CHECK(interfaces_->GetDelegate()); |
| 75 | CHECK(!func.IsEmpty()); |
| 76 | interfaces_->GetDelegate()->PostTask( |
| 77 | base::BindOnce(&GCController::AsyncCollectAllWithEmptyStack, |
| 78 | base::Unretained(this), std::move(func))); |
| 79 | } |
| 80 | |
| 81 | void GCController::AsyncCollectAllWithEmptyStack( |
| 82 | v8::UniquePersistent<v8::Function> callback) { |
| 83 | v8::Isolate* const isolate = blink::MainThreadIsolate(); |
| 84 | |
| 85 | for (int i = 0; i < kNumberOfGCsForFullCollection; i++) { |
| 86 | isolate->GetEmbedderHeapTracer()->GarbageCollectionForTesting( |
| 87 | v8::EmbedderHeapTracer::kEmpty); |
| 88 | } |
| 89 | |
| 90 | v8::HandleScope scope(isolate); |
| 91 | v8::Local<v8::Function> func = callback.Get(isolate); |
| 92 | v8::Local<v8::Context> context = func->CreationContext(); |
| 93 | v8::Context::Scope context_scope(context); |
| 94 | func->Call(context, v8::Undefined(isolate), 0, nullptr).ToLocalChecked(); |
| 95 | } |
| 96 | |
| [email protected] | 41fba0e | 2014-01-16 18:19:42 | [diff] [blame] | 97 | void GCController::MinorCollect(const gin::Arguments& args) { |
| 98 | args.isolate()->RequestGarbageCollectionForTesting( |
| 99 | v8::Isolate::kMinorGarbageCollection); |
| 100 | } |
| 101 | |
| sadrul | 4340577 | 2015-10-15 23:12:37 | [diff] [blame] | 102 | } // namespace test_runner |