From a33bd1672fab3ac2ca72f2921716bf860d500aa3 Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 22 Jun 2009 01:17:46 -0700 Subject: [PATCH] improve Vector<> with types that can be trivially moved and remove some unused code. This optimization applies to sp<> and wp<> which should now perform about the same as regular pointers when placed in to Vector<>. --- include/utils/SortedVector.h | 3 +- include/utils/TypeHelpers.h | 135 +++++++++++++++++++---------------- include/utils/Vector.h | 3 +- include/utils/VectorImpl.h | 1 - 4 files changed, 74 insertions(+), 68 deletions(-) diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h index c8a61531f..8beec5732 100644 --- a/include/utils/SortedVector.h +++ b/include/utils/SortedVector.h @@ -141,8 +141,7 @@ SortedVector::SortedVector() : SortedVectorImpl(sizeof(TYPE), ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) |(traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) - |(traits::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) + |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) ) { } diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h index c04c37fa9..2ff2749ba 100644 --- a/include/utils/TypeHelpers.h +++ b/include/utils/TypeHelpers.h @@ -29,35 +29,39 @@ namespace android { /* * Types traits */ - -template struct trait_trivial_ctor { enum { value = false }; }; -template struct trait_trivial_dtor { enum { value = false }; }; -template struct trait_trivial_copy { enum { value = false }; }; -template struct trait_trivial_assign{ enum { value = false }; }; -template struct trait_pointer { enum { value = false }; }; -template struct trait_pointer { enum { value = true }; }; +template struct trait_trivial_ctor { enum { value = false }; }; +template struct trait_trivial_dtor { enum { value = false }; }; +template struct trait_trivial_copy { enum { value = false }; }; +template struct trait_trivial_move { enum { value = false }; }; +template struct trait_pointer { enum { value = false }; }; +template struct trait_pointer { enum { value = true }; }; -#define ANDROID_BASIC_TYPES_TRAITS( T ) \ - template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ - template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ - template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ - template<> struct trait_trivial_assign< T >{ enum { value = true }; }; +// sp<> can be trivially moved +template class sp; +template struct trait_trivial_move< sp >{ + enum { value = true }; +}; -#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \ - template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \ - template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \ - template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \ - template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; +// wp<> can be trivially moved +template class wp; +template struct trait_trivial_move< wp >{ + enum { value = true }; +}; template struct traits { enum { + // whether this type is a pointer is_pointer = trait_pointer::value, + // whether this type's constructor is a no-op has_trivial_ctor = is_pointer || trait_trivial_ctor::value, + // whether this type's destructor is a no-op has_trivial_dtor = is_pointer || trait_trivial_dtor::value, + // whether this type type can be copy-constructed with memcpy has_trivial_copy = is_pointer || trait_trivial_copy::value, - has_trivial_assign = is_pointer || trait_trivial_assign::value + // whether this type can be moved with memmove + has_trivial_move = is_pointer || trait_trivial_move::value }; }; @@ -65,37 +69,47 @@ template struct aggregate_traits { enum { is_pointer = false, - has_trivial_ctor = traits::has_trivial_ctor && traits::has_trivial_ctor, - has_trivial_dtor = traits::has_trivial_dtor && traits::has_trivial_dtor, - has_trivial_copy = traits::has_trivial_copy && traits::has_trivial_copy, - has_trivial_assign = traits::has_trivial_assign && traits::has_trivial_assign + has_trivial_ctor = + traits::has_trivial_ctor && traits::has_trivial_ctor, + has_trivial_dtor = + traits::has_trivial_dtor && traits::has_trivial_dtor, + has_trivial_copy = + traits::has_trivial_copy && traits::has_trivial_copy, + has_trivial_move = + traits::has_trivial_move && traits::has_trivial_move }; }; +#define ANDROID_BASIC_TYPES_TRAITS( T ) \ + template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ + template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ + template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ + template<> struct trait_trivial_move< T > { enum { value = true }; }; + // --------------------------------------------------------------------------- /* * basic types traits */ - -ANDROID_BASIC_TYPES_TRAITS( void ); -ANDROID_BASIC_TYPES_TRAITS( bool ); -ANDROID_BASIC_TYPES_TRAITS( char ); -ANDROID_BASIC_TYPES_TRAITS( unsigned char ); -ANDROID_BASIC_TYPES_TRAITS( short ); -ANDROID_BASIC_TYPES_TRAITS( unsigned short ); -ANDROID_BASIC_TYPES_TRAITS( int ); -ANDROID_BASIC_TYPES_TRAITS( unsigned int ); -ANDROID_BASIC_TYPES_TRAITS( long ); -ANDROID_BASIC_TYPES_TRAITS( unsigned long ); -ANDROID_BASIC_TYPES_TRAITS( long long ); -ANDROID_BASIC_TYPES_TRAITS( unsigned long long ); -ANDROID_BASIC_TYPES_TRAITS( float ); -ANDROID_BASIC_TYPES_TRAITS( double ); + +ANDROID_BASIC_TYPES_TRAITS( void ) +ANDROID_BASIC_TYPES_TRAITS( bool ) +ANDROID_BASIC_TYPES_TRAITS( char ) +ANDROID_BASIC_TYPES_TRAITS( unsigned char ) +ANDROID_BASIC_TYPES_TRAITS( short ) +ANDROID_BASIC_TYPES_TRAITS( unsigned short ) +ANDROID_BASIC_TYPES_TRAITS( int ) +ANDROID_BASIC_TYPES_TRAITS( unsigned int ) +ANDROID_BASIC_TYPES_TRAITS( long ) +ANDROID_BASIC_TYPES_TRAITS( unsigned long ) +ANDROID_BASIC_TYPES_TRAITS( long long ) +ANDROID_BASIC_TYPES_TRAITS( unsigned long long ) +ANDROID_BASIC_TYPES_TRAITS( float ) +ANDROID_BASIC_TYPES_TRAITS( double ) // --------------------------------------------------------------------------- - + /* * compare and order types */ @@ -111,9 +125,9 @@ int compare_type(const TYPE& lhs, const TYPE& rhs) { } /* - * create, destroy, copy and assign types... + * create, destroy, copy and move types... */ - + template inline void construct_type(TYPE* p, size_t n) { if (!traits::has_trivial_ctor) { @@ -145,17 +159,6 @@ void copy_type(TYPE* d, const TYPE* s, size_t n) { } } -template inline -void assign_type(TYPE* d, const TYPE* s, size_t n) { - if (!traits::has_trivial_assign) { - while (n--) { - *d++ = *s++; - } - } else { - memcpy(d,s,n*sizeof(TYPE)); - } -} - template inline void splat_type(TYPE* where, const TYPE* what, size_t n) { if (!traits::has_trivial_copy) { @@ -164,15 +167,19 @@ void splat_type(TYPE* where, const TYPE* what, size_t n) { where++; } } else { - while (n--) { - *where++ = *what; + while (n--) { + *where++ = *what; } } } template inline void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if (!traits::has_trivial_copy || !traits::has_trivial_dtor) { + if ((traits::has_trivial_dtor && traits::has_trivial_copy) + || traits::has_trivial_move) + { + memmove(d,s,n*sizeof(TYPE)); + } else { d += n; s += n; while (n--) { @@ -180,35 +187,37 @@ void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { if (!traits::has_trivial_copy) { new(d) TYPE(*s); } else { - *d = *s; + *d = *s; } if (!traits::has_trivial_dtor) { s->~TYPE(); } } - } else { - memmove(d,s,n*sizeof(TYPE)); } } template inline void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if (!traits::has_trivial_copy || !traits::has_trivial_dtor) { + if ((traits::has_trivial_dtor && traits::has_trivial_copy) + || traits::has_trivial_move) + { + memmove(d,s,n*sizeof(TYPE)); + } else { while (n--) { if (!traits::has_trivial_copy) { new(d) TYPE(*s); } else { - *d = *s; + *d = *s; } if (!traits::has_trivial_dtor) { s->~TYPE(); } d++, s++; } - } else { - memmove(d,s,n*sizeof(TYPE)); } } + + // --------------------------------------------------------------------------- /* @@ -242,8 +251,8 @@ struct trait_trivial_copy< key_value_pair_t > { enum { value = aggregate_traits::has_trivial_copy }; }; template<> template -struct trait_trivial_assign< key_value_pair_t > -{ enum { value = aggregate_traits::has_trivial_assign};}; +struct trait_trivial_move< key_value_pair_t > +{ enum { value = aggregate_traits::has_trivial_move }; }; // --------------------------------------------------------------------------- diff --git a/include/utils/Vector.h b/include/utils/Vector.h index be365d83e..ad59fd63e 100644 --- a/include/utils/Vector.h +++ b/include/utils/Vector.h @@ -175,8 +175,7 @@ Vector::Vector() : VectorImpl(sizeof(TYPE), ((traits::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) |(traits::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) - |(traits::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) + |(traits::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)) ) { } diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h index 2525229be..49b03f10b 100644 --- a/include/utils/VectorImpl.h +++ b/include/utils/VectorImpl.h @@ -44,7 +44,6 @@ public: HAS_TRIVIAL_CTOR = 0x00000001, HAS_TRIVIAL_DTOR = 0x00000002, HAS_TRIVIAL_COPY = 0x00000004, - HAS_TRIVIAL_ASSIGN = 0x00000008 }; VectorImpl(size_t itemSize, uint32_t flags);