| Index: third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
|
| diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
|
| deleted file mode 100644
|
| index 4c6c71f007c4a75926dd5256bf7abd2d722a8ff8..0000000000000000000000000000000000000000
|
| --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableVisitor.cpp
|
| +++ /dev/null
|
| @@ -1,314 +0,0 @@
|
| -// Copyright 2016 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "bindings/core/v8/ScriptWrappableVisitor.h"
|
| -
|
| -#include "bindings/core/v8/ActiveScriptWrappable.h"
|
| -#include "bindings/core/v8/DOMWrapperWorld.h"
|
| -#include "bindings/core/v8/ScopedPersistent.h"
|
| -#include "bindings/core/v8/ScriptWrappable.h"
|
| -#include "bindings/core/v8/ScriptWrappableVisitorVerifier.h"
|
| -#include "bindings/core/v8/V8AbstractEventListener.h"
|
| -#include "bindings/core/v8/WrapperTypeInfo.h"
|
| -#include "core/dom/DocumentStyleSheetCollection.h"
|
| -#include "core/dom/ElementRareData.h"
|
| -#include "core/dom/NodeListsNodeData.h"
|
| -#include "core/dom/NodeRareData.h"
|
| -#include "core/dom/StyleEngine.h"
|
| -#include "core/dom/shadow/ElementShadow.h"
|
| -#include "core/html/imports/HTMLImportsController.h"
|
| -#include "platform/heap/HeapCompact.h"
|
| -#include "platform/heap/HeapPage.h"
|
| -#include "platform/scheduler/child/web_scheduler.h"
|
| -#include "platform/wtf/AutoReset.h"
|
| -#include "public/platform/Platform.h"
|
| -
|
| -namespace blink {
|
| -
|
| -ScriptWrappableVisitor::~ScriptWrappableVisitor() {}
|
| -
|
| -void ScriptWrappableVisitor::TracePrologue() {
|
| - // This CHECK ensures that wrapper tracing is not started from scopes
|
| - // that forbid GC execution, e.g., constructors.
|
| - CHECK(ThreadState::Current());
|
| - CHECK(!ThreadState::Current()->IsWrapperTracingForbidden());
|
| - PerformCleanup();
|
| -
|
| - CHECK(!tracing_in_progress_);
|
| - CHECK(!should_cleanup_);
|
| - CHECK(headers_to_unmark_.IsEmpty());
|
| - CHECK(marking_deque_.IsEmpty());
|
| - CHECK(verifier_deque_.IsEmpty());
|
| - tracing_in_progress_ = true;
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::EnterFinalPause() {
|
| - CHECK(ThreadState::Current());
|
| - CHECK(!ThreadState::Current()->IsWrapperTracingForbidden());
|
| - ActiveScriptWrappableBase::TraceActiveScriptWrappables(isolate_, this);
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::TraceEpilogue() {
|
| - CHECK(ThreadState::Current());
|
| - CHECK(!ThreadState::Current()->IsWrapperTracingForbidden());
|
| - DCHECK(marking_deque_.IsEmpty());
|
| -#if DCHECK_IS_ON()
|
| - ScriptWrappableVisitorVerifier verifier;
|
| - for (auto& marking_data : verifier_deque_) {
|
| - marking_data.TraceWrappers(&verifier);
|
| - }
|
| -#endif
|
| -
|
| - should_cleanup_ = true;
|
| - tracing_in_progress_ = false;
|
| - ScheduleIdleLazyCleanup();
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::AbortTracing() {
|
| - CHECK(ThreadState::Current());
|
| - should_cleanup_ = true;
|
| - tracing_in_progress_ = false;
|
| - PerformCleanup();
|
| -}
|
| -
|
| -size_t ScriptWrappableVisitor::NumberOfWrappersToTrace() {
|
| - CHECK(ThreadState::Current());
|
| - return marking_deque_.size();
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::PerformCleanup() {
|
| - if (!should_cleanup_)
|
| - return;
|
| -
|
| - CHECK(!tracing_in_progress_);
|
| - for (auto header : headers_to_unmark_) {
|
| - // Dead objects residing in the marking deque may become invalid due to
|
| - // minor garbage collections and are therefore set to nullptr. We have
|
| - // to skip over such objects.
|
| - if (header)
|
| - header->UnmarkWrapperHeader();
|
| - }
|
| -
|
| - headers_to_unmark_.clear();
|
| - marking_deque_.clear();
|
| - verifier_deque_.clear();
|
| - should_cleanup_ = false;
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::ScheduleIdleLazyCleanup() {
|
| - // Some threads (e.g. PPAPI thread) don't have a scheduler.
|
| - if (!Platform::Current()->CurrentThread()->Scheduler())
|
| - return;
|
| -
|
| - if (idle_cleanup_task_scheduled_)
|
| - return;
|
| -
|
| - Platform::Current()->CurrentThread()->Scheduler()->PostIdleTask(
|
| - BLINK_FROM_HERE, WTF::Bind(&ScriptWrappableVisitor::PerformLazyCleanup,
|
| - WTF::Unretained(this)));
|
| - idle_cleanup_task_scheduled_ = true;
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::PerformLazyCleanup(double deadline_seconds) {
|
| - idle_cleanup_task_scheduled_ = false;
|
| -
|
| - if (!should_cleanup_)
|
| - return;
|
| -
|
| - TRACE_EVENT1("blink_gc,devtools.timeline",
|
| - "ScriptWrappableVisitor::performLazyCleanup",
|
| - "idleDeltaInSeconds",
|
| - deadline_seconds - MonotonicallyIncreasingTime());
|
| -
|
| - const int kDeadlineCheckInterval = 2500;
|
| - int processed_wrapper_count = 0;
|
| - for (auto it = headers_to_unmark_.rbegin();
|
| - it != headers_to_unmark_.rend();) {
|
| - auto header = *it;
|
| - // Dead objects residing in the marking deque may become invalid due to
|
| - // minor garbage collections and are therefore set to nullptr. We have
|
| - // to skip over such objects.
|
| - if (header)
|
| - header->UnmarkWrapperHeader();
|
| -
|
| - ++it;
|
| - headers_to_unmark_.pop_back();
|
| -
|
| - processed_wrapper_count++;
|
| - if (processed_wrapper_count % kDeadlineCheckInterval == 0) {
|
| - if (deadline_seconds <= MonotonicallyIncreasingTime()) {
|
| - ScheduleIdleLazyCleanup();
|
| - return;
|
| - }
|
| - }
|
| - }
|
| -
|
| - // Unmarked all headers.
|
| - CHECK(headers_to_unmark_.IsEmpty());
|
| - marking_deque_.clear();
|
| - verifier_deque_.clear();
|
| - should_cleanup_ = false;
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::RegisterV8Reference(
|
| - const std::pair<void*, void*>& internal_fields) {
|
| - if (!tracing_in_progress_) {
|
| - return;
|
| - }
|
| -
|
| - WrapperTypeInfo* wrapper_type_info =
|
| - reinterpret_cast<WrapperTypeInfo*>(internal_fields.first);
|
| - if (wrapper_type_info->gin_embedder != gin::GinEmbedder::kEmbedderBlink) {
|
| - return;
|
| - }
|
| - DCHECK(wrapper_type_info->wrapper_class_id == WrapperTypeInfo::kNodeClassId ||
|
| - wrapper_type_info->wrapper_class_id ==
|
| - WrapperTypeInfo::kObjectClassId);
|
| -
|
| - ScriptWrappable* script_wrappable =
|
| - reinterpret_cast<ScriptWrappable*>(internal_fields.second);
|
| -
|
| - wrapper_type_info->TraceWrappers(this, script_wrappable);
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::RegisterV8References(
|
| - const std::vector<std::pair<void*, void*>>&
|
| - internal_fields_of_potential_wrappers) {
|
| - CHECK(ThreadState::Current());
|
| - // TODO(hlopko): Visit the vector in the V8 instead of passing it over if
|
| - // there is no performance impact
|
| - for (auto& pair : internal_fields_of_potential_wrappers) {
|
| - RegisterV8Reference(pair);
|
| - }
|
| -}
|
| -
|
| -bool ScriptWrappableVisitor::AdvanceTracing(
|
| - double deadline_in_ms,
|
| - v8::EmbedderHeapTracer::AdvanceTracingActions actions) {
|
| - // Do not drain the marking deque in a state where we can generally not
|
| - // perform a GC. This makes sure that TraceTraits and friends find
|
| - // themselves in a well-defined environment, e.g., properly set up vtables.
|
| - CHECK(ThreadState::Current());
|
| - CHECK(!ThreadState::Current()->IsWrapperTracingForbidden());
|
| - CHECK(tracing_in_progress_);
|
| - WTF::AutoReset<bool>(&advancing_tracing_, true);
|
| - while (actions.force_completion ==
|
| - v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION ||
|
| - WTF::MonotonicallyIncreasingTimeMS() < deadline_in_ms) {
|
| - if (marking_deque_.IsEmpty()) {
|
| - return false;
|
| - }
|
| - marking_deque_.TakeFirst().TraceWrappers(this);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool ScriptWrappableVisitor::MarkWrapperHeader(HeapObjectHeader* header) const {
|
| - if (header->IsWrapperHeaderMarked())
|
| - return false;
|
| -
|
| - // Verify that no compactable & movable objects are slated for
|
| - // lazy unmarking.
|
| - DCHECK(!HeapCompact::IsCompactableArena(
|
| - PageFromObject(header)->Arena()->ArenaIndex()));
|
| - header->MarkWrapperHeader();
|
| - headers_to_unmark_.push_back(header);
|
| - return true;
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::MarkWrappersInAllWorlds(
|
| - const ScriptWrappable* script_wrappable) const {
|
| - DOMWrapperWorld::MarkWrappersInAllWorlds(
|
| - const_cast<ScriptWrappable*>(script_wrappable), this);
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::WriteBarrier(
|
| - v8::Isolate* isolate,
|
| - const void* src_object,
|
| - const TraceWrapperV8Reference<v8::Value>* dst_object) {
|
| - if (!src_object || !dst_object || dst_object->IsEmpty()) {
|
| - return;
|
| - }
|
| - // We only require a write barrier if |srcObject| is already marked. Note
|
| - // that this implicitly disables the write barrier when the GC is not
|
| - // active as object will not be marked in this case.
|
| - if (!HeapObjectHeader::FromPayload(src_object)->IsWrapperHeaderMarked()) {
|
| - return;
|
| - }
|
| - CurrentVisitor(isolate)->MarkWrapper(
|
| - &(const_cast<TraceWrapperV8Reference<v8::Value>*>(dst_object)->Get()));
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::WriteBarrier(
|
| - v8::Isolate* isolate,
|
| - const v8::Persistent<v8::Object>* dst_object) {
|
| - if (!dst_object || dst_object->IsEmpty()) {
|
| - return;
|
| - }
|
| - CurrentVisitor(isolate)->MarkWrapper(&(dst_object->As<v8::Value>()));
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::TraceWrappers(
|
| - const TraceWrapperV8Reference<v8::Value>& traced_wrapper) const {
|
| - MarkWrapper(
|
| - &(const_cast<TraceWrapperV8Reference<v8::Value>&>(traced_wrapper).Get()));
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::MarkWrapper(
|
| - const v8::PersistentBase<v8::Value>* handle) const {
|
| - // The write barrier may try to mark a wrapper because cleanup is still
|
| - // delayed. Bail out in this case. We also allow unconditional marking which
|
| - // requires us to bail out here when tracing is not in progress.
|
| - if (!tracing_in_progress_ || handle->IsEmpty())
|
| - return;
|
| - handle->RegisterExternalReference(isolate_);
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::DispatchTraceWrappers(
|
| - const TraceWrapperBase* wrapper_base) const {
|
| - wrapper_base->TraceWrappers(this);
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::InvalidateDeadObjectsInMarkingDeque() {
|
| - for (auto it = marking_deque_.begin(); it != marking_deque_.end(); ++it) {
|
| - auto& marking_data = *it;
|
| - if (marking_data.ShouldBeInvalidated()) {
|
| - marking_data.Invalidate();
|
| - }
|
| - }
|
| - for (auto it = verifier_deque_.begin(); it != verifier_deque_.end(); ++it) {
|
| - auto& marking_data = *it;
|
| - if (marking_data.ShouldBeInvalidated()) {
|
| - marking_data.Invalidate();
|
| - }
|
| - }
|
| - for (auto it = headers_to_unmark_.begin(); it != headers_to_unmark_.end();
|
| - ++it) {
|
| - auto header = *it;
|
| - if (header && !header->IsMarked()) {
|
| - *it = nullptr;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::InvalidateDeadObjectsInMarkingDeque(
|
| - v8::Isolate* isolate) {
|
| - ScriptWrappableVisitor* script_wrappable_visitor =
|
| - V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor();
|
| - if (script_wrappable_visitor)
|
| - script_wrappable_visitor->InvalidateDeadObjectsInMarkingDeque();
|
| -}
|
| -
|
| -void ScriptWrappableVisitor::PerformCleanup(v8::Isolate* isolate) {
|
| - ScriptWrappableVisitor* script_wrappable_visitor =
|
| - V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor();
|
| - if (script_wrappable_visitor)
|
| - script_wrappable_visitor->PerformCleanup();
|
| -}
|
| -
|
| -WrapperVisitor* ScriptWrappableVisitor::CurrentVisitor(v8::Isolate* isolate) {
|
| - return V8PerIsolateData::From(isolate)->GetScriptWrappableVisitor();
|
| -}
|
| -
|
| -} // namespace blink
|
|
|