зеркало из https://github.com/mozilla/gecko-dev.git
Bug 723228 - nsTArray::AssignRange should use memcpy when possible. r=jlebar for the XPCOM changes, r=jwalden for js/mfbt changes
--HG-- extra : rebase_source : 2442a0d29ae0fa7edd0312d980cbc270a4f33134
This commit is contained in:
Родитель
7e794af42a
Коммит
c8372e3fae
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "js/TemplateLib.h"
|
||||
|
@ -546,20 +547,25 @@ class HashMapEntry
|
|||
Value value;
|
||||
};
|
||||
|
||||
namespace tl {
|
||||
} // namespace js
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template <class T>
|
||||
struct IsPodType<detail::HashTableEntry<T> > {
|
||||
static const bool result = IsPodType<T>::result;
|
||||
struct IsPod<js::detail::HashTableEntry<T> >
|
||||
{
|
||||
static const bool result = IsPod<T>::result;
|
||||
};
|
||||
|
||||
template <class K, class V>
|
||||
struct IsPodType<HashMapEntry<K, V> >
|
||||
struct IsPod<js::HashMapEntry<K, V> >
|
||||
{
|
||||
static const bool result = IsPodType<K>::result && IsPodType<V>::result;
|
||||
static const bool result = IsPod<K>::result && IsPod<V>::result;
|
||||
};
|
||||
|
||||
} // namespace tl
|
||||
} // namespace mozilla
|
||||
|
||||
namespace js {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
@ -1244,7 +1250,7 @@ class HashTable : private AllocPolicy
|
|||
public:
|
||||
void clear()
|
||||
{
|
||||
if (tl::IsPodType<Entry>::result) {
|
||||
if (mozilla::IsPod<Entry>::result) {
|
||||
memset(table, 0, sizeof(*table) * capacity());
|
||||
} else {
|
||||
uint32_t tableCapacity = capacity();
|
||||
|
|
|
@ -68,14 +68,6 @@ template <class T> struct BitSize {
|
|||
template <bool> struct StaticAssert {};
|
||||
template <> struct StaticAssert<true> { typedef int result; };
|
||||
|
||||
/* Boolean test for whether two types are the same. */
|
||||
template <class T, class U> struct IsSameType {
|
||||
static const bool result = false;
|
||||
};
|
||||
template <class T> struct IsSameType<T,T> {
|
||||
static const bool result = true;
|
||||
};
|
||||
|
||||
/*
|
||||
* Produce an N-bit mask, where N <= BitSize<size_t>::result. Handle the
|
||||
* language-undefined edge case when N = BitSize<size_t>::result.
|
||||
|
@ -116,34 +108,9 @@ template <class T> struct UnsafeRangeSizeMask {
|
|||
template <class T> struct StripConst { typedef T result; };
|
||||
template <class T> struct StripConst<const T> { typedef T result; };
|
||||
|
||||
/*
|
||||
* Traits class for identifying POD types. Until C++0x, there is no automatic
|
||||
* way to detect PODs, so for the moment it is done manually.
|
||||
*/
|
||||
template <class T> struct IsPodType { static const bool result = false; };
|
||||
template <> struct IsPodType<char> { static const bool result = true; };
|
||||
template <> struct IsPodType<signed char> { static const bool result = true; };
|
||||
template <> struct IsPodType<unsigned char> { static const bool result = true; };
|
||||
template <> struct IsPodType<short> { static const bool result = true; };
|
||||
template <> struct IsPodType<unsigned short> { static const bool result = true; };
|
||||
template <> struct IsPodType<int> { static const bool result = true; };
|
||||
template <> struct IsPodType<unsigned int> { static const bool result = true; };
|
||||
template <> struct IsPodType<long> { static const bool result = true; };
|
||||
template <> struct IsPodType<unsigned long> { static const bool result = true; };
|
||||
template <> struct IsPodType<long long> { static const bool result = true; };
|
||||
template <> struct IsPodType<unsigned long long> { static const bool result = true; };
|
||||
template <> struct IsPodType<bool> { static const bool result = true; };
|
||||
template <> struct IsPodType<float> { static const bool result = true; };
|
||||
template <> struct IsPodType<double> { static const bool result = true; };
|
||||
template <> struct IsPodType<wchar_t> { static const bool result = true; };
|
||||
template <typename T> struct IsPodType<T *> { static const bool result = true; };
|
||||
|
||||
template <bool cond, typename T, T v1, T v2> struct If { static const T result = v1; };
|
||||
template <typename T, T v1, T v2> struct If<false, T, v1, v2> { static const T result = v2; };
|
||||
|
||||
template <class T> struct IsPointerType { static const bool result = false; };
|
||||
template <class T> struct IsPointerType<T *> { static const bool result = true; };
|
||||
|
||||
/*
|
||||
* Traits class for identifying types that are implicitly barriered.
|
||||
*/
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define jsvector_h_
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "TemplateLib.h"
|
||||
#include "Utility.h"
|
||||
|
@ -30,7 +31,7 @@ class Vector;
|
|||
|
||||
/*
|
||||
* This template class provides a default implementation for vector operations
|
||||
* when the element type is not known to be a POD, as judged by IsPodType.
|
||||
* when the element type is not known to be a POD, as judged by IsPod.
|
||||
*/
|
||||
template <class T, size_t N, class AP, bool IsPod>
|
||||
struct VectorImpl
|
||||
|
@ -102,7 +103,7 @@ struct VectorImpl
|
|||
/*
|
||||
* This partial template specialization provides a default implementation for
|
||||
* vector operations when the element type is known to be a POD, as judged by
|
||||
* IsPodType.
|
||||
* IsPod.
|
||||
*/
|
||||
template <class T, size_t N, class AP>
|
||||
struct VectorImpl<T, N, AP, true>
|
||||
|
@ -184,7 +185,7 @@ class Vector : private AllocPolicy
|
|||
|
||||
/* utilities */
|
||||
|
||||
static const bool sElemIsPod = tl::IsPodType<T>::result;
|
||||
static const bool sElemIsPod = mozilla::IsPod<T>::result;
|
||||
typedef VectorImpl<T, N, AllocPolicy, sElemIsPod> Impl;
|
||||
friend struct VectorImpl<T, N, AllocPolicy, sElemIsPod>;
|
||||
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
#ifndef LifoAlloc_h__
|
||||
#define LifoAlloc_h__
|
||||
|
||||
#include "mozilla/ASan.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/GuardObjects.h"
|
||||
#include "mozilla/ASan.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#if defined(MOZ_VALGRIND)
|
||||
#include "valgrind/memcheck.h"
|
||||
|
@ -277,7 +278,7 @@ class LifoAlloc
|
|||
void *mem = alloc(sizeof(T) * count);
|
||||
if (!mem)
|
||||
return NULL;
|
||||
JS_STATIC_ASSERT(tl::IsPodType<T>::result);
|
||||
JS_STATIC_ASSERT(mozilla::IsPod<T>::result);
|
||||
return (T *) mem;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,9 +27,9 @@ ParseMapPool::checkInvariants()
|
|||
JS_STATIC_ASSERT(sizeof(AtomDefnMap::Entry) == sizeof(AtomDefnListMap::Entry));
|
||||
JS_STATIC_ASSERT(sizeof(AtomMapT::Entry) == sizeof(AtomDefnListMap::Entry));
|
||||
/* Ensure that the HasTable::clear goes quickly via memset. */
|
||||
JS_STATIC_ASSERT(tl::IsPodType<AtomIndexMap::WordMap::Entry>::result);
|
||||
JS_STATIC_ASSERT(tl::IsPodType<AtomDefnListMap::WordMap::Entry>::result);
|
||||
JS_STATIC_ASSERT(tl::IsPodType<AtomDefnMap::WordMap::Entry>::result);
|
||||
JS_STATIC_ASSERT(mozilla::IsPod<AtomIndexMap::WordMap::Entry>::result);
|
||||
JS_STATIC_ASSERT(mozilla::IsPod<AtomDefnListMap::WordMap::Entry>::result);
|
||||
JS_STATIC_ASSERT(mozilla::IsPod<AtomDefnMap::WordMap::Entry>::result);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#define ParseMaps_h__
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "ds/InlineMap.h"
|
||||
#include "js/HashTable.h"
|
||||
|
@ -415,14 +416,16 @@ typedef AtomDefnListMap::Range AtomDefnListRange;
|
|||
|
||||
} /* namespace frontend */
|
||||
|
||||
namespace tl {
|
||||
} /* namespace js */
|
||||
|
||||
template <> struct IsPodType<frontend::DefinitionList> {
|
||||
namespace mozilla {
|
||||
|
||||
template <>
|
||||
struct IsPod<js::frontend::DefinitionList>
|
||||
{
|
||||
static const bool result = true;
|
||||
};
|
||||
|
||||
} /* namespace tl */
|
||||
|
||||
} /* namepsace js */
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -207,7 +207,7 @@ class Handle : public js::HandleBase<T>
|
|||
|
||||
/* Create a handle for a NULL pointer. */
|
||||
Handle(NullPtr) {
|
||||
typedef typename js::tl::StaticAssert<js::tl::IsPointerType<T>::result>::result _;
|
||||
typedef typename js::tl::StaticAssert<mozilla::IsPointer<T>::result>::result _;
|
||||
ptr = reinterpret_cast<const T *>(&NullPtr::constNullValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#ifndef jsanalyze_h___
|
||||
#define jsanalyze_h___
|
||||
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jsautooplen.h"
|
||||
#include "jscompartment.h"
|
||||
#include "jscntxt.h"
|
||||
|
@ -1289,16 +1291,14 @@ void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc);
|
|||
} /* namespace analyze */
|
||||
} /* namespace js */
|
||||
|
||||
namespace js {
|
||||
namespace tl {
|
||||
namespace mozilla {
|
||||
|
||||
template <> struct IsPodType<js::analyze::LifetimeVariable> { static const bool result = true; };
|
||||
template <> struct IsPodType<js::analyze::LoopAnalysis> { static const bool result = true; };
|
||||
template <> struct IsPodType<js::analyze::SlotValue> { static const bool result = true; };
|
||||
template <> struct IsPodType<js::analyze::SSAValue> { static const bool result = true; };
|
||||
template <> struct IsPodType<js::analyze::SSAUseChain> { static const bool result = true; };
|
||||
template <> struct IsPod<js::analyze::LifetimeVariable> { static const bool result = true; };
|
||||
template <> struct IsPod<js::analyze::LoopAnalysis> { static const bool result = true; };
|
||||
template <> struct IsPod<js::analyze::SlotValue> { static const bool result = true; };
|
||||
template <> struct IsPod<js::analyze::SSAValue> { static const bool result = true; };
|
||||
template <> struct IsPod<js::analyze::SSAUseChain> { static const bool result = true; };
|
||||
|
||||
} /* namespace tl */
|
||||
} /* namespace js */
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif // jsanalyze_h___
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include <limits>
|
||||
#include "mozilla/StandardInteger.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# undef min
|
||||
|
@ -159,7 +160,7 @@ template <typename Target, typename Source> struct BoundsChecker<Target, Source,
|
|||
}
|
||||
};
|
||||
|
||||
template <typename Target, typename Source, bool SameType = js::tl::IsSameType<Target, Source>::result> struct BoundsCheckElider;
|
||||
template <typename Target, typename Source, bool SameType = mozilla::IsSame<Target, Source>::result> struct BoundsCheckElider;
|
||||
template <typename Target, typename Source> struct BoundsCheckElider<Target, Source, true> {
|
||||
static bool inBounds(Source) { return true; }
|
||||
};
|
||||
|
|
|
@ -7,6 +7,14 @@
|
|||
#ifndef mozilla_TypeTraits_h_
|
||||
#define mozilla_TypeTraits_h_
|
||||
|
||||
/*
|
||||
* These traits are approximate copies of the traits and semantics from C++11's
|
||||
* <type_traits> header. Don't add traits not in that header! When all
|
||||
* platforms provide that header, we can convert all users and remove this one.
|
||||
*/
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace detail {
|
||||
|
@ -171,6 +179,75 @@ struct EnableIf<true, T>
|
|||
typedef T Type;
|
||||
};
|
||||
|
||||
/**
|
||||
* IsSame tests whether two types are the same type.
|
||||
*
|
||||
* mozilla::IsSame<int, int>::value is true;
|
||||
* mozilla::IsSame<int*, int*>::value is true;
|
||||
* mozilla::IsSame<int, unsigned int>::value is false;
|
||||
* mozilla::IsSame<void, void>::value is true;
|
||||
* mozilla::IsSame<const int, int>::value is false;
|
||||
* mozilla::IsSame<struct S, struct S>::value is true.
|
||||
*/
|
||||
template<typename T, typename U>
|
||||
struct IsSame
|
||||
{
|
||||
static const bool result = false;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct IsSame<T,T>
|
||||
{
|
||||
static const bool result = true;
|
||||
};
|
||||
|
||||
/*
|
||||
* Traits class for identifying POD types. Until C++0x, there is no automatic
|
||||
* way to detect PODs, so for the moment it is done manually.
|
||||
*/
|
||||
template<typename T>
|
||||
struct IsPod
|
||||
{
|
||||
static const bool result = false;
|
||||
};
|
||||
template<> struct IsPod<char> { static const bool result = true; };
|
||||
template<> struct IsPod<signed char> { static const bool result = true; };
|
||||
template<> struct IsPod<unsigned char> { static const bool result = true; };
|
||||
template<> struct IsPod<short> { static const bool result = true; };
|
||||
template<> struct IsPod<unsigned short> { static const bool result = true; };
|
||||
template<> struct IsPod<int> { static const bool result = true; };
|
||||
template<> struct IsPod<unsigned int> { static const bool result = true; };
|
||||
template<> struct IsPod<long> { static const bool result = true; };
|
||||
template<> struct IsPod<unsigned long> { static const bool result = true; };
|
||||
template<> struct IsPod<long long> { static const bool result = true; };
|
||||
template<> struct IsPod<unsigned long long> { static const bool result = true; };
|
||||
template<> struct IsPod<bool> { static const bool result = true; };
|
||||
template<> struct IsPod<float> { static const bool result = true; };
|
||||
template<> struct IsPod<double> { static const bool result = true; };
|
||||
template<> struct IsPod<wchar_t> { static const bool result = true; };
|
||||
template<typename T> struct IsPod<T*> { static const bool result = true; };
|
||||
|
||||
/**
|
||||
* IsPointer determines whether a type is a pointer type (but not a pointer-to-
|
||||
* member type).
|
||||
*
|
||||
* mozilla::IsPointer<struct S*>::value is true;
|
||||
* mozilla::IsPointer<int**>::value is true;
|
||||
* mozilla::IsPointer<void (*)(void)>::value is true;
|
||||
* mozilla::IsPointer<int>::value is false;
|
||||
* mozilla::IsPointer<struct S>::value is false.
|
||||
*/
|
||||
template<typename T>
|
||||
struct IsPointer
|
||||
{
|
||||
static const bool result = false;
|
||||
};
|
||||
template<typename T>
|
||||
struct IsPointer<T*>
|
||||
{
|
||||
static const bool result = true;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* mozilla_TypeTraits_h_ */
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include <string.h>
|
||||
|
@ -449,6 +450,26 @@ public:
|
|||
template <class E> class InfallibleTArray;
|
||||
template <class E> class FallibleTArray;
|
||||
|
||||
template<bool IsPod, bool IsSameType>
|
||||
struct AssignRangeAlgorithm {
|
||||
template<class Item, class ElemType, class IndexType, class SizeType>
|
||||
static void implementation(ElemType* elements, IndexType start,
|
||||
SizeType count, const Item *values) {
|
||||
ElemType *iter = elements + start, *end = iter + count;
|
||||
for (; iter != end; ++iter, ++values)
|
||||
nsTArrayElementTraits<ElemType>::Construct(iter, *values);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct AssignRangeAlgorithm<true, true> {
|
||||
template<class Item, class ElemType, class IndexType, class SizeType>
|
||||
static void implementation(ElemType* elements, IndexType start,
|
||||
SizeType count, const Item *values) {
|
||||
memcpy(elements + start, values, count * sizeof(ElemType));
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// nsTArray_Impl contains most of the guts supporting nsTArray, FallibleTArray,
|
||||
// nsAutoTArray, and AutoFallibleTArray.
|
||||
|
@ -1305,10 +1326,9 @@ protected:
|
|||
template<class Item>
|
||||
void AssignRange(index_type start, size_type count,
|
||||
const Item *values) {
|
||||
elem_type *iter = Elements() + start, *end = iter + count;
|
||||
for (; iter != end; ++iter, ++values) {
|
||||
elem_traits::Construct(iter, *values);
|
||||
}
|
||||
AssignRangeAlgorithm<mozilla::IsPod<Item>::result,
|
||||
mozilla::IsSame<Item, elem_type>::result>
|
||||
::implementation(Elements(), start, count, values);
|
||||
}
|
||||
|
||||
// This method sifts an item down to its proper place in a binary heap
|
||||
|
|
Загрузка…
Ссылка в новой задаче