Changes between Initial Version and Version 1 of DOMBindingsEventLoopNotes


Ignore:
Timestamp:
Nov 1, 2019, 1:43:51 PM (5 years ago)
Author:
Jon Davis
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DOMBindingsEventLoopNotes

    v1 v1  
     1= DOM Bindings, Event Loop & More
     2''by Ryosuke Niwa''
     3
     4- C++ and JS Objects
     5    - C++ objects define behavior
     6    - JS wrappers expose them to JavaScript
     7    - Injected scripts have their own DOM wrapper “world”
     8- Converting Objects
     9    - toJS(node) to get a JS wrapper
     10    - toWrapped(node) / jsNode.wrapped() to get C++ object
     11    - Cache main world’s wrapper via ScriptWrappable
     12- When should we use it?
     13    - Use it when performance matters
     14    - Cost is one extra object; memory concern
     15    - Wrapped object is always fast
     16- Lifecycle of DOM Objects
     17    - JS wrapper keeps C++ object alive
     18            - Ref<> in JSDOMWrapper
     19    - Two ways to keep JS wrappers alive
     20        - Visit children
     21        - Reachable from Opaque Roots
     22    - Visit children? Implement visitChildren function and do something?
     23        - Yes
     24        - Inspector GC heap, you can look at it in Web Inspector
     25- Common misconception
     26    - C++ objects do NOT keep their JS wrappers alive by default
     27class Some : RefCounted<Some> {
     28    …
     29    Ref<Other> m_other; // <<—  JS other will still go away
     30}
     31class Other : RefCounted<Other> { }
     32- Lifecycle: Visit Children
     33    - JSCustomMarkFunction in IDL
     34    - Add JS*::visitAdditionalChildren in JS*Custom.cpp
     35    - Visit JS object kept by WebCore
     36- Lifecycle: Opaque Roots
     37    - GeneratelsReachable=Impl* or CustomlsReachable in IDL
     38    - addOpaqueRoot in visitAdditionalChildren
     39    - JS*::isReachableFromOpaqueRoots
     40- Lifecycle: Concurrency
     41    - Visiting & opaque root checks happen in non-main threads
     42    - Can’t make createWeakPtr or ref / deref RefCounted objects
     43    - Cant lookup HashMap
     44    - What ones run with the main thread stopped vs what runs when main thread is not stopped?
     45        - VisitChildren runs when the main thread is running, runs on background threads when the main thread is not running
     46        - IsOpaqueRoots stops the main thread and runs on background threads
     47- Lifecycle: Common Cases
     48    - Keeping JS object alive → Visit Children
     49        - Store JSC::Weak<JSC::JSObject>
     50        - ActiveDOMCallback for callbacks
     51    - C++ object relationship → Opaque Roots
     52        - Agree on opaque root; typically root Node
     53        - Write thread safe code to get opaque root
     54- Lifecycle: NodeLists
     55    - Diagram
     56- Lifecycle: DOM Nodes
     57    - Node is alive if it has refCount > 0 or has parent node
     58    - Node increments Document’s m_referencingNodeCount
     59    - Document is alive if refCount > 0 or m_referencingNodeCount > 0
     60    - Node::removedLastRef on Element
     61    - ContainerNode::removeDetachedChildren in ~ContainerNode
     62    - Turn into flat linked list in deletion queue
     63    - Document::removedLastRef() must clear any Ref / RefPtr to Node
     64    - Not safe to traverse DOM tree during destruction
     65- Node Insertion & Removal
     66    - Node::insertedIntoAncestor / removedFromAncestor
     67        - Called whenever node’s ancestor changes
     68        - Either “this” or its ancestor got inserted or removed
     69        - Don’t assume tree scope or document change
     70    - No script execution in insertedIntoAncestor or removedFromAncestor
     71        - Will hit release assertion
     72        - Use didFinishInsertingNode instead
     73- Node Insertion Order
     74    - insertedIntoAncestor called in tree order
     75    - Only talk to nodes earlier in tree order
     76- Node Removal Order
     77    - removedFromAncestor called in tree order
     78    - Only talk to nodes earlier in tree order
     79        - Run layout tests with --world-leaks
     80- Lifecycle: Delayed Use
     81    - Asynchronous use of “this” - XHR, media, …
     82        - Make “this” ActiveDOMObject
     83    - Asynchronous use of Node - MutationObserver, ResizeObserver, …
     84        - GCReachableRef ← This is a leak!
     85- Lifecycle: ActiveDOMObject
     86    - Async work → dispatchEvent on this
     87    - Reachable if hasPendingActivity is true
     88    - Suspendable for back-forward cache
     89- HTML5 Event Loop
     90    - WindowEventLoop has been added
     91    - WorkerEventLoop is coming
     92    - WindowEventLoop is shared across documents of similar origins
     93- Event Loop: In New Code
     94    - Do NOT USE
     95        - Timer / SuspendableTimer
     96        - GenericEventQueue / GenericTaskQueue
     97
     98''(rniwa is a genius. officially.)''