Bug 928378 - Add description of post-barriers r=billm
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 17 Dec 2013 10:41:27 +0000
changeset 171015 92772cf08f61015352a5ae410fd2c5259692f9ea
parent 171014 661aa3848628f4d6e174dc953fafd7854d618a38
child 171016 ff89e684ff19680bf1f6b237ba4ead9ee93aa5f4
push id5166
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:47:54 +0000
treeherdermozilla-aurora@977eb2548b2d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs928378
milestone29.0a1
Bug 928378 - Add description of post-barriers r=billm
js/src/gc/Barrier.h
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -91,18 +91,35 @@
  * extra branch.
  *
  * In practice, we implement the pre-barrier differently based on the type of
  * value0. E.g., see JSObject::writeBarrierPre, which is used if obj->field is
  * a JSObject*. It takes value0 as a parameter.
  *
  *                                POST-BARRIER
  *
- * These are not yet implemented. Once we get generational GC, they will allow
- * us to keep track of pointers from non-nursery space into the nursery.
+ * For generational GC, we want to be able to quickly collect the nursery in a
+ * minor collection.  Part of the way this is achieved is to only mark the
+ * nursery itself; tenured things, which may form the majority of the heap, are
+ * not traced through or marked.  This leads to the problem of what to do about
+ * tenured objects that have pointers into the nursery: if such things are not
+ * marked, they may be discarded while there are still live objects which
+ * reference them. The solution is to maintain information about these pointers,
+ * and mark their targets when we start a minor collection.
+ *
+ * The pointers can be thoughs of as edges in object graph, and the set of edges
+ * from the tenured generation into the nursery is know as the remembered set.
+ * Post barriers are used to track this remembered set.
+ *
+ * Whenever a slot which could contain such a pointer is written, we use a write
+ * barrier to check if the edge created is in the remembered set, and if so we
+ * insert it into the store buffer, which is the collector's representation of
+ * the remembered set.  This means than when we come to do a minor collection we
+ * can examine the contents of the store buffer and mark any edge targets that
+ * are in the nursery.
  *
  *                            IMPLEMENTATION DETAILS
  *
  * Since it would be awkward to change every write to memory into a function
  * call, this file contains a bunch of C++ classes and templates that use
  * operator overloading to take care of barriers automatically. In many cases,
  * all that's necessary to make some field be barriered is to replace
  *     Type *field;
@@ -111,16 +128,31 @@
  * There are also special classes HeapValue and HeapId, which barrier js::Value
  * and jsid, respectively.
  *
  * One additional note: not all object writes need to be barriered. Writes to
  * newly allocated objects do not need a pre-barrier.  In these cases, we use
  * the "obj->field.init(value)" method instead of "obj->field = value". We use
  * the init naming idiom in many places to signify that a field is being
  * assigned for the first time.
+ *
+ * For each of pointers, Values and jsids this file implements four classes,
+ * illustrated here for the pointer (Ptr) classes:
+ *
+ * BarrieredPtr           abstract base class which provides common operations
+ *  |  |  |
+ *  |  | EncapsulatedPtr  provides pre-barriers only
+ *  |  |
+ *  | HeapPtr             provides pre- and post-barriers
+ *  |
+ * RelocatablePtr         provides pre- and post-barriers and is relocatable
+ *
+ * These classes are designed to be used by the internals of the JS engine.
+ * Barriers designed to be used externally are provided in
+ * js/public/RootingAPI.h.
  */
 
 namespace js {
 
 class PropertyName;
 
 #ifdef DEBUG
 bool