Commit ea056bf4 authored by hlopko's avatar hlopko Committed by Commit bot

Maintain wrapper tracing deque in ScriptWrappableVisitor

This cl uses updated V8 api which will be easier to work with incrementally
(althrough it is not used incrementally at the moment). For that
ScriptWrappableVisitor now has to maintain his marking deque.

LOG=no
BUG=468240

Review-Url: https://codereview.chromium.org/2044023002
Cr-Commit-Position: refs/heads/master@{#398273}
parent aa9125d2
......@@ -31,7 +31,6 @@
#ifndef ScriptWrappable_h
#define ScriptWrappable_h
#include "bindings/core/v8/ScriptWrappableVisitor.h"
#include "bindings/core/v8/WrapperTypeInfo.h"
#include "core/CoreExport.h"
#include "platform/heap/Handle.h"
......
......@@ -6,7 +6,6 @@
#include "bindings/core/v8/ActiveScriptWrappable.h"
#include "bindings/core/v8/DOMWrapperWorld.h"
#include "bindings/core/v8/ScriptWrappable.h"
#include "bindings/core/v8/WrapperTypeInfo.h"
#include "core/dom/DocumentStyleSheetCollection.h"
#include "core/dom/ElementRareData.h"
......@@ -39,27 +38,37 @@ void ScriptWrappableVisitor::TraceEpilogue()
m_tracingInProgress = false;
}
void ScriptWrappableVisitor::TraceWrappersFrom(const std::vector<std::pair<void*, void*>>& internalFieldsOfPotentialWrappers)
void ScriptWrappableVisitor::RegisterV8References(const std::vector<std::pair<void*, void*>>& internalFieldsOfPotentialWrappers)
{
ASSERT(m_tracingInProgress);
// TODO(hlopko): Visit the vector in the V8 instead of passing it over if
// there is no performance impact
for (auto pair : internalFieldsOfPotentialWrappers) {
traceWrappersFrom(pair);
WrapperTypeInfo* wrapperTypeInfo = reinterpret_cast<WrapperTypeInfo*>(pair.first);
if (wrapperTypeInfo->ginEmbedder != gin::GinEmbedder::kEmbedderBlink)
continue;
ScriptWrappable* scriptWrappable = reinterpret_cast<ScriptWrappable*>(pair.second);
DCHECK(wrapperTypeInfo->wrapperClassId == WrapperTypeInfo::NodeClassId
|| wrapperTypeInfo->wrapperClassId == WrapperTypeInfo::ObjectClassId);
m_markingDeque.append(scriptWrappable);
}
}
void ScriptWrappableVisitor::traceWrappersFrom(std::pair<void*, void*> internalFields)
bool ScriptWrappableVisitor::AdvanceTracing(double deadlineInMs, v8::EmbedderHeapTracer::AdvanceTracingActions actions)
{
WrapperTypeInfo* wrapperTypeInfo = reinterpret_cast<WrapperTypeInfo*>(internalFields.first);
if (wrapperTypeInfo->ginEmbedder != gin::GinEmbedder::kEmbedderBlink)
return;
ScriptWrappable* scriptWrappable = reinterpret_cast<ScriptWrappable*>(internalFields.second);
ASSERT(wrapperTypeInfo->wrapperClassId == WrapperTypeInfo::NodeClassId
|| wrapperTypeInfo->wrapperClassId == WrapperTypeInfo::ObjectClassId);
scriptWrappable->traceWrappers(this);
DCHECK(m_tracingInProgress);
while (actions.force_completion == v8::EmbedderHeapTracer::ForceCompletionAction::FORCE_COMPLETION
|| WTF::monotonicallyIncreasingTimeMS() < deadlineInMs) {
if (m_markingDeque.isEmpty()) {
return false;
}
const ScriptWrappable* scriptWrappable = m_markingDeque.takeFirst();
markWrapperHeader(scriptWrappable);
scriptWrappable->traceWrappers(this);
}
return true;
}
bool ScriptWrappableVisitor::markWrapperHeader(HeapObjectHeader* header) const
......
......@@ -6,15 +6,16 @@
#define ScriptWrappableVisitor_h
#include "bindings/core/v8/ScopedPersistent.h"
#include "bindings/core/v8/ScriptWrappable.h"
#include "core/CoreExport.h"
#include "platform/heap/WrapperVisitor.h"
#include "wtf/Deque.h"
#include "wtf/Vector.h"
#include <v8.h>
namespace blink {
class ScriptWrappable;
class HeapObjectHeader;
template<typename T> class Member;
......@@ -23,8 +24,9 @@ template<typename T> class Member;
* references. It is used during V8 garbage collection. When this visitor is
* set to the v8::Isolate as its embedder heap tracer, V8 will call it during
* its garbage collection. At the beginning, it will call TracePrologue, then
* repeatedly (as v8 discovers more wrappers) it will call TraceWrappersFrom,
* and at the end it will call TraceEpilogue.
* repeatedly it will call AdvanceTracing, and at the end it will call
* TraceEpilogue. Everytime V8 finds new wrappers, it will let the tracer know
* using RegisterV8References.
*/
class CORE_EXPORT ScriptWrappableVisitor : public WrapperVisitor, public v8::EmbedderHeapTracer {
public:
......@@ -45,11 +47,10 @@ public:
}
void TracePrologue() override;
void TraceWrappersFrom(const std::vector<std::pair<void*, void*>>& internalFieldsOfPotentialWrappers) override;
void RegisterV8References(const std::vector<std::pair<void*, void*>>& internalFieldsOfPotentialWrappers) override;
bool AdvanceTracing(double deadlineInMs, v8::EmbedderHeapTracer::AdvanceTracingActions) override;
void TraceEpilogue() override;
void traceWrappersFrom(const ScriptWrappable*) const;
template <typename T>
void markWrapper(const v8::Persistent<T>* handle) const
{
......@@ -71,8 +72,15 @@ private:
bool markWrapperHeader(HeapObjectHeader*) const;
bool markWrapperHeader(const ScriptWrappable*) const override;
bool markWrapperHeader(const void* garbageCollected) const override;
inline void traceWrappersFrom(std::pair<void*, void*> internalFields);
bool m_tracingInProgress = false;
/**
* Collection of ScriptWrappables we need to trace from. We assume it safe
* to hold on to the raw pointers because:
* * oilpan object cannot move
* * for the oilpan gc, this deque is part of the root set, so objects
* in the deque will not die
*/
mutable WTF::Deque<const ScriptWrappable*> m_markingDeque;
/**
* Collection of headers we need to unmark after the tracing finished. We
* assume it is safe to hold on to the headers because:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment