components/script/dom/bindings/codegen/Bindings) for the Rust code. The servo developers then fill in the missing Rust code. You can find those implementations in
components/script/dom. There are common DOM elements like
htmlanchorelement.rs), just to name a few.
SpiderMonkey used to use a conservative mark-and-sweep garbage collector, but it migrated to a exact rooting garbage collector.
The basic concept behind the mark-and-sweep GC (garbage collection) is easy: The variables or in-memory data structures that are no longer accessable are considered garbage, and needs to be reclaimed. But first, these garbages are allow to accumulate. Until a certain criteria is met, for example: a new object allocation is requested but there is no enough memory, or a certain timeout has reached, the main program is paused for the garbage collector to do its job.
In the first phase, the garbage collector walks through (or trace out, thus the name tracing GC) the memory to mark objects that are directly or indirectly reachable as live. Directly reachable objects (root in GC speaking) includes objects that are referenced by static variables, stack variab les or even CPU register. Indirectly reachable objects are those referenced by the directly reachable objects or each other. In the second phase, the objects on the heap that are not marked as live are freed, or sweeped.
However, depending on the timing of the GC, there might be unreachable objects that are actually needed afterwords. For example, consider a local variable that was created to be inserted into an array. But before the insertion is executed, the GC kicks in. At that point, the local variable is actually live but unreachable from any root.
There are at least two ways to solve this problem. The first is called conservative GC. What is does is that during the marking phase, it looks into the stack and CPU registers and find anything that looks like a pointer pointing into the heap. Although there may be false positives, we still treat the object at the pointed address as live objects. Another way is called exact rooting. Programmers has to manually mark newly created variables or objects as root, so they will not be recycled.
At first glance, exact rooting puts a lot of burden on programmers, and can be error-prone if the programmer forget to mark anything. Forgetting to mark an object as live may cause memory leak, create security loopholes or used-after-free problems. Although conservative GC has some false positives, but it looks easy and clean. However, the conservative approach has a fatal flaw: the GC managed objects, or GC thing, can't be moved. This prevents many advanced GC optimization like compacting and generational GC, which will be discussed later.
When we want to move a GC thing, we need to update all the pointers that points to it. However, because conservative GC are not exactly sure if a value in the stack or register is an actual pointer or not, it might accidentally change the wrong thing. For example, suppose we have a value X somewhere in the memory, but the garbage collector wants to move the GC thing at heap address X to Y. The value might be treated as a pointer to X and being changed to Y. This will corrupt the value and affect the behavior of the program. With exact rooting, since all live objects are manually marked, the garbage collector can confidently move a GC thing because it knows what is a pointer and what is not.
Then why would a garbage collector wants to move GC things around? One use case is an optimization method call compacting. Since after a few runs of GC, the live objects may be scattered sparsely in the memory. In order to eliminate the fragmentation of the free space for more efficient usage of memory, the garbage collector may want to shift the live GC things together in memory.
Another use case, which have been implemented in SpiderMonkey, is called Generational GC. In generational GC, the heap is split into two sections: the nursery area and the tenured area. Newly created objects are allocated in the nursery area. If the object lives long enough, it will be moved into the tenured area. Since many objects, like local variable, usually don't live very long, the move will not be very often. Since many objects die early in the nursery, usually a fast minor GC in the nursery only will reclaim enough memory for the program to continue running. We only need to do a full-scale major GC on the whole heap occasionally, reducing the overall GC pause time. Also the fragmentation will reduce because the long-lived objects will be pretty condensed in the tenured area.
In order to collaborate with the garbage collector, Servo introduced a few smart pointers, which are located in
components/script/dom/bindings/js.rs. We'll introduce why these smart pointers are necessary, and when to use them.
Atomtype used in the html element attribute?
Interned strings are stored in a hashmap. If the a string already exists in the hashmap, the
Atom version of it will only store the location in the hashmap.
You might encounter the length unit
Au when doing layout queries. For example, when you use layout query to get the upper-left corner position of a
origin.y are both in
Au is an "App Unit" and represents 1/60th of a CSS pixel. It was originally proposed in 2002  as a standard unit of measure in Gecko. The definition of
Au is in
14:24 slyu-home I have one more question, in the dom implementations, there are new_inherited(), new(), and Constructor(). What are the differences between them? Thanks 14:24 larsberg I'm not entirely sure. There are any number of things that can cause a failure to happen and merges to not happen. But I suspect that adding the linux2 builder had the good side effect of fixing that android bit. 14:24 Ms2ger slyu, Constructor is the thing called from JS 14:24 * larsberg does not like all the rube goldbergian semi-related moving parts in these systems 14:25 Ms2ger slyu-home, new() is the thing you call when you create the object 14:25 Ms2ger slyu-home, new_inherited() is the thing you call from Class::new() and Subclass::new() 14:26 slyu-home Ms2ger, I didn't get the new_inherited() 14:26 Ms2ger slyu-home, so we have to fake class inheritance because rust doesn't support that 14:27 slyu-home Oh I see 14:27 Ms2ger slyu-home, Foo::new returns an object with a reflector of type Foo, which you don't want for Bar that inherits from Foo 14:29 slyu-home A side question: why do we call it a "reflector" 14:29 slyu-home As far as I understand, it's something created in the JS VM so it can access the underlying Rust 14:29 Ms2ger It reflects DOM APIs across the JS<->Rust boundary 14:30 slyu-home I see 14:30 Ms2ger The alternative is "wrapper", which can mean any of a dozen things :) 14:30 slyu-home Because "reflect" makes me think of bouncing back 14:30 Ms2ger Heh 14:30 slyu-home Now I understand