Bug 1275033 - Optimise global object write barrier r=jandem
authorJon Coppeard <jcoppeard@mozilla.com>
Tue, 24 May 2016 12:39:26 +0100
changeset 298652 3a7ba1ce51d6be815e7ff170025349176ef25cf4
parent 298651 aa5838e85fc88a169fc8c9918160d422bab442d1
child 298653 1fe1c3b03d083e4748d4456d1ea207959dc161cb
push id77265
push userjcoppeard@mozilla.com
push dateTue, 24 May 2016 11:44:37 +0000
treeherdermozilla-inbound@3a7ba1ce51d6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1275033
milestone49.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 1275033 - Optimise global object write barrier r=jandem
js/src/jit/CodeGenerator.cpp
js/src/jit/VMFunctions.cpp
js/src/jscompartment.cpp
js/src/jscompartment.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -3465,18 +3465,30 @@ CodeGenerator::emitPostWriteBarrier(Regi
     AllocatableGeneralRegisterSet regs(GeneralRegisterSet::Volatile());
     regs.takeUnchecked(objreg);
     EmitPostWriteBarrier(masm, objreg, false, regs);
 }
 
 void
 CodeGenerator::visitOutOfLineCallPostWriteBarrier(OutOfLineCallPostWriteBarrier* ool)
 {
+    const LAllocation* obj = ool->object();
+
+    // Check whether the object is a global that we have already barriered
+    // before calling into the VM.
+    if (obj->isConstant()) {
+        JSObject* object = &obj->toConstant()->toObject();
+        if (object->is<GlobalObject>()) {
+            JSCompartment* comp = object->compartment();
+            AbsoluteAddress addr(&comp->globalWriteBarriered);
+            masm.branch32(Assembler::NotEqual, addr, Imm32(0), ool->rejoin());
+        }
+    }
+
     saveLiveVolatile(ool->lir());
-    const LAllocation* obj = ool->object();
     emitPostWriteBarrier(obj);
     restoreLiveVolatile(ool->lir());
 
     masm.jump(ool->rejoin());
 }
 
 template <class LPostBarrierType>
 void
--- a/js/src/jit/VMFunctions.cpp
+++ b/js/src/jit/VMFunctions.cpp
@@ -627,17 +627,17 @@ PostWriteElementBarrier(JSRuntime* rt, J
 }
 
 void
 PostGlobalWriteBarrier(JSRuntime* rt, JSObject* obj)
 {
     MOZ_ASSERT(obj->is<GlobalObject>());
     if (!obj->compartment()->globalWriteBarriered) {
         PostWriteBarrier(rt, obj);
-        obj->compartment()->globalWriteBarriered = true;
+        obj->compartment()->globalWriteBarriered = 1;
     }
 }
 
 uint32_t
 GetIndexFromString(JSString* str)
 {
     // Masks the return value UINT32_MAX as failure to get the index.
     // I.e. it is impossible to distinguish between failing to get the index
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -58,17 +58,17 @@ JSCompartment::JSCompartment(Zone* zone,
 #endif
     global_(nullptr),
     enterCompartmentDepth(0),
     performanceMonitoring(runtime_),
     data(nullptr),
     allocationMetadataBuilder(nullptr),
     lastAnimationTime(0),
     regExps(runtime_),
-    globalWriteBarriered(false),
+    globalWriteBarriered(0),
     detachedTypedObjects(0),
     objectMetadataState(ImmediateMetadata()),
     propertyTree(thisForCtor()),
     baseShapes(zone, BaseShapeSet()),
     initialShapes(zone, InitialShapeSet()),
     selfHostingScriptSource(nullptr),
     objectMetadataTable(nullptr),
     lazyArrayBuffers(nullptr),
@@ -675,17 +675,17 @@ JSCompartment::traceRoots(JSTracer* trc,
 
     if (nonSyntacticLexicalScopes_)
         nonSyntacticLexicalScopes_->trace(trc);
 }
 
 void
 JSCompartment::sweepAfterMinorGC()
 {
-    globalWriteBarriered = false;
+    globalWriteBarriered = 0;
 
     if (innerViews.needsSweepAfterMinorGC())
         innerViews.sweepAfterMinorGC();
 }
 
 void
 JSCompartment::sweepInnerViews()
 {
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -422,20 +422,20 @@ struct JSCompartment
     int64_t                      lastAnimationTime;
 
     js::RegExpCompartment        regExps;
 
     /*
      * For generational GC, record whether a write barrier has added this
      * compartment's global to the store buffer since the last minor GC.
      *
-     * This is used to avoid adding it to the store buffer on every write, which
-     * can quickly fill the buffer and also cause performance problems.
+     * This is used to avoid calling into the VM every time a nursery object is
+     * written to a property of the global.
      */
-    bool                         globalWriteBarriered;
+    uint32_t                     globalWriteBarriered;
 
     // Non-zero if the storage underlying any typed object in this compartment
     // might be detached.
     int32_t                      detachedTypedObjects;
 
   private:
     friend class js::AutoSetNewObjectMetadata;
     js::NewObjectMetadataState objectMetadataState;