Bug 1461556 - Don't use mozilla::PodZero in a bunch of places to initialize values of non-trivial type. r=jandem
authorJeff Walden <jwalden@mit.edu>
Tue, 15 May 2018 09:31:24 -0700
changeset 418607 ead72cce7f0e
parent 418606 c68fadb2d596
child 418608 73c36389c5f7
push id103351
push userjwalden@mit.edu
push date2018-05-17 07:17 +0000
treeherdermozilla-inbound@e016aa76775e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1461556
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 1461556 - Don't use mozilla::PodZero in a bunch of places to initialize values of non-trivial type. r=jandem
js/public/MemoryMetrics.h
js/src/builtin/RegExp.cpp
js/src/gc/GCInternals.h
js/src/gc/Statistics.h
js/src/jit/IonCode.h
js/src/jit/shared/Assembler-shared.h
js/src/vm/Caches.h
js/src/vm/Runtime.h
js/src/vm/StringType.h
js/src/vm/TypeInference.h
js/src/wasm/WasmModule.h
--- a/js/public/MemoryMetrics.h
+++ b/js/public/MemoryMetrics.h
@@ -6,17 +6,16 @@
 
 #ifndef js_MemoryMetrics_h
 #define js_MemoryMetrics_h
 
 // These declarations are highly likely to change in the future. Depend on them
 // at your own risk.
 
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/PodOperations.h"
 #include "mozilla/TypeTraits.h"
 
 #include <string.h>
 
 #include "jspubtd.h"
 
 #include "js/AllocPolicy.h"
 #include "js/HashTable.h"
@@ -69,45 +68,37 @@ struct ServoSizes
         GCHeapUnused,
         GCHeapAdmin,
         GCHeapDecommitted,
         MallocHeap,
         NonHeap,
         Ignore
     };
 
-    ServoSizes()
-      : gcHeapUsed(0)
-      , gcHeapUnused(0)
-      , gcHeapAdmin(0)
-      , gcHeapDecommitted(0)
-      , mallocHeap(0)
-      , nonHeap(0)
-    {
-    }
+    ServoSizes() = default;
 
     void add(Kind kind, size_t n) {
         switch (kind) {
             case GCHeapUsed:        gcHeapUsed        += n; break;
             case GCHeapUnused:      gcHeapUnused      += n; break;
             case GCHeapAdmin:       gcHeapAdmin       += n; break;
             case GCHeapDecommitted: gcHeapDecommitted += n; break;
             case MallocHeap:        mallocHeap        += n; break;
             case NonHeap:           nonHeap           += n; break;
             case Ignore:            /* do nothing */        break;
             default:                MOZ_CRASH("bad ServoSizes kind");
         }
     }
 
-    size_t gcHeapUsed;
-    size_t gcHeapUnused;
-    size_t gcHeapAdmin;
-    size_t gcHeapDecommitted;
-    size_t mallocHeap;
-    size_t nonHeap;
+    size_t gcHeapUsed = 0;
+    size_t gcHeapUnused = 0;
+    size_t gcHeapAdmin = 0;
+    size_t gcHeapDecommitted = 0;
+    size_t mallocHeap = 0;
+    size_t nonHeap = 0;
 };
 
 } // namespace JS
 
 namespace js {
 
 /**
  * In memory reporting, we have concept of "sundries", line items which are too
--- a/js/src/builtin/RegExp.cpp
+++ b/js/src/builtin/RegExp.cpp
@@ -1173,21 +1173,21 @@ js::RegExpTesterRaw(JSContext* cx, Handl
 
     return false;
 }
 
 using CapturesVector = GCVector<Value, 4>;
 
 struct JSSubString
 {
-    JSLinearString* base;
-    size_t          offset;
-    size_t          length;
+    JSLinearString* base = nullptr;
+    size_t offset = 0;
+    size_t length = 0;
 
-    JSSubString() { mozilla::PodZero(this); }
+    JSSubString() = default;
 
     void initEmpty(JSLinearString* base) {
         this->base = base;
         offset = length = 0;
     }
     void init(JSLinearString* base, size_t offset, size_t length) {
         this->base = base;
         this->offset = offset;
--- a/js/src/gc/GCInternals.h
+++ b/js/src/gc/GCInternals.h
@@ -8,17 +8,16 @@
  * GC-internal definitions.
  */
 
 #ifndef gc_GCInternals_h
 #define gc_GCInternals_h
 
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Maybe.h"
-#include "mozilla/PodOperations.h"
 
 #include "gc/RelocationOverlay.h"
 #include "gc/Zone.h"
 #include "vm/HelperThreads.h"
 #include "vm/Runtime.h"
 
 namespace js {
 namespace gc {
@@ -153,19 +152,19 @@ struct TenureCount
 // Keep rough track of how many times we tenure objects in particular groups
 // during minor collections, using a fixed size hash for efficiency at the cost
 // of potential collisions.
 struct TenureCountCache
 {
     static const size_t EntryShift = 4;
     static const size_t EntryCount = 1 << EntryShift;
 
-    TenureCount entries[EntryCount];
+    TenureCount entries[EntryCount] = {}; // zeroes
 
-    TenureCountCache() { mozilla::PodZero(this); }
+    TenureCountCache() = default;
 
     HashNumber hash(ObjectGroup* group) {
 #if JS_BITS_PER_WORD == 32
         static const size_t ZeroBits = 3;
 #else
         static const size_t ZeroBits = 4;
 #endif
 
--- a/js/src/gc/Statistics.h
+++ b/js/src/gc/Statistics.h
@@ -6,17 +6,16 @@
 
 #ifndef gc_Statistics_h
 #define gc_Statistics_h
 
 #include "mozilla/Array.h"
 #include "mozilla/Atomics.h"
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/IntegerRange.h"
-#include "mozilla/PodOperations.h"
 #include "mozilla/TimeStamp.h"
 
 #include "jspubtd.h"
 #include "NamespaceImports.h"
 
 #include "gc/GCEnum.h"
 #include "js/AllocPolicy.h"
 #include "js/SliceBudget.h"
@@ -45,43 +44,41 @@ enum Stat {
     STAT_ARENA_RELOCATED,
 
     STAT_LIMIT
 };
 
 struct ZoneGCStats
 {
     /* Number of zones collected in this GC. */
-    int collectedZoneCount;
+    int collectedZoneCount = 0;
 
     /* Number of zones that could have been collected in this GC. */
-    int collectableZoneCount;
+    int collectableZoneCount = 0;
 
     /* Total number of zones in the Runtime at the start of this GC. */
-    int zoneCount;
+    int zoneCount = 0;
 
     /* Number of zones swept in this GC. */
-    int sweptZoneCount;
+    int sweptZoneCount = 0;
 
     /* Total number of compartments in all zones collected. */
-    int collectedCompartmentCount;
+    int collectedCompartmentCount = 0;
 
     /* Total number of compartments in the Runtime at the start of this GC. */
-    int compartmentCount;
+    int compartmentCount = 0;
 
     /* Total number of compartments swept by this GC. */
-    int sweptCompartmentCount;
+    int sweptCompartmentCount = 0;
 
     bool isFullCollection() const {
         return collectedZoneCount == collectableZoneCount;
     }
 
-    ZoneGCStats() {
-        mozilla::PodZero(this);
-    }
+    ZoneGCStats() = default;
 };
 
 #define FOR_EACH_GC_PROFILE_TIME(_)                                           \
     _(BeginCallback, "bgnCB",  PhaseKind::GC_BEGIN)                           \
     _(MinorForMajor, "evct4m", PhaseKind::EVICT_NURSERY_FOR_MAJOR_GC)         \
     _(WaitBgThread,  "waitBG", PhaseKind::WAIT_BACKGROUND_THREAD)             \
     _(Prepare,       "prep",   PhaseKind::PREPARE)                            \
     _(Mark,          "mark",   PhaseKind::MARK)                               \
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_IonCode_h
 #define jit_IonCode_h
 
 #include "mozilla/Atomics.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/PodOperations.h"
 
 #include "jstypes.h"
 
 #include "gc/Heap.h"
 #include "jit/ExecutableAllocator.h"
 #include "jit/ICStubSpace.h"
 #include "jit/IonOptimizationLevels.h"
 #include "jit/IonTypes.h"
@@ -672,27 +671,24 @@ struct IonBlockCounts
 };
 
 // Execution information for a compiled script which may persist after the
 // IonScript is destroyed, for use during profiling.
 struct IonScriptCounts
 {
   private:
     // Any previous invalidated compilation(s) for the script.
-    IonScriptCounts* previous_;
+    IonScriptCounts* previous_ = nullptr;
 
     // Information about basic blocks in this script.
-    size_t numBlocks_;
-    IonBlockCounts* blocks_;
+    size_t numBlocks_ = 0;
+    IonBlockCounts* blocks_ = nullptr;
 
   public:
-
-    IonScriptCounts() {
-        mozilla::PodZero(this);
-    }
+    IonScriptCounts() = default;
 
     ~IonScriptCounts() {
         for (size_t i = 0; i < numBlocks_; i++)
             blocks_[i].destroy();
         js_free(blocks_);
         // The list can be long in some corner cases (bug 1140084), so
         // unroll the recursion.
         IonScriptCounts* victims = previous_;
--- a/js/src/jit/shared/Assembler-shared.h
+++ b/js/src/jit/shared/Assembler-shared.h
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef jit_shared_Assembler_shared_h
 #define jit_shared_Assembler_shared_h
 
 #include "mozilla/CheckedInt.h"
-#include "mozilla/PodOperations.h"
 
 #include <limits.h>
 
 #include "jit/AtomicOp.h"
 #include "jit/JitAllocPolicy.h"
 #include "jit/Label.h"
 #include "jit/Registers.h"
 #include "jit/RegisterSets.h"
@@ -592,38 +591,36 @@ private:
 
 typedef Vector<CodeLabel, 0, SystemAllocPolicy> CodeLabelVector;
 
 // Location of a jump or label in a generated JitCode block, relative to the
 // start of the block.
 
 class CodeOffsetJump
 {
-    size_t offset_;
+    size_t offset_ = 0;
 
 #ifdef JS_SMALL_BRANCH
-    size_t jumpTableIndex_;
+    size_t jumpTableIndex_ = 0;
 #endif
 
   public:
 
 #ifdef JS_SMALL_BRANCH
     CodeOffsetJump(size_t offset, size_t jumpTableIndex)
         : offset_(offset), jumpTableIndex_(jumpTableIndex)
     {}
     size_t jumpTableIndex() const {
         return jumpTableIndex_;
     }
 #else
     explicit CodeOffsetJump(size_t offset) : offset_(offset) {}
 #endif
 
-    CodeOffsetJump() {
-        mozilla::PodZero(this);
-    }
+    CodeOffsetJump() = default;
 
     size_t offset() const {
         return offset_;
     }
     void fixup(MacroAssembler* masm);
 };
 
 // Absolute location of a jump or a label in some generated JitCode block.
--- a/js/src/vm/Caches.h
+++ b/js/src/vm/Caches.h
@@ -2,16 +2,18 @@
  * vim: set ts=8 sts=4 et sw=4 tw=99:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_Caches_h
 #define vm_Caches_h
 
+#include <new>
+
 #include "jsmath.h"
 
 #include "frontend/SourceNotes.h"
 #include "gc/Tracer.h"
 #include "js/RootingAPI.h"
 #include "js/TypeDecls.h"
 #include "js/UniquePtr.h"
 #include "vm/ArrayObject.h"
@@ -137,24 +139,30 @@ class NewObjectCache
 
         /*
          * Template object to copy from, with the initial values of fields,
          * fixed slots (undefined) and private data (nullptr).
          */
         char templateObject[MAX_OBJ_SIZE];
     };
 
-    Entry entries[41];  // TODO: reconsider size
+    using EntryArray = Entry[41]; // TODO: reconsider size;
+    EntryArray entries;
 
   public:
 
-    typedef int EntryIndex;
+    using EntryIndex = int;
 
-    NewObjectCache() { mozilla::PodZero(this); }
-    void purge() { mozilla::PodZero(this); }
+    NewObjectCache()
+      : entries{} // zeroes out the array
+    {}
+
+    void purge() {
+        new (&entries) EntryArray{}; // zeroes out the array
+    }
 
     /* Remove any cached items keyed on moved objects. */
     void clearNurseryObjects(JSRuntime* rt);
 
     /*
      * Get the entry index for the given lookup, return whether there was a hit
      * on an existing entry.
      */
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -9,21 +9,21 @@
 
 #include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DoublyLinkedList.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MaybeOneOf.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/PodOperations.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/ThreadLocal.h"
 #include "mozilla/Vector.h"
 
+#include <algorithm>
 #include <setjmp.h>
 
 #include "builtin/AtomicsObject.h"
 #include "builtin/intl/SharedIntlData.h"
 #include "builtin/Promise.h"
 #include "frontend/BinSourceRuntimeSupport.h"
 #include "frontend/NameCollections.h"
 #include "gc/GCRuntime.h"
@@ -1088,48 +1088,49 @@ class MOZ_RAII AutoUnlockGC
     AutoUnlockGC& operator=(const AutoUnlockGC&) = delete;
 };
 
 /************************************************************************/
 
 static MOZ_ALWAYS_INLINE void
 MakeRangeGCSafe(Value* vec, size_t len)
 {
-    mozilla::PodZero(vec, len);
+    // Don't PodZero here because JS::Value is non-trivial.
+    for (size_t i = 0; i < len; i++)
+        vec[i].setDouble(+0.0);
 }
 
 static MOZ_ALWAYS_INLINE void
 MakeRangeGCSafe(Value* beg, Value* end)
 {
-    mozilla::PodZero(beg, end - beg);
+    MakeRangeGCSafe(beg, end - beg);
 }
 
 static MOZ_ALWAYS_INLINE void
 MakeRangeGCSafe(jsid* beg, jsid* end)
 {
-    for (jsid* id = beg; id != end; ++id)
-        *id = INT_TO_JSID(0);
+    std::fill(beg, end, INT_TO_JSID(0));
 }
 
 static MOZ_ALWAYS_INLINE void
 MakeRangeGCSafe(jsid* vec, size_t len)
 {
     MakeRangeGCSafe(vec, vec + len);
 }
 
 static MOZ_ALWAYS_INLINE void
 MakeRangeGCSafe(Shape** beg, Shape** end)
 {
-    mozilla::PodZero(beg, end - beg);
+    std::fill(beg, end, nullptr);
 }
 
 static MOZ_ALWAYS_INLINE void
 MakeRangeGCSafe(Shape** vec, size_t len)
 {
-    mozilla::PodZero(vec, len);
+    MakeRangeGCSafe(vec, vec + len);
 }
 
 static MOZ_ALWAYS_INLINE void
 SetValueRangeToUndefined(Value* beg, Value* end)
 {
     for (Value* v = beg; v != end; ++v)
         v->setUndefined();
 }
--- a/js/src/vm/StringType.h
+++ b/js/src/vm/StringType.h
@@ -3,17 +3,16 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_StringType_h
 #define vm_StringType_h
 
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/PodOperations.h"
 #include "mozilla/Range.h"
 #include "mozilla/TextUtils.h"
 
 #include "jsapi.h"
 #include "jsfriendapi.h"
 
 #include "builtin/String.h"
 #include "gc/Barrier.h"
@@ -1275,29 +1274,27 @@ namespace js {
 
 class StaticStrings
 {
   private:
     /* Bigger chars cannot be in a length-2 string. */
     static const size_t SMALL_CHAR_LIMIT    = 128U;
     static const size_t NUM_SMALL_CHARS     = 64U;
 
-    JSAtom* length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS];
+    JSAtom* length2StaticTable[NUM_SMALL_CHARS * NUM_SMALL_CHARS] = {}; // zeroes
 
   public:
     /* We keep these public for the JITs. */
     static const size_t UNIT_STATIC_LIMIT   = 256U;
-    JSAtom* unitStaticTable[UNIT_STATIC_LIMIT];
+    JSAtom* unitStaticTable[UNIT_STATIC_LIMIT] = {}; // zeroes
 
     static const size_t INT_STATIC_LIMIT    = 256U;
-    JSAtom* intStaticTable[INT_STATIC_LIMIT];
+    JSAtom* intStaticTable[INT_STATIC_LIMIT] = {}; // zeroes
 
-    StaticStrings() {
-        mozilla::PodZero(this);
-    }
+    StaticStrings() = default;
 
     bool init(JSContext* cx);
     void trace(JSTracer* trc);
 
     static bool hasUint(uint32_t u) { return u < INT_STATIC_LIMIT; }
 
     JSAtom* getUint(uint32_t u) {
         MOZ_ASSERT(hasUint(u));
--- a/js/src/vm/TypeInference.h
+++ b/js/src/vm/TypeInference.h
@@ -952,22 +952,20 @@ AddClearDefiniteFunctionUsesInScript(JSC
 class PreliminaryObjectArray
 {
   public:
     static const uint32_t COUNT = 20;
 
   private:
     // All objects with the type which have been allocated. The pointers in
     // this array are weak.
-    JSObject* objects[COUNT];
+    JSObject* objects[COUNT] = {}; // zeroes
 
   public:
-    PreliminaryObjectArray() {
-        mozilla::PodZero(this);
-    }
+    PreliminaryObjectArray() = default;
 
     void registerNewObject(PlainObject* res);
     void unregisterObject(PlainObject* obj);
 
     JSObject* get(size_t i) const {
         MOZ_ASSERT(i < COUNT);
         return objects[i];
     }
@@ -1051,53 +1049,53 @@ class TypeNewScript
         uint32_t offset;
         Initializer(Kind kind, uint32_t offset)
           : kind(kind), offset(offset)
         {}
     };
 
   private:
     // Scripted function which this information was computed for.
-    HeapPtr<JSFunction*> function_;
+    HeapPtr<JSFunction*> function_ = {};
 
     // Any preliminary objects with the type. The analyses are not performed
     // until this array is cleared.
-    PreliminaryObjectArray* preliminaryObjects;
+    PreliminaryObjectArray* preliminaryObjects = nullptr;
 
     // After the new script properties analyses have been performed, a template
     // object to use for newly constructed objects. The shape of this object
     // reflects all definite properties the object will have, and the
     // allocation kind to use. This is null if the new objects have an unboxed
     // layout, in which case the UnboxedLayout provides the initial structure
     // of the object.
-    HeapPtr<PlainObject*> templateObject_;
+    HeapPtr<PlainObject*> templateObject_ = {};
 
     // Order in which definite properties become initialized. We need this in
     // case the definite properties are invalidated (such as by adding a setter
     // to an object on the prototype chain) while an object is in the middle of
     // being initialized, so we can walk the stack and fixup any objects which
     // look for in-progress objects which were prematurely set with an incorrect
     // shape. Property assignments in inner frames are preceded by a series of
     // SETPROP_FRAME entries specifying the stack down to the frame containing
     // the write.
-    Initializer* initializerList;
+    Initializer* initializerList = nullptr;
 
     // If there are additional properties found by the acquired properties
     // analysis which were not found by the definite properties analysis, this
     // shape contains all such additional properties (plus the definite
     // properties). When an object of this group acquires this shape, it is
     // fully initialized and its group can be changed to initializedGroup.
-    HeapPtr<Shape*> initializedShape_;
+    HeapPtr<Shape*> initializedShape_ = {};
 
     // Group with definite properties set for all properties found by
     // both the definite and acquired properties analyses.
-    HeapPtr<ObjectGroup*> initializedGroup_;
+    HeapPtr<ObjectGroup*> initializedGroup_ = {};
 
   public:
-    TypeNewScript() { mozilla::PodZero(this); }
+    TypeNewScript() = default;
     ~TypeNewScript() {
         js_delete(preliminaryObjects);
         js_free(initializerList);
     }
 
     void clear() {
         function_ = nullptr;
         templateObject_ = nullptr;
--- a/js/src/wasm/WasmModule.h
+++ b/js/src/wasm/WasmModule.h
@@ -38,21 +38,21 @@ struct CompileArgs;
 //
 // LinkData is built incrementally by ModuleGenerator and then stored immutably
 // in Module. LinkData is distinct from Metadata in that LinkData is owned and
 // destroyed by the Module since it is not needed after instantiation; Metadata
 // is needed at runtime.
 
 struct LinkDataTierCacheablePod
 {
-    uint32_t outOfBoundsOffset;
-    uint32_t unalignedAccessOffset;
-    uint32_t trapOffset;
+    uint32_t outOfBoundsOffset = 0;
+    uint32_t unalignedAccessOffset = 0;
+    uint32_t trapOffset = 0;
 
-    LinkDataTierCacheablePod() { mozilla::PodZero(this); }
+    LinkDataTierCacheablePod() = default;
 };
 
 struct LinkDataTier : LinkDataTierCacheablePod
 {
     const Tier tier;
 
     explicit LinkDataTier(Tier tier) : tier(tier) {}