Bug 929494 - use template typedefs, not inheritance, to define nsTArray element copiers; r=ehsan
authorNathan Froyd <froydnj@mozilla.com>
Tue, 22 Oct 2013 10:36:34 -0400
changeset 166512 8b72c1a37bd614c36ea0471efacf88c0022e9b4f
parent 166511 1811271ac7e187222cee41a327732ab77a8bcbd3
child 166513 d0e2322cbc600214f76d82d62620fc0a72b8982c
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs929494
milestone27.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 929494 - use template typedefs, not inheritance, to define nsTArray element copiers; r=ehsan There's no reason to use inheritance here, and using plain typedefs avoids massive amounts of code duplication for the common case of copying with mem*. Code savings on Android come in at about 570K (!), or ~2% of libxul .text size, which is a massive win.
layout/style/nsStyleStruct.h
xpcom/glue/nsTArray.h
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2415,18 +2415,19 @@ private:
   nsStyleCoord mFilterParameter; // coord, percent, factor, angle
   union {
     nsIURI* mURL;
     nsCSSShadowArray* mDropShadow;
   };
 };
 
 template<>
-struct nsTArray_CopyElements<nsStyleFilter>
-  : public nsTArray_CopyWithConstructors<nsStyleFilter> {};
+struct nsTArray_CopyChooser<nsStyleFilter> {
+  typedef nsTArray_CopyWithConstructors<nsStyleFilter> Type;
+};
 
 struct nsStyleSVGReset {
   nsStyleSVGReset();
   nsStyleSVGReset(const nsStyleSVGReset& aSource);
   ~nsStyleSVGReset();
 
   void* operator new(size_t sz, nsPresContext* aContext) CPP_THROW_NEW {
     return aContext->AllocateFromShell(sz);
--- a/xpcom/glue/nsTArray.h
+++ b/xpcom/glue/nsTArray.h
@@ -58,17 +58,17 @@ class Heap;
 // elements and has the following requirements:
 //
 //   T MUST be safely memmove()'able.
 //   T MUST define a copy-constructor.
 //   T MAY define operator< for sorting.
 //   T MAY define operator== for searching.
 //
 // (Note that the memmove requirement may be relaxed for certain types - see
-// nsTArray_CopyElements below.)
+// nsTArray_CopyChooser below.)
 //
 // For methods taking a Comparator instance, the Comparator must be a class
 // defining the following methods:
 //
 //   class Comparator {
 //     public:
 //       /** @return True if the elements are equals; false otherwise. */
 //       bool Equals(const elem_type& a, const Item& b) const;
@@ -568,17 +568,17 @@ struct AssignRangeAlgorithm<true, true> 
   static void implementation(ElemType* elements, IndexType start,
                              SizeType count, const Item *values) {
     memcpy(elements + start, values, count * sizeof(ElemType));
   }
 };
 
 //
 // Normally elements are copied with memcpy and memmove, but for some element
-// types that is problematic.  The nsTArray_CopyElements template class can be
+// types that is problematic.  The nsTArray_CopyChooser template class can be
 // specialized to ensure that copying calls constructors and destructors
 // instead, as is done below for JS::Heap<E> elements.
 //
 
 //
 // A class that defines how to copy elements using memcpy/memmove.
 //
 struct nsTArray_CopyWithMemutils
@@ -653,24 +653,28 @@ struct nsTArray_CopyWithConstructors
     }
   }
 };
 
 //
 // The default behaviour is to use memcpy/memmove for everything.
 //
 template <class E>
-struct nsTArray_CopyElements : public nsTArray_CopyWithMemutils {};
+struct nsTArray_CopyChooser {
+  typedef nsTArray_CopyWithMemutils Type;
+};
 
 //
 // JS::Heap<E> elements require constructors/destructors to be called and so is
 // specialized here.
 //
 template <class E>
-struct nsTArray_CopyElements<JS::Heap<E> > : public nsTArray_CopyWithConstructors<E> {};
+struct nsTArray_CopyChooser<JS::Heap<E> > {
+  typedef nsTArray_CopyWithConstructors<E> Type;
+};
 
 //
 // Base class for nsTArray_Impl that is templated on element type and derived
 // nsTArray_Impl class, to allow extra conversions to be added for specific
 // types.
 //
 template <class E, class Derived>
 struct nsTArray_TypedBase : public nsTArray_SafeElementAtHelper<E, Derived> {};
@@ -712,21 +716,21 @@ struct nsTArray_TypedBase<JS::Heap<E>, D
 // is if you're writing code which mutates a TArray which may or may not be
 // infallible.
 //
 // Code which merely reads from a TArray which may or may not be infallible can
 // simply cast the TArray to |const nsTArray&|; both fallible and infallible
 // TArrays can be cast to |const nsTArray&|.
 //
 template<class E, class Alloc>
-class nsTArray_Impl : public nsTArray_base<Alloc, nsTArray_CopyElements<E> >,
+class nsTArray_Impl : public nsTArray_base<Alloc, typename nsTArray_CopyChooser<E>::Type>,
                       public nsTArray_TypedBase<E, nsTArray_Impl<E, Alloc> >
 {
 public:
-  typedef nsTArray_CopyElements<E>                   copy_type;
+  typedef typename nsTArray_CopyChooser<E>::Type     copy_type;
   typedef nsTArray_base<Alloc, copy_type>            base_type;
   typedef typename base_type::size_type              size_type;
   typedef typename base_type::index_type             index_type;
   typedef E                                          elem_type;
   typedef nsTArray_Impl<E, Alloc>                    self_type;
   typedef nsTArrayElementTraits<E>                   elem_traits;
   typedef nsTArray_SafeElementAtHelper<E, self_type> safeelementat_helper_type;