Bug 1462693 - Update JSScript and LazyScript in separate phases in compacting GC r=sfink
authorJon Coppeard <jcoppeard@mozilla.com>
Mon, 04 Jun 2018 11:18:04 +0100
changeset 475384 6e430a8ad9cc8e2568a9f5f87bcb324a6db68916
parent 475383 df11dced021e6e4ef9f38ae84c56842b12cce173
child 475385 aefbe3ce94760bb582b259e4b45c98be4dfeab10
push id9374
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:43:20 +0000
treeherdermozilla-beta@160e085dfb0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1462693
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1462693 - Update JSScript and LazyScript in separate phases in compacting GC r=sfink
js/src/gc/GC.cpp
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -2854,32 +2854,40 @@ GCRuntime::updateCellPointers(Zone* zone
 //   - Updating a typed object makes use of its type descriptor object
 //
 // This means we require at least three phases for update:
 //
 //  1) shapes
 //  2) typed object type descriptor objects
 //  3) all other objects
 //
-// Since we want to minimize the number of phases, we put everything else into
-// the first phase and label it the 'misc' phase.
-
-static const AllocKinds UpdatePhaseMisc {
+// Also, JSScripts and LazyScripts can have pointers to each other. Each can be
+// updated safely without requiring the referent to be up-to-date, but TSAN can
+// warn about data races when calling IsForwarded() on the new location of a
+// cell that is being updated in parallel. To avoid this, we update these in
+// separate phases.
+//
+// Since we want to minimize the number of phases, arrange kinds into three
+// arbitrary phases.
+
+static const AllocKinds UpdatePhaseOne {
     AllocKind::SCRIPT,
-    AllocKind::LAZY_SCRIPT,
     AllocKind::BASE_SHAPE,
     AllocKind::SHAPE,
     AllocKind::ACCESSOR_SHAPE,
     AllocKind::OBJECT_GROUP,
     AllocKind::STRING,
     AllocKind::JITCODE,
     AllocKind::SCOPE
 };
 
-static const AllocKinds UpdatePhaseObjects {
+// UpdatePhaseTwo is typed object descriptor objects.
+
+static const AllocKinds UpdatePhaseThree {
+    AllocKind::LAZY_SCRIPT,
     AllocKind::FUNCTION,
     AllocKind::FUNCTION_EXTENDED,
     AllocKind::OBJECT0,
     AllocKind::OBJECT0_BACKGROUND,
     AllocKind::OBJECT2,
     AllocKind::OBJECT2_BACKGROUND,
     AllocKind::OBJECT4,
     AllocKind::OBJECT4_BACKGROUND,
@@ -2891,23 +2899,23 @@ static const AllocKinds UpdatePhaseObjec
     AllocKind::OBJECT16_BACKGROUND
 };
 
 void
 GCRuntime::updateAllCellPointers(MovingTracer* trc, Zone* zone)
 {
     size_t bgTaskCount = CellUpdateBackgroundTaskCount();
 
-    updateCellPointers(zone, UpdatePhaseMisc, bgTaskCount);
-
-    // Update TypeDescrs before all other objects as typed objects access these
-    // objects when we trace them.
+    updateCellPointers(zone, UpdatePhaseOne, bgTaskCount);
+
+    // UpdatePhaseTwo: Update TypeDescrs before all other objects as typed
+    // objects access these objects when we trace them.
     updateTypeDescrObjects(trc, zone);
 
-    updateCellPointers(zone, UpdatePhaseObjects, bgTaskCount);
+    updateCellPointers(zone, UpdatePhaseThree, bgTaskCount);
 }
 
 /*
  * Update pointers to relocated cells in a single zone by doing a traversal of
  * that zone's arenas and calling per-zone sweep hooks.
  *
  * The latter is necessary to update weak references which are not marked as
  * part of the traversal.