| OLD | NEW |
| 1 # Wrapper Tracing Reference | 1 # Wrapper Tracing Reference |
| 2 | 2 |
| 3 This document describes wrapper tracing and how its API is supposed to be used. | 3 This document describes wrapper tracing and how its API is supposed to be used. |
| 4 | 4 |
| 5 [TOC] | 5 [TOC] |
| 6 | 6 |
| 7 ## Quickstart guide | 7 ## Quickstart guide |
| 8 | 8 |
| 9 Wrapper tracing is used to represent reachability across V8 and Blink. The | 9 Wrapper tracing is used to represent reachability across V8 and Blink. The |
| 10 following checklist highlights the modifications needed to make a class | 10 following checklist highlights the modifications needed to make a class |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 Member<NonWrappable> m_nonWrappable; | 125 Member<NonWrappable> m_nonWrappable; |
| 126 }; | 126 }; |
| 127 | 127 |
| 128 DEFINE_TRACE_WRAPPERS(SomeDOMObject) { | 128 DEFINE_TRACE_WRAPPERS(SomeDOMObject) { |
| 129 visitor->traceWrappers(m_otherWrappable); | 129 visitor->traceWrappers(m_otherWrappable); |
| 130 } | 130 } |
| 131 ``` | 131 ``` |
| 132 | 132 |
| 133 | 133 |
| 134 Blink and V8 implement *incremental* wrapper tracing, which means that marking | 134 Blink and V8 implement *incremental* wrapper tracing, which means that marking |
| 135 can be interleaved with JavaSCript or even DOM operations. This poses a | 135 can be interleaved with JavaScript or even DOM operations. This poses a |
| 136 challenge, because already marked objects will not be considered again if they | 136 challenge, because already marked objects will not be considered again if they |
| 137 are reached through some other path. | 137 are reached through some other path. |
| 138 | 138 |
| 139 For example, consider an object ``A`` that has already been marked and a write | 139 For example, consider an object ``A`` that has already been marked and a write |
| 140 to a field ``A.x`` setting ``x`` to an unmarked object ``Y``. Since ``A.x`` is | 140 to a field ``A.x`` setting ``x`` to an unmarked object ``Y``. Since ``A.x`` is |
| 141 the only reference keeping ``Y``, and ``A`` has already been marked, the garbage | 141 the only reference keeping ``Y``, and ``A`` has already been marked, the garbage |
| 142 collector will not find ``Y`` and reclaim it. | 142 collector will not find ``Y`` and reclaim it. |
| 143 | 143 |
| 144 To overcome this problem we require all writes of interesting objects, i.e., | 144 To overcome this problem we require all writes of interesting objects, i.e., |
| 145 writes to traced fields, to go through a write barrier. Repeat for simpler | 145 writes to traced fields, to go through a write barrier. Repeat for simpler |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 ``ScriptWrappable``. For example, consider the object graph | 249 ``ScriptWrappable``. For example, consider the object graph |
| 250 ``A -> B -> C`` where both ``A`` and ``C`` are ``ScriptWrappable``s that | 250 ``A -> B -> C`` where both ``A`` and ``C`` are ``ScriptWrappable``s that |
| 251 need to be traced. | 251 need to be traced. |
| 252 | 252 |
| 253 In this case, the same rules as with ``ScriptWrappables`` apply, except for the | 253 In this case, the same rules as with ``ScriptWrappables`` apply, except for the |
| 254 difference that these classes need to inherit from ``TraceWrapperBase``. | 254 difference that these classes need to inherit from ``TraceWrapperBase``. |
| 255 | 255 |
| 256 ### Memory-footprint critical uses | 256 ### Memory-footprint critical uses |
| 257 | 257 |
| 258 In the case we cannot afford inheriting from ``TraceWrapperBase``, which will | 258 In the case we cannot afford inheriting from ``TraceWrapperBase``, which will |
| 259 add a vtable pointer for tracing wrappers, an entry in a macro | 259 add a vtable pointer for tracing wrappers, use |
| 260 ``WRAPPER_VISITOR_SPECIAL_CASES`` | 260 ``DECLARE_TRACE_WRAPPERS_WITHOUT_BASE`` to declare a traceWrappers method. |
| 261 is required in | |
| 262 ``platform/heap/WrapperVisitor.h``. | |
| 263 | 261 |
| 264 ## Explicit write barriers | 262 ## Explicit write barriers |
| 265 | 263 |
| 266 Sometimes it is necessary to stick with the regular types and issue the write | 264 Sometimes it is necessary to stick with the regular types and issue the write |
| 267 barriers explicitly. For example, if memory footprint is really important and | 265 barriers explicitly. For example, if memory footprint is really important and |
| 268 it's not possible to use ``TraceWrapperMember`` which adds another pointer | 266 it's not possible to use ``TraceWrapperMember`` which adds another pointer |
| 269 field. In this case, tracing needs to be adjusted to tell the system that all | 267 field. In this case, tracing needs to be adjusted to tell the system that all |
| 270 barriers will be done manually. | 268 barriers will be done manually. |
| 271 | 269 |
| 272 ```c++ | 270 ```c++ |
| 273 class ManualWrappable : public ScriptWrappable { | 271 class ManualWrappable : public ScriptWrappable { |
| 274 public: | 272 public: |
| 275 void setNew(OtherWrappable* newValue) { | 273 void setNew(OtherWrappable* newValue) { |
| 276 m_otherWrappable = newValue; | 274 m_otherWrappable = newValue; |
| 277 SriptWrappableVisitor::writeBarrier(this, m_otherWrappable); | 275 SriptWrappableVisitor::writeBarrier(this, m_otherWrappable); |
| 278 } | 276 } |
| 279 | 277 |
| 280 DECLARE_VIRTUAL_TRACE_WRAPPERS(); | 278 DECLARE_VIRTUAL_TRACE_WRAPPERS(); |
| 281 private: | 279 private: |
| 282 Member<OtherWrappable>> m_otherWrappable; | 280 Member<OtherWrappable>> m_otherWrappable; |
| 283 }; | 281 }; |
| 284 | 282 |
| 285 DEFINE_TRACE_WRAPPERS(ManualWrappable) { | 283 DEFINE_TRACE_WRAPPERS(ManualWrappable) { |
| 286 for (auto other : m_otherWrappables) | 284 for (auto other : m_otherWrappables) |
| 287 visitor->traceWrappersWithManualWriteBarrier(other); | 285 visitor->traceWrappersWithManualWriteBarrier(other); |
| 288 } | 286 } |
| 289 ``` | 287 ``` |
| OLD | NEW |