Bug 1264830 - Part 1: Add an nsStyleAutoArray array type, similar to AutoTArray<...,1> but memmovable. r=bholley
authorCameron McCormack <cam@mcc.id.au>
Tue, 19 Apr 2016 09:51:15 +1000
changeset 317454 4f5b11b6680d5b17d74839152e8c6c5841debf51
parent 317453 53252c783a434673b8c56728c2273f984883bc53
child 317455 38c2a55b608c064321c82531c06cdf414ecfe0ba
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbholley
bugs1264830
milestone48.0a1
Bug 1264830 - Part 1: Add an nsStyleAutoArray array type, similar to AutoTArray<...,1> but memmovable. r=bholley Existing uses of AutoTArray in style structs makes them non-memmovable. We introduce this AutoTArray-alike class for use by those style struct members that really do need to use an auto array's built-in allocation.
layout/style/nsStyleStruct.h
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -448,16 +448,75 @@ struct nsStyleColor
       FreeByObjectID(mozilla::eArenaObjectID_nsStyleColor, this);
   }
 
   // Don't add ANY members to this struct!  We can achieve caching in the rule
   // tree (rather than the style tree) by letting color stay by itself! -dwh
   nscolor mColor;                 // [inherited]
 };
 
+/**
+ * An array of objects, similar to AutoTArray<T,1> but which is memmovable. It
+ * always has length >= 1.
+ */
+template<typename T>
+class nsStyleAutoArray
+{
+public:
+  // This constructor places a single element in mFirstElement.
+  enum WithSingleInitialElement { WITH_SINGLE_INITIAL_ELEMENT };
+  explicit nsStyleAutoArray(WithSingleInitialElement) {}
+  nsStyleAutoArray(const nsStyleAutoArray& aOther) { *this = aOther; }
+  nsStyleAutoArray& operator=(const nsStyleAutoArray& aOther) {
+    mFirstElement = aOther.mFirstElement;
+    mOtherElements = aOther.mOtherElements;
+    return *this;
+  }
+
+  bool operator==(const nsStyleAutoArray& aOther) const {
+    return Length() == aOther.Length() &&
+           mFirstElement == aOther.mFirstElement &&
+           mOtherElements == aOther.mOtherElements;
+  }
+  bool operator!=(const nsStyleAutoArray& aOther) const {
+    return !(*this == aOther);
+  }
+
+  size_t Length() const {
+    return mOtherElements.Length() + 1;
+  }
+  const T& operator[](size_t aIndex) const {
+    return aIndex == 0 ? mFirstElement : mOtherElements[aIndex - 1];
+  }
+  T& operator[](size_t aIndex) {
+    return aIndex == 0 ? mFirstElement : mOtherElements[aIndex - 1];
+  }
+
+  void EnsureLengthAtLeast(size_t aMinLen) {
+    if (aMinLen > 0) {
+      mOtherElements.EnsureLengthAtLeast(aMinLen - 1);
+    }
+  }
+
+  void SetLengthNonZero(size_t aNewLen) {
+    MOZ_ASSERT(aNewLen > 0);
+    mOtherElements.SetLength(aNewLen - 1);
+  }
+
+  void TruncateLengthNonZero(size_t aNewLen) {
+    MOZ_ASSERT(aNewLen > 0);
+    MOZ_ASSERT(aNewLen <= Length());
+    mOtherElements.TruncateLength(aNewLen - 1);
+  }
+
+private:
+  T mFirstElement;
+  nsTArray<T> mOtherElements;
+};
+
 struct nsStyleImageLayers {
   nsStyleImageLayers();
   nsStyleImageLayers(const nsStyleImageLayers &aSource);
   ~nsStyleImageLayers() {
     MOZ_COUNT_DTOR(nsStyleImageLayers);
   }
 
   // Indices into kBackgroundLayerTable and kMaskLayerTable