15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/shell/renderer/gc_controller.h" 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/arguments.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/handle.h" 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gin/object_template_builder.h" 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebKit.h" 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "v8/include/v8.h" 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content { 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gin::WrapperInfo GCController::kWrapperInfo = {gin::kEmbedderNativeGin}; 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GCController::Install(blink::WebFrame* frame) { 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Isolate* isolate = blink::mainThreadIsolate(); 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::HandleScope handle_scope(isolate); 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Handle<v8::Context> context = frame->mainWorldScriptContext(); 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (context.IsEmpty()) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Context::Scope context_scope(context); 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gin::Handle<GCController> controller = 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) gin::CreateHandle(isolate, new GCController()); 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (controller.IsEmpty()) 315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return; 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Handle<v8::Object> global = context->Global(); 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) global->Set(gin::StringToV8(isolate, "GCController"), controller.ToV8()); 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GCController::GCController() {} 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)GCController::~GCController() {} 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gin::ObjectTemplateBuilder GCController::GetObjectTemplateBuilder( 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Isolate* isolate) { 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return gin::Wrappable<GCController>::GetObjectTemplateBuilder(isolate) 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .SetMethod("collect", &GCController::Collect) 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .SetMethod("collectAll", &GCController::CollectAll) 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .SetMethod("minorCollect", &GCController::MinorCollect); 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GCController::Collect(const gin::Arguments& args) { 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.isolate()->RequestGarbageCollectionForTesting( 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Isolate::kFullGarbageCollection); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GCController::CollectAll(const gin::Arguments& args) { 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In order to collect a DOM wrapper, two GC cycles are needed. 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In the first GC cycle, a weak callback of the DOM wrapper is called back 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // and the weak callback disposes a persistent handle to the DOM wrapper. 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In the second GC cycle, the DOM wrapper is reclaimed. 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Given that two GC cycles are needed to collect one DOM wrapper, 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // more than two GC cycles are needed to collect all DOM wrappers 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // that are chained. Seven GC cycles look enough in most tests. 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (int i = 0; i < 7; i++) { 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.isolate()->RequestGarbageCollectionForTesting( 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Isolate::kFullGarbageCollection); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void GCController::MinorCollect(const gin::Arguments& args) { 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) args.isolate()->RequestGarbageCollectionForTesting( 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) v8::Isolate::kMinorGarbageCollection); 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace content 73