aboutsummaryrefslogtreecommitdiffstats
path: root/components/script
diff options
context:
space:
mode:
Diffstat (limited to 'components/script')
-rw-r--r--components/script/dom/bindings/DESIGN.md42
-rw-r--r--components/script/dom/bindings/trace.rs8
-rw-r--r--components/script/dom/mod.rs16
3 files changed, 15 insertions, 51 deletions
diff --git a/components/script/dom/bindings/DESIGN.md b/components/script/dom/bindings/DESIGN.md
deleted file mode 100644
index 9ee7a50a7ac..00000000000
--- a/components/script/dom/bindings/DESIGN.md
+++ /dev/null
@@ -1,42 +0,0 @@
-# The design of Garbage collected DOM
-
-This is how Servo provides an object graph to SpiderMonkey's Garbage Collector.
-
-## Construct
-When Servo creates a Rusty DOM object the binding code creates a corresponding wrapper `JSObject` with SpiderMonkey. It’s produced and set to the Rusty object in `FooBinding::Wrap`.
-
-In `FooBinding::Wrap`, the wrapper `JSObject` gets the pointer for the Rusty object to itself. At the same time the wrapper `JSObject` is set to the Rusty object’s `Reflector` field (all Rusty DOM objects have `dom::bindings::utils::Reflector` in their most basic fields). These steps are the “binding” work necessary to create the relationship between both objects.
-
-
-## Trace object graph from SpiderMonkey GC
-This is a tricky mechanism done with the help of the Rust compiler.
-The outline is:
-
-1. SpiderMonkey's GC calls `JSClass.trace` defined in `FooBinding` during the marking phase. This `JSClass` is the basis of each wrapper `JSObject`.
-2. `JSClass.trace` calls `Foo::trace()` (an implementation of `JSTraceable`).
- This is typically derived via a #[jstraceable] annotation.
-3. For all fields, `Foo::trace()`
- calls `trace()` on the field. For example, for fields of type `JS<T>`, `JS<T>::trace()` calls
- `trace_reflector()`. Non-JS-managed types have an empty inline `trace()` method, achieved via `no_jsmanaged_fields!` or similar.
-4. `trace_reflector()` fetches the reflector that is reachable from a Rust object and notifies it to the GC using JSTracer.
-5. This operation continues for the rest of the graph.
-6. Finally, the GC checks whether the Rust object lives or not from `JSObject`s which are held by Rust object.
-
-
-## Destruct
-When destructing DOM objects (wrapper JSObjects), SpiderMonkey calls the `JSClass.finalize()` which is basis of each wrapper `JSObject`. This method refers to `FooBinding::_finalize()`.
-
-In the `_finalize()` function the pointer of the Rusty DOM object that is contained in the JSObject is unwrapped. It is then cast to a Rust owned pointer and assigned to an empty local variable. Thus we can destruct the Rusty object afterwards.
-
-
-## Interact with Exact GC’s rooting
-For supporting SpiderMonkey’s exact GC rooting, we introduce [some types](https://github.com/mozilla/servo/wiki/Using-DOM-types):
-
-- `JS<T>` is used for the DOM typed field in a DOM type structure. The GC can trace them recursively while the enclosing DOM object (maybe root) is alive.
- - `LayoutJS<T>` is specialized `JS<T>` to use in layout. `Layout*Helper` must be implemented on this type to prevent calling methods from non layout code.
-- `Unrooted<T>` is used to wrap raw pointers to DOM objects extracted from their reflectors.
-- `Temporary<T>` is used as a return value for functions returning a DOM type. They are rooted for the duration of their lifetime. But a retun value gets moved around which can break the LIFO ordering constraint. Thus we need to introduce `Root<T>`.
-- `Root<T>` contains the pointer to `JSObject` which the represented DOM type has. SpiderMonkey's conservative stack scanner scans it's pointers and marks a pointed `JSObject` as GC root.
-- `JSRef` is just a reference to the value rooted by `Root<T>`.
-- `RootCollection` is used to dynamically check if rooting satisfies LIFO ordering, because SpiderMonkey's GC requires LIFO order (See also: [Exact Stack Rooting - Storing a GCPointer on the CStack](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Internals/GC/Exact_Stack_Rooting)).
- - `MutHeap<T>` is a version of `Cell<T>` that is safe to use for internal mutability of Spidermonkey heap objects like `JSVal` and `JS<T>`
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 0eca6f00a14..e447b4c6a67 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -12,7 +12,9 @@
//! phase. (This happens through `JSClass.trace` for non-proxy bindings, and
//! through `ProxyTraps.trace` otherwise.)
//! 2. `_trace` calls `Foo::trace()` (an implementation of `JSTraceable`).
-//! This is typically derived via a #[jstraceable] annotation
+//! This is typically derived via a `#[dom_struct]` (implies `#[jstraceable]`) annotation.
+//! Non-JS-managed types have an empty inline `trace()` method,
+//! achieved via `no_jsmanaged_fields!` or similar.
//! 3. For all fields, `Foo::trace()`
//! calls `trace()` on the field.
//! For example, for fields of type `JS<T>`, `JS<T>::trace()` calls
@@ -21,8 +23,10 @@
//! reflector.
//! 5. `trace_object()` calls `JS_CallTracer()` to notify the GC, which will
//! add the object to the graph, and will trace that object as well.
+//! 6. When the GC finishes tracing, it [`finalizes`](../index.html#destruction)
+//! any reflectors that were not reachable.
//!
-//! The no_jsmanaged_fields!() macro adds an empty implementation of JSTraceable to
+//! The `no_jsmanaged_fields!()` macro adds an empty implementation of `JSTraceable` to
//! a datatype.
use dom::bindings::js::JS;
diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs
index 0650a900494..6a9b4827e96 100644
--- a/components/script/dom/mod.rs
+++ b/components/script/dom/mod.rs
@@ -67,10 +67,10 @@
//! (The result of either method can be wrapped in `Result`, if that is
//! appropriate for the type in question.)
//!
-//! The latter calls the former, boxes the result, and creates a reflector for
-//! it by calling `dom::bindings::utils::reflect_dom_object` (which yields
-//! ownership of the object to the SpiderMonkey Garbage Collector). This is the
-//! API to use when creating a DOM object.
+//! The latter calls the former, boxes the result, and creates a reflector
+//! corresponding to it by calling `dom::bindings::utils::reflect_dom_object`
+//! (which yields ownership of the object to the SpiderMonkey Garbage Collector).
+//! This is the API to use when creating a DOM object.
//!
//! The former should only be called by the latter, and by subclasses'
//! `new_inherited` methods.
@@ -98,9 +98,11 @@
//! =============================
//!
//! Every DOM object has a `Reflector` as its first (transitive) member field.
-//! This contains a `*mut JSObject` that points to its reflector. This field
-//! is initialized by the `FooBinding::Wrap` method, called from
-//! `reflect_dom_object`.
+//! This contains a `*mut JSObject` that points to its reflector.
+//!
+//! The `FooBinding::Wrap` function creates the reflector, stores a pointer to
+//! the DOM object in the reflector, and initializes the pointer to the reflector
+//! in the `Reflector` field.
//!
//! The `Reflectable` trait provides a `reflector()` method that returns the
//! DOM object's `Reflector`. It is implemented automatically for DOM structs