Index: third_party/WebKit/Source/bindings/core/v8/TraceWrapperReference.md |
diff --git a/third_party/WebKit/Source/bindings/core/v8/TraceWrapperReference.md b/third_party/WebKit/Source/bindings/core/v8/TraceWrapperReference.md |
deleted file mode 100644 |
index 4908ec22f11a85c3006a454dcff23273312a63a9..0000000000000000000000000000000000000000 |
--- a/third_party/WebKit/Source/bindings/core/v8/TraceWrapperReference.md |
+++ /dev/null |
@@ -1,288 +0,0 @@ |
-# Wrapper Tracing Reference |
- |
-This document describes wrapper tracing and how its API is supposed to be used. |
- |
-[TOC] |
- |
-## Quickstart guide |
- |
-Wrapper tracing is used to represent reachability across V8 and Blink. The |
-following checklist highlights the modifications needed to make a class |
-participate in wrapper tracing. |
- |
-1. Make sure that objects participating in tracing either inherit from |
-``ScriptWrappable`` (if they can reference wrappers) or ``TraceWrapperBase`` |
-(transitively holding wrappers alive). |
-2. Use ``TraceWrapperMember<T>`` to annotate fields that need to be followed to |
-find other wrappers that this object should keep alive. |
-3. Use ``TraceWrapperV8Reference<T>`` to annotate references to V8 that this |
-object should keep alive. |
-4. Declare a method to trace other wrappers using |
-``DECLARE_VIRTUAL_TRACE_WRAPPERS()``. |
-5. Define the method using ``DEFINE_TRACE_WRAPPERS(ClassName)``. |
-6. Trace all fields that received a wrapper tracing type in (1) and (2) using |
-``visitor->traceWrapers(<m_field>)`` in the body of ``DEFINE_TRACE_WRAPPERS``. |
- |
-The following example illustrates these steps: |
- |
-```c++ |
-#include "bindings/core/v8/ScriptWrappable.h" |
-#include "bindings/core/v8/TraceWrapperMember.h" |
-#include "bindings/core/v8/TraceWrapperV8Reference.h" |
- |
-class SomeDOMObject : public ScriptWrappable { // (1) |
- public: |
- DECLARE_VIRTUAL_TRACE_WRAPPERS(); // (4) |
- |
- private: |
- TraceWrapperMember<OtherWrappable> m_otherWrappable; // (2) |
- Member<NonWrappable> m_nonWrappable; |
- TraceWrapperV8Reference<v8::Value> m_v8object; // (3) |
- // ... |
-}; |
- |
-DEFINE_TRACE_WRAPPERS(SomeDOMObject) { // (5) |
- visitor->traceWrappers(m_otherWrappable); // (6) |
- visitor->traceWrappers(m_v8object); // (6) |
-} |
-``` |
- |
-For more in-depth information and how to deal with corner cases continue on reading. |
- |
-## Background |
- |
-Blink and V8 need to cooperate to collect JavaScript *wrappers*. Each V8 |
-*wrapper* object (*W*) in JavaScript is assigned a C++ *DOM object* (*D*) in |
-Blink. A single C++ *DOM object* can hold onto one or many *wrapper* objects. |
-During a garbage collection initiated from JavaScript, a *wrapper* then keeps |
-the C++ *DOM object* and all its transitive dependencies, including other |
-*wrappers*, alive, effectively tracing paths like |
-*W<sub>x</sub> -> D<sub>1</sub> -> ⋯ -> D<sub>n</sub> -> W<sub>y</sub>*. |
- |
-Previously, this relationship was expressed using so-called object groups, |
-effectively assigning all C++ *DOM objects* in a given DOM tree the same group. |
-The group would only die if all objects belonging to the same group die. A brief |
-introduction on the limitations on this approach can be found in |
-[this slide deck][object-grouping-slides]. |
- |
-Wrapper tracing solves this problem by determining liveness based on |
-reachability by tracing through the C++ *DOM objects*. The rest of this document |
-describes how the API is used to keep JavaScript wrapper objects alive. |
- |
-Note that *wrappables* have to be *on-heap objects* and thus all |
-[Oilpan-related rules][oilpan-docs] apply. |
- |
-[object-grouping-slides]: https://docs.google.com/presentation/d/1I6leiRm0ysSTqy7QWh33Gfp7_y4ngygyM2tDAqdF0fI/ |
-[oilpan-docs]: https://chromium.googlesource.com/chromium/src/+/master/third_party/WebKit/Source/platform/heap/BlinkGCAPIReference.md |
- |
-## Basic usage |
- |
-The annotations that are required can be found in the following header files. |
-Pick the header file depending on what types are needed. |
- |
-```c++ |
-#include "bindings/core/v8/ScriptWrappable.h" |
-#include "bindings/core/v8/TraceWrapperBase.h" |
-#include "bindings/core/v8/TraceWrapperMember.h" |
-#include "bindings/core/v8/TraceWrapperV8Reference.h" |
-``` |
- |
-The following example will guide through the modifications that are needed to |
-adjust a given class ``SomeDOMObject`` to participate in wrapper tracing. |
- |
-```c++ |
-class SomeDOMObject : public ScriptWrappable { |
- // ... |
- private: |
- Member<OtherWrappable /* extending ScriptWrappable */> m_otherWrappable; |
- Member<NonWrappable> m_nonWrappable; |
-}; |
-``` |
- |
-In this scenario ``SomeDOMObject`` is the object that is wrapped by an object on |
-the JavaScript side. The next step is to identify the paths that lead to other |
-wrappables. In this case, only ``m_otherWrappable`` needs to be traced to find |
-other *wrappers* in V8. |
- |
-As wrapper tracing only traces a subset of members residing on the Oilpan heap, |
-it requires its own tracing method. The macros are as follows: |
- |
-* ``DECLARE_VIRTUAL_TRACE_WRAPPERS();``: Use in the class declaration to declare |
-the needed wrapper tracing method. |
-* ``DEFINE_TRACE_WRAPPERS(ClassName)``: Use to define the implementation of |
-wrapper tracing. |
- |
-Many more convenience wrappers, like inline definitions, can be found in |
-``platform/heap/WrapperVisitor.h``. |
- |
-```c++ |
-class SomeDOMObject : public ScriptWrappable { |
- public: |
- DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
- |
- private: |
- Member<OtherWrappable> m_otherWrappable; |
- Member<NonWrappable> m_nonWrappable; |
-}; |
- |
-DEFINE_TRACE_WRAPPERS(SomeDOMObject) { |
- visitor->traceWrappers(m_otherWrappable); |
-} |
-``` |
- |
- |
-Blink and V8 implement *incremental* wrapper tracing, which means that marking |
-can be interleaved with JavaScript or even DOM operations. This poses a |
-challenge, because already marked objects will not be considered again if they |
-are reached through some other path. |
- |
-For example, consider an object ``A`` that has already been marked and a write |
-to a field ``A.x`` setting ``x`` to an unmarked object ``Y``. Since ``A.x`` is |
-the only reference keeping ``Y``, and ``A`` has already been marked, the garbage |
-collector will not find ``Y`` and reclaim it. |
- |
-To overcome this problem we require all writes of interesting objects, i.e., |
-writes to traced fields, to go through a write barrier. Repeat for simpler |
-readers: The write barrier will check for the problem case above and make sure |
-``Y`` will be marked. In order to automatically issue a write barrier |
-``m_otherWrappable`` needs ``TraceWrapperMember`` type. |
- |
-```c++ |
-class SomeDOMObject : public ScriptWrappable { |
- public: |
- SomeDOMObject() : m_otherWrappable(this, nullptr) {} |
- DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
- |
- private: |
- TraceWrapperMember<OtherWrappable> m_otherWrappable; |
- Member<NonWrappable> m_nonWrappable; |
-}; |
- |
-DEFINE_TRACE_WRAPPERS(SomeDOMObject) { |
- visitor->traceWrappers(m_otherWrappable); |
-} |
-``` |
- |
-``TraceWrapperMember`` makes sure that any write to ``m_otherWrappable`` will |
-consider doing a write barrier. Using the proper type, the write barrier is |
-correct by construction, i.e., it will never be missed. |
- |
-## Heap collections |
- |
-The proper type usage for collections, e.g. ``HeapVector`` looks like the |
-following. |
- |
-```c++ |
-class SomeDOMObject : public ScriptWrappable { |
- public: |
- // ... |
- void AppendNewValue(OtherWrappable* newValue); |
- DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
- |
- private: |
- HeapVector<TraceWrapperMember<OtherWrappable>> m_otherWrappables; |
-}; |
- |
-DEFINE_TRACE_WRAPPERS(SomeDOMObject) { |
- for (auto other : m_otherWrappables) |
- visitor->traceWrappers(other); |
-} |
-``` |
- |
-Note that this is different to Oilpan which can just trace the whole collection. |
-Whenever an element is added through ``append()`` the value needs to be |
-constructed using ``TraceWrapperMember``, e.g. |
- |
-```c++ |
-void SomeDOMObject::AppendNewValue(OtherWrappable* newValue) { |
- m_otherWrappables.append(TraceWrapperMember(this, newValue)); |
-} |
-``` |
- |
-The compiler will throw an error for each ommitted ``TraceWrapperMember`` |
-construction. |
- |
-### Corner-case: Pre-sized containers |
- |
-Containers know how to construct an empty ``TraceWrapperMember`` slot. This |
-allows simple creation of containers at the cost of loosing the compile-time |
-check for assigning a raw value. |
- |
-```c++ |
-class SomeDOMObject : public ScriptWrappable { |
- public: |
- SomeDOMObject() { |
- m_otherWrappables.resize(5); |
- } |
- |
- void writeAt(int i, OtherWrappable* other) { |
- m_otherWrappables[i] = other; |
- } |
- |
- DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
- private: |
- HeapVector<TraceWrapperMember<OtherWrappable>> m_otherWrappables; |
-}; |
- |
-DEFINE_TRACE_WRAPPERS(SomeDOMObject) { |
- for (auto other : m_otherWrappables) |
- visitor->traceWrappers(other); |
-} |
-``` |
- |
-In this example, the compiler will not warn you on |
-``m_otherWrappables[i] = other``, but an assertion will throw at runtime as long |
-as there exists a test covering that branch. |
- |
-The correct assignment looks like |
- |
-```c++ |
-m_otherWrappables[i] = TraceWrapperMember<OtherWrappable>(this, other); |
-``` |
- |
-Note that the assertion that triggers when the annotation is not present does |
-not require wrapper tracing to be enabled. |
- |
-## Tracing through non-``ScriptWrappable`` types |
- |
-Sometimes it is necessary to trace through types that do not inherit from |
-``ScriptWrappable``. For example, consider the object graph |
-``A -> B -> C`` where both ``A`` and ``C`` are ``ScriptWrappable``s that |
-need to be traced. |
- |
-In this case, the same rules as with ``ScriptWrappables`` apply, except for the |
-difference that these classes need to inherit from ``TraceWrapperBase``. |
- |
-### Memory-footprint critical uses |
- |
-In the case we cannot afford inheriting from ``TraceWrapperBase``, which will |
-add a vtable pointer for tracing wrappers, use |
-``DEFINE_TRAIT_FOR_TRACE_WRAPPERS(ClassName)`` after defining |
-``ClassName`` to define the proper tracing specializations. |
- |
-## Explicit write barriers |
- |
-Sometimes it is necessary to stick with the regular types and issue the write |
-barriers explicitly. For example, if memory footprint is really important and |
-it's not possible to use ``TraceWrapperMember`` which adds another pointer |
-field. In this case, tracing needs to be adjusted to tell the system that all |
-barriers will be done manually. |
- |
-```c++ |
-class ManualWrappable : public ScriptWrappable { |
- public: |
- void setNew(OtherWrappable* newValue) { |
- m_otherWrappable = newValue; |
- SriptWrappableVisitor::writeBarrier(this, m_otherWrappable); |
- } |
- |
- DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
- private: |
- Member<OtherWrappable>> m_otherWrappable; |
-}; |
- |
-DEFINE_TRACE_WRAPPERS(ManualWrappable) { |
- for (auto other : m_otherWrappables) |
- visitor->traceWrappersWithManualWriteBarrier(other); |
-} |
-``` |