Bug 1626587 - Part 3: Replace mozilla::IsPod in InlineTablePool. r=jwalden
authorAndré Bargull <andre.bargull@gmail.com>
Mon, 27 Apr 2020 10:11:20 +0000
changeset 526238 239b37c87f58f323922ec9e781d02d2be1984d1f
parent 526237 1e75beb9d31158b254179ed89bd4ac8ff9cc9cac
child 526239 1e75de42137c533f4cc8919b6cd51cb14eaa379a
push id114141
push userdluca@mozilla.com
push dateMon, 27 Apr 2020 14:18:59 +0000
treeherderautoland@1e75de42137c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1626587
milestone77.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 1626587 - Part 3: Replace mozilla::IsPod in InlineTablePool. r=jwalden We can't use `std::is_trivial` for the table entry type, because the entry value isn't trivially default constructible. (Neither `mozilla::HashMapEntry` nor `RecyclableAtomMapValueWrapper` are trivially default constructible.) So instead of using `std::is_trivial<EntryType>` directly, we have to check `std::is_trivial<KeyType>` and `std::is_trivial<ValueType>` separately, where we potentially need to unwrap `ValueType` in case it's `IsRecyclableAtomMapValueWrapper`. This allows to remove the `mozilla::IsPod` specialisations for `NameLocation`, `DeclaredNameInfo`, `MaybeCheckTDZ`, and `RecyclableAtomMapValueWrapper`. Differential Revision: https://phabricator.services.mozilla.com/D69200
js/src/frontend/NameAnalysisTypes.h
js/src/frontend/NameCollections.h
js/src/vm/Stack.h
--- a/js/src/frontend/NameAnalysisTypes.h
+++ b/js/src/frontend/NameAnalysisTypes.h
@@ -335,19 +335,9 @@ using AtomVector = Vector<JSAtom*, 24, S
 class FunctionBox;
 // FunctionBoxes stored in this type are required to be rooted
 // by the parser
 using FunctionBoxVector = Vector<const FunctionBox*, 8>;
 
 }  // namespace frontend
 }  // namespace js
 
-namespace mozilla {
-
-template <>
-struct IsPod<js::frontend::DeclaredNameInfo> : std::true_type {};
-
-template <>
-struct IsPod<js::frontend::NameLocation> : std::true_type {};
-
-}  // namespace mozilla
-
 #endif  // frontend_NameAnalysisTypes_h
--- a/js/src/frontend/NameCollections.h
+++ b/js/src/frontend/NameCollections.h
@@ -102,16 +102,18 @@ class CollectionPool {
     // Reserved in allocateFresh.
     recyclable_.infallibleAppend(*collection);
     *collection = nullptr;
   }
 };
 
 template <typename Wrapped>
 struct RecyclableAtomMapValueWrapper {
+  using WrappedType = Wrapped;
+
   union {
     Wrapped wrapped;
     uint64_t dummy;
   };
 
   static void assertInvariant() {
     static_assert(sizeof(Wrapped) <= sizeof(uint64_t),
                   "Can only recycle atom maps with values smaller than uint64");
@@ -151,25 +153,58 @@ using RecyclableNameMap =
 using DeclaredNameMap = RecyclableNameMap<DeclaredNameInfo>;
 using NameLocationMap = RecyclableNameMap<NameLocation>;
 using AtomIndexMap = RecyclableNameMap<uint32_t>;
 
 template <typename RepresentativeTable>
 class InlineTablePool
     : public CollectionPool<RepresentativeTable,
                             InlineTablePool<RepresentativeTable>> {
+  template <typename>
+  struct IsRecyclableAtomMapValueWrapper : std::false_type {};
+
+  template <typename T>
+  struct IsRecyclableAtomMapValueWrapper<RecyclableAtomMapValueWrapper<T>>
+      : std::true_type {};
+
  public:
   template <typename Table>
   static void assertInvariants() {
     static_assert(
         Table::SizeOfInlineEntries == RepresentativeTable::SizeOfInlineEntries,
         "Only tables with the same size for inline entries are usable in the "
         "pool.");
-    static_assert(mozilla::IsPod<typename Table::Table::Entry>::value,
-                  "Only tables with POD values are usable in the pool.");
+
+    using EntryType = typename Table::Table::Entry;
+    using KeyType = typename EntryType::KeyType;
+    using ValueType = typename EntryType::ValueType;
+
+    static_assert(IsRecyclableAtomMapValueWrapper<ValueType>::value,
+                  "Please adjust the static assertions below if you need to "
+                  "support other types than RecyclableAtomMapValueWrapper");
+
+    using WrappedType = typename ValueType::WrappedType;
+
+    // We can't directly check |std::is_trivial<EntryType>|, because neither
+    // mozilla::HashMapEntry nor IsRecyclableAtomMapValueWrapper are trivially
+    // default constructible. Instead we check that the key and the unwrapped
+    // value are trivial and additionally ensure that the entry itself is
+    // trivially copyable and destructible.
+
+    static_assert(std::is_trivial_v<KeyType>,
+                  "Only tables with trivial keys are usable in the pool.");
+    static_assert(std::is_trivial_v<WrappedType>,
+                  "Only tables with trivial values are usable in the pool.");
+
+    static_assert(
+        std::is_trivially_copyable_v<EntryType>,
+        "Only tables with trivially copyable entries are usable in the pool.");
+    static_assert(std::is_trivially_destructible_v<EntryType>,
+                  "Only tables with trivially destructible entries are usable "
+                  "in the pool.");
   }
 };
 
 template <typename RepresentativeVector>
 class VectorPool : public CollectionPool<RepresentativeVector,
                                          VectorPool<RepresentativeVector>> {
  public:
   template <typename Vector>
@@ -334,16 +369,9 @@ class PooledVectorPtr : public PooledCol
   const typename Vector::ElementType& operator[](size_t index) const {
     return collection()[index];
   }
 };
 
 }  // namespace frontend
 }  // namespace js
 
-namespace mozilla {
-
-template <typename T>
-struct IsPod<js::frontend::RecyclableAtomMapValueWrapper<T>> : IsPod<T> {};
-
-}  // namespace mozilla
-
 #endif  // frontend_NameCollections_h
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -79,21 +79,16 @@ class Instance;
 // from the stack and the InterpreterRegs struct (pointed to by the
 // InterpreterActivation) is a local var of js::Interpret.
 
 enum MaybeCheckAliasing { CHECK_ALIASING = true, DONT_CHECK_ALIASING = false };
 enum MaybeCheckTDZ { CheckTDZ = true, DontCheckTDZ = false };
 
 }  // namespace js
 
-namespace mozilla {
-template <>
-struct IsPod<js::MaybeCheckTDZ> : std::true_type {};
-}  // namespace mozilla
-
 /*****************************************************************************/
 
 namespace js {
 
 namespace jit {
 class BaselineFrame;
 class RematerializedFrame;
 }  // namespace jit