Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5f28411a authored by Mathias Agopian's avatar Mathias Agopian
Browse files

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<>.
parent 8e56914a
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -141,8 +141,7 @@ SortedVector<TYPE>::SortedVector()
    : SortedVectorImpl(sizeof(TYPE),
                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))
                )
{
}
+75 −66
Original line number Diff line number Diff line
@@ -33,31 +33,35 @@ namespace android {
template <typename T> struct trait_trivial_ctor { enum { value = false }; };
template <typename T> struct trait_trivial_dtor { enum { value = false }; };
template <typename T> struct trait_trivial_copy { enum { value = false }; };
template <typename T> struct trait_trivial_assign{ enum { value = false }; };

template <typename T> struct trait_trivial_move { enum { value = false }; };
template <typename T> struct trait_pointer      { enum { value = false }; };    
template <typename T> struct trait_pointer<T*>  { 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 <typename T> class sp;
template <typename T> struct trait_trivial_move< sp<T> >{
    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 <typename T> class wp;
template <typename T> struct trait_trivial_move< wp<T> >{ 
    enum { value = true }; 
};

template <typename TYPE>
struct traits {
    enum {
        // whether this type is a pointer
        is_pointer          = trait_pointer<TYPE>::value,
        // whether this type's constructor is a no-op
        has_trivial_ctor    = is_pointer || trait_trivial_ctor<TYPE>::value,
        // whether this type's destructor is a no-op
        has_trivial_dtor    = is_pointer || trait_trivial_dtor<TYPE>::value,
        // whether this type type can be copy-constructed with memcpy
        has_trivial_copy    = is_pointer || trait_trivial_copy<TYPE>::value,
        has_trivial_assign  = is_pointer || trait_trivial_assign<TYPE>::value   
        // whether this type can be moved with memmove
        has_trivial_move    = is_pointer || trait_trivial_move<TYPE>::value
    };
};

@@ -65,33 +69,43 @@ template <typename T, typename U>
struct aggregate_traits {
    enum {
        is_pointer          = false,
        has_trivial_ctor    = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
        has_trivial_dtor    = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
        has_trivial_copy    = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
        has_trivial_assign  = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign
        has_trivial_ctor    = 
            traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
        has_trivial_dtor    = 
            traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
        has_trivial_copy    = 
            traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
        has_trivial_move    = 
            traits<T>::has_trivial_move && traits<U>::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 )

// ---------------------------------------------------------------------------

@@ -111,7 +125,7 @@ int compare_type(const TYPE& lhs, const TYPE& rhs) {
}

/*
 * create, destroy, copy and assign types...
 * create, destroy, copy and move types...
 */

template<typename TYPE> inline
@@ -145,17 +159,6 @@ void copy_type(TYPE* d, const TYPE* s, size_t n) {
    }
}

template<typename TYPE> inline
void assign_type(TYPE* d, const TYPE* s, size_t n) {
    if (!traits<TYPE>::has_trivial_assign) {
        while (n--) {
            *d++ = *s++;
        }
    } else {
        memcpy(d,s,n*sizeof(TYPE));
    }
}

template<typename TYPE> inline
void splat_type(TYPE* where, const TYPE* what, size_t n) {
    if (!traits<TYPE>::has_trivial_copy) {
@@ -172,7 +175,11 @@ void splat_type(TYPE* where, const TYPE* what, size_t n) {

template<typename TYPE> inline
void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
            || traits<TYPE>::has_trivial_move) 
    {
        memmove(d,s,n*sizeof(TYPE));
    } else {
        d += n;
        s += n;
        while (n--) {
@@ -186,14 +193,16 @@ void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
                s->~TYPE();
            }
        }
    } else {
        memmove(d,s,n*sizeof(TYPE));
    }
}

template<typename TYPE> inline
void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
    if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
    if ((traits<TYPE>::has_trivial_dtor && traits<TYPE>::has_trivial_copy) 
            || traits<TYPE>::has_trivial_move) 
    {
        memmove(d,s,n*sizeof(TYPE));
    } else {
        while (n--) {
            if (!traits<TYPE>::has_trivial_copy) {
                new(d) TYPE(*s);
@@ -205,10 +214,10 @@ void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
            }
            d++, s++;
        }
    } else {
        memmove(d,s,n*sizeof(TYPE));
    }
}


// ---------------------------------------------------------------------------

/*
@@ -242,8 +251,8 @@ struct trait_trivial_copy< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
template<> 
template <typename K, typename V>
struct trait_trivial_assign< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_assign};};
struct trait_trivial_move< key_value_pair_t<K, V> >
{ enum { value = aggregate_traits<K,V>::has_trivial_move }; };

// ---------------------------------------------------------------------------

+1 −2
Original line number Diff line number Diff line
@@ -175,8 +175,7 @@ Vector<TYPE>::Vector()
    : VectorImpl(sizeof(TYPE),
                ((traits<TYPE>::has_trivial_ctor   ? HAS_TRIVIAL_CTOR   : 0)
                |(traits<TYPE>::has_trivial_dtor   ? HAS_TRIVIAL_DTOR   : 0)
                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0)
                |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
                |(traits<TYPE>::has_trivial_copy   ? HAS_TRIVIAL_COPY   : 0))
                )
{
}
+0 −1
Original line number Diff line number Diff line
@@ -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);