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:
Razvan Cojocaru 2013-02-08 13:18:49 -08:00
Родитель 7e794af42a
Коммит c8372e3fae
11 изменённых файлов: 144 добавлений и 68 удалений

Просмотреть файл

@ -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