From e68d5e248f73180def7c8928b32482347dd91de4 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 14 Dec 2011 16:18:19 -0500 Subject: SH-2789 WIP - add asserts to check object address alignment where needed --- indra/llcommon/llmemory.h | 9 +++++++++ indra/llmath/llmatrix3a.cpp | 0 indra/llmath/llsimdmath.h | 3 +-- indra/llmath/llsimdtypes.inl | 2 ++ indra/llmath/llvector4a.cpp | 3 +++ indra/llmath/llvector4a.h | 2 ++ indra/llmath/llvector4a.inl | 1 + indra/llmath/llvector4logical.h | 2 ++ indra/llmath/llvolume.cpp | 23 ++++++----------------- indra/newview/llspatialpartition.cpp | 3 +++ 10 files changed, 29 insertions(+), 19 deletions(-) mode change 100644 => 100755 indra/llcommon/llmemory.h mode change 100644 => 100755 indra/llmath/llmatrix3a.cpp mode change 100644 => 100755 indra/llmath/llsimdmath.h mode change 100644 => 100755 indra/llmath/llvolume.cpp mode change 100644 => 100755 indra/newview/llspatialpartition.cpp diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h old mode 100644 new mode 100755 index bbbdaa6497..baf91bb96d --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -512,4 +512,13 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) // LLSingleton moved to llsingleton.h +#define CHECK_ALIGNMENT + +#ifdef CHECK_ALIGNMENT +#define ll_assert_aligned(ptr,alignment) llassert((reinterpret_cast(ptr))%(alignment) == 0) +#else +#define ll_assert_aligned(ptr,alignment) +#endif + + #endif diff --git a/indra/llmath/llmatrix3a.cpp b/indra/llmath/llmatrix3a.cpp old mode 100644 new mode 100755 diff --git a/indra/llmath/llsimdmath.h b/indra/llmath/llsimdmath.h old mode 100644 new mode 100755 index c7cdf7b32c..01458521ec --- a/indra/llmath/llsimdmath.h +++ b/indra/llmath/llsimdmath.h @@ -67,11 +67,10 @@ template T* LL_NEXT_ALIGNED_ADDRESS_64(T* address) #define LL_ALIGN_16(var) LL_ALIGN_PREFIX(16) var LL_ALIGN_POSTFIX(16) - - #include #include +#include "llmemory.h" #include "llsimdtypes.h" #include "llsimdtypes.inl" diff --git a/indra/llmath/llsimdtypes.inl b/indra/llmath/llsimdtypes.inl index 712239e425..e905c84954 100644 --- a/indra/llmath/llsimdtypes.inl +++ b/indra/llmath/llsimdtypes.inl @@ -62,6 +62,7 @@ inline LLSimdScalar operator/(const LLSimdScalar& a, const LLSimdScalar& b) inline LLSimdScalar operator-(const LLSimdScalar& a) { static LL_ALIGN_16(const U32 signMask[4]) = {0x80000000, 0x80000000, 0x80000000, 0x80000000 }; + ll_assert_aligned(signMask,16); return _mm_xor_ps(*reinterpret_cast(signMask), a); } @@ -146,6 +147,7 @@ inline LLSimdScalar& LLSimdScalar::operator/=(const LLSimdScalar& rhs) inline LLSimdScalar LLSimdScalar::getAbs() const { static const LL_ALIGN_16(U32 F_ABS_MASK_4A[4]) = { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; + ll_assert_aligned(F_ABS_MASK_4A,16); return _mm_and_ps( mQ, *reinterpret_cast(F_ABS_MASK_4A)); } diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index b66b7a7076..49b8754cd0 100644 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -24,6 +24,7 @@ * $/LicenseInfo$ */ +#include "llmemory.h" #include "llmath.h" #include "llquantize.h" @@ -189,6 +190,8 @@ void LLVector4a::quantize16( const LLVector4a& low, const LLVector4a& high ) LLVector4a oneOverDelta; { static LL_ALIGN_16( const F32 F_TWO_4A[4] ) = { 2.f, 2.f, 2.f, 2.f }; + ll_assert_aligned(F_TWO_4A,16); + LLVector4a two; two.load4a( F_TWO_4A ); // Here we use _mm_rcp_ps plus one round of newton-raphson diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 596082509d..eada6ed1b7 100644 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -32,6 +32,7 @@ class LLRotation; #include #include "llpreprocessor.h" +#include "llmemory.h" /////////////////////////////////// // FIRST TIME USERS PLEASE READ @@ -90,6 +91,7 @@ public: LLVector4a() { //DO NOT INITIALIZE -- The overhead is completely unnecessary + ll_assert_aligned(this,16); } LLVector4a(F32 x, F32 y, F32 z, F32 w = 0.f) diff --git a/indra/llmath/llvector4a.inl b/indra/llmath/llvector4a.inl index 7ad22a5631..7c52ffef21 100644 --- a/indra/llmath/llvector4a.inl +++ b/indra/llmath/llvector4a.inl @@ -475,6 +475,7 @@ inline void LLVector4a::setLerp(const LLVector4a& lhs, const LLVector4a& rhs, F3 inline LLBool32 LLVector4a::isFinite3() const { static LL_ALIGN_16(const U32 nanOrInfMask[4]) = { 0x7f800000, 0x7f800000, 0x7f800000, 0x7f800000 }; + ll_assert_aligned(nanOrInfMask,16); const __m128i nanOrInfMaskV = *reinterpret_cast (nanOrInfMask); const __m128i maskResult = _mm_and_si128( _mm_castps_si128(mQ), nanOrInfMaskV ); const LLVector4Logical equalityCheck = _mm_castsi128_ps(_mm_cmpeq_epi32( maskResult, nanOrInfMaskV )); diff --git a/indra/llmath/llvector4logical.h b/indra/llmath/llvector4logical.h index dd66b09d43..c5698f7cea 100644 --- a/indra/llmath/llvector4logical.h +++ b/indra/llmath/llvector4logical.h @@ -27,6 +27,7 @@ #ifndef LL_VECTOR4LOGICAL_H #define LL_VECTOR4LOGICAL_H +#include "llmemory.h" //////////////////////////// // LLVector4Logical @@ -77,6 +78,7 @@ public: inline LLVector4Logical& invert() { static const LL_ALIGN_16(U32 allOnes[4]) = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; + ll_assert_aligned(allOnes,16); mQ = _mm_andnot_ps( mQ, *(LLQuad*)(allOnes) ); return *this; } diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp old mode 100644 new mode 100755 index da0fa32963..113d4835bb --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -95,17 +95,6 @@ const S32 SCULPT_MIN_AREA_DETAIL = 1; extern BOOL gDebugGL; -void assert_aligned(void* ptr, uintptr_t alignment) -{ -#if 0 - uintptr_t t = (uintptr_t) ptr; - if (t%alignment != 0) - { - llerrs << "Alignment check failed." << llendl; - } -#endif -} - BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm) { LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -6894,14 +6883,14 @@ void LLVolumeFace::resizeVertices(S32 num_verts) if (num_verts) { mPositions = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - assert_aligned(mPositions, 16); + ll_assert_aligned(mPositions, 16); mNormals = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); - assert_aligned(mNormals, 16); + ll_assert_aligned(mNormals, 16); //pad texture coordinate block end to allow for QWORD reads S32 size = ((num_verts*sizeof(LLVector2)) + 0xF) & ~0xF; mTexCoords = (LLVector2*) ll_aligned_malloc_16(size); - assert_aligned(mTexCoords, 16); + ll_assert_aligned(mTexCoords, 16); } else { @@ -7027,11 +7016,11 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat //allocate new buffer space mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a)); - assert_aligned(mPositions, 16); + ll_assert_aligned(mPositions, 16); mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a)); - assert_aligned(mNormals, 16); + ll_assert_aligned(mNormals, 16); mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF); - assert_aligned(mTexCoords, 16); + ll_assert_aligned(mTexCoords, 16); mNumVertices = new_count; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp old mode 100644 new mode 100755 index 3e16ccf3da..a8b5ee47d1 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -546,6 +546,7 @@ void LLSpatialGroup::setVisible() void LLSpatialGroup::validate() { + ll_assert_aligned(this,64); #if LL_OCTREE_PARANOIA_CHECK sg_assert(!isState(DIRTY)); @@ -1195,6 +1196,8 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mCurUpdatingSlotp(NULL), mCurUpdatingTexture (NULL) { + ll_assert_aligned(this,64); + sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); -- cgit v1.2.3 From e4a1b12e7a9c4bb8cbc2a1e41fddb8cec5a1b1e0 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 15 Dec 2011 12:48:07 -0500 Subject: SH-2789 WIP - build without tcmalloc, force alignment in various places --- indra/cmake/FindGooglePerfTools.cmake | 2 ++ indra/cmake/GooglePerfTools.cmake | 2 +- indra/llmath/llcamera.h | 12 ++++++------ indra/llmath/llmatrix3a.h | 2 +- indra/llmath/llmatrix4a.h | 2 +- indra/llmath/llplane.h | 4 +++- indra/llmath/llvector4a.h | 3 ++- indra/newview/CMakeLists.txt | 5 +++-- indra/newview/lldrawable.h | 7 ++++--- indra/newview/llspatialpartition.h | 12 ++++++------ indra/newview/llviewercamera.h | 4 +++- indra/newview/llvoavatar.cpp | 2 +- indra/newview/llvoavatar.h | 2 +- 13 files changed, 34 insertions(+), 25 deletions(-) mode change 100644 => 100755 indra/cmake/FindGooglePerfTools.cmake mode change 100644 => 100755 indra/cmake/GooglePerfTools.cmake mode change 100644 => 100755 indra/llmath/llcamera.h mode change 100644 => 100755 indra/llmath/llmatrix4a.h mode change 100644 => 100755 indra/llmath/llplane.h mode change 100644 => 100755 indra/llmath/llvector4a.h mode change 100644 => 100755 indra/newview/CMakeLists.txt mode change 100644 => 100755 indra/newview/lldrawable.h mode change 100644 => 100755 indra/newview/llspatialpartition.h mode change 100644 => 100755 indra/newview/llviewercamera.h mode change 100644 => 100755 indra/newview/llvoavatar.cpp mode change 100644 => 100755 indra/newview/llvoavatar.h diff --git a/indra/cmake/FindGooglePerfTools.cmake b/indra/cmake/FindGooglePerfTools.cmake old mode 100644 new mode 100755 index bb125d538e..1c785d3461 --- a/indra/cmake/FindGooglePerfTools.cmake +++ b/indra/cmake/FindGooglePerfTools.cmake @@ -64,3 +64,5 @@ MARK_AS_ADVANCED( PROFILER_LIBRARY GOOGLE_PERFTOOLS_INCLUDE_DIR ) + +SET(GOOGLE_PERFTOOLS_FOUND "NO") diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake old mode 100644 new mode 100755 index d9f91193be..2e96912769 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -29,7 +29,7 @@ if (GOOGLE_PERFTOOLS_FOUND) endif (GOOGLE_PERFTOOLS_FOUND) if (WINDOWS) - set(USE_GOOGLE_PERFTOOLS ON) + set(USE_GOOGLE_PERFTOOLS OFF) endif (WINDOWS) if (USE_GOOGLE_PERFTOOLS) diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h old mode 100644 new mode 100755 index ec67b91d05..0b591be622 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -60,7 +60,7 @@ static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD; // roll(), pitch(), yaw() // etc... - +LL_ALIGN_PREFIX(16) class LLCamera : public LLCoordFrame { @@ -108,7 +108,7 @@ public: }; private: - LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP + LL_ALIGN_16(LLPlane mAgentPlanes[7]); //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP U8 mPlaneMask[8]; // 8 for alignment F32 mView; // angle between top and bottom frustum planes in radians. @@ -116,13 +116,13 @@ private: S32 mViewHeightInPixels; // for ViewHeightInPixels() only F32 mNearPlane; F32 mFarPlane; - LLPlane mLocalPlanes[4]; + LL_ALIGN_16(LLPlane mLocalPlanes[4]); F32 mFixedDistance; // Always return this distance, unless < 0 LLVector3 mFrustCenter; // center of frustum and radius squared for ultra-quick exclusion test F32 mFrustRadiusSquared; - LLPlane mWorldPlanes[PLANE_NUM]; - LLPlane mHorizPlanes[HORIZ_PLANE_NUM]; + LL_ALIGN_16(LLPlane mWorldPlanes[PLANE_NUM]); + LL_ALIGN_16(LLPlane mHorizPlanes[HORIZ_PLANE_NUM]); U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in @@ -208,7 +208,7 @@ protected: void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom); void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2); void calculateWorldFrustumPlanes(); -}; +} LL_ALIGN_POSTFIX(16); #endif diff --git a/indra/llmath/llmatrix3a.h b/indra/llmath/llmatrix3a.h index adb7e3389d..9916cfd2da 100644 --- a/indra/llmath/llmatrix3a.h +++ b/indra/llmath/llmatrix3a.h @@ -111,7 +111,7 @@ public: protected: - LLVector4a mColumns[3]; + LL_ALIGN_16(LLVector4a mColumns[3]); }; diff --git a/indra/llmath/llmatrix4a.h b/indra/llmath/llmatrix4a.h old mode 100644 new mode 100755 index 27cf5b79f6..c4cefdb4fa --- a/indra/llmath/llmatrix4a.h +++ b/indra/llmath/llmatrix4a.h @@ -34,7 +34,7 @@ class LLMatrix4a { public: - LLVector4a mMatrix[4]; + LL_ALIGN_16(LLVector4a mMatrix[4]); inline void clear() { diff --git a/indra/llmath/llplane.h b/indra/llmath/llplane.h old mode 100644 new mode 100755 index a611894721..3c32441b11 --- a/indra/llmath/llplane.h +++ b/indra/llmath/llplane.h @@ -36,6 +36,8 @@ // The plane normal = [A, B, C] // The closest approach = D / sqrt(A*A + B*B + C*C) + +LL_ALIGN_PREFIX(16) class LLPlane { public: @@ -94,7 +96,7 @@ public: private: LLVector4a mV; -}; +} LL_ALIGN_POSTFIX(16); diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h old mode 100644 new mode 100755 index eada6ed1b7..9de0e66774 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -47,6 +47,7 @@ class LLRotation; // LLVector3/LLVector4. ///////////////////////////////// +LL_ALIGN_PREFIX(16) class LLVector4a { public: @@ -315,7 +316,7 @@ public: private: LLQuad mQ; -}; +} LL_ALIGN_POSTFIX(16); inline void update_min_max(LLVector4a& min, LLVector4a& max, const LLVector4a& p) { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt old mode 100644 new mode 100755 index 6b2fe1e45a..825cbbef8f --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1509,7 +1509,8 @@ if (WINDOWS) PROPERTIES # *TODO -reenable this once we get server usage sorted out #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" +# LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" LINK_FLAGS_RELEASE "" ) @@ -1764,7 +1765,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${CRYPTO_LIBRARIES} ${LLLOGIN_LIBRARIES} ${LLCONVEXDECOMP_LIBRARY} - ${TCMALLOC_LIBRARIES} +# ${TCMALLOC_LIBRARIES} ) if (USE_KDU) diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h old mode 100644 new mode 100755 index e268640a21..244b87b2e7 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -59,6 +59,7 @@ class LLViewerTexture; const U32 SILHOUETTE_HIGHLIGHT = 0; // All data for new renderer goes into this class. +LL_ALIGN_PREFIX(16) class LLDrawable : public LLRefCount { public: @@ -280,8 +281,8 @@ public: } EDrawableFlags; private: //aligned members - LLVector4a mExtents[2]; - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mExtents[2]); + LL_ALIGN_16(LLVector4a mPositionGroup); public: LLXformMatrix mXform; @@ -322,7 +323,7 @@ private: static U32 sNumZombieDrawables; static LLDynamicArrayPtr > sDeadList; -}; +} LL_ALIGN_POSTFIX(16); inline LLFace* LLDrawable::getFace(const S32 i) const diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h old mode 100644 new mode 100755 index f0c8a372ee..cbd4507f84 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -372,12 +372,12 @@ public: V4_COUNT = 10 } eV4Index; - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children - LLVector4a mObjectExtents[2]; // extents (min, max) of objects in this node - LLVector4a mObjectBounds[2]; // bounding box (center, size) of objects in this node - LLVector4a mViewAngle; - LLVector4a mLastUpdateViewAngle; + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mObjectExtents[2]); // extents (min, max) of objects in this node + LL_ALIGN_16(LLVector4a mObjectBounds[2]); // bounding box (center, size) of objects in this node + LL_ALIGN_16(LLVector4a mViewAngle); + LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); private: U32 mCurUpdatingTime ; diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h old mode 100644 new mode 100755 index cc3395115b..7257297cfd --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -51,6 +51,7 @@ const BOOL NOT_FOR_SELECTION = FALSE; extern template class LLViewerCamera* LLSingleton::getInstance(); #endif +LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton { public: @@ -137,6 +138,7 @@ protected: S16 mZoomSubregion; public: -}; +} LL_ALIGN_POSTFIX(16); + #endif // LL_LLVIEWERCAMERA_H diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp old mode 100644 new mode 100755 index 4767ba2bed..ad5ea15bbb --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2595,7 +2595,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (isImpostor() && !mNeedsImpostorUpdate) { - LLVector4a ext[2]; + LL_ALIGN_16(LLVector4a ext[2]); F32 distance; LLVector3 angle; diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h old mode 100644 new mode 100755 index 59796370ae..82157436b9 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -212,7 +212,7 @@ public: bool isBuilt() const { return mIsBuilt; } private: //aligned members - LLVector4a mImpostorExtents[2]; + LL_ALIGN_16(LLVector4a mImpostorExtents[2]); private: BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients -- cgit v1.2.3 From e62ad2bf13aa05cb19c2bd72e0d9f59117a6ec84 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 15 Dec 2011 19:26:03 -0500 Subject: SH-2789 WIP - tests for alignment --- indra/llmath/CMakeLists.txt | 1 + indra/llmath/tests/alignment_test.cpp | 127 ++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) mode change 100644 => 100755 indra/llmath/CMakeLists.txt create mode 100755 indra/llmath/tests/alignment_test.cpp diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt old mode 100644 new mode 100755 index b5e59c1ca3..5865ae030c --- a/indra/llmath/CMakeLists.txt +++ b/indra/llmath/CMakeLists.txt @@ -117,6 +117,7 @@ if (LL_TESTS) # INTEGRATION TESTS set(test_libs llmath llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES}) # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests. + LL_ADD_INTEGRATION_TEST(alignment "" "${test_libs}") LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}") LL_ADD_INTEGRATION_TEST(llquaternion llquaternion.cpp "${test_libs}") LL_ADD_INTEGRATION_TEST(mathmisc "" "${test_libs}") diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp new file mode 100755 index 0000000000..6b4a454fd2 --- /dev/null +++ b/indra/llmath/tests/alignment_test.cpp @@ -0,0 +1,127 @@ +/** + * @file v3dmath_test.cpp + * @author Vir + * @date 2011-12 + * @brief v3dmath test cases. + * + * $LicenseInfo:firstyear=2011&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2011, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// Tests related to allocating objects with alignment constraints, particularly for SSE support. + +#include "linden_common.h" +#include "../test/lltut.h" +#include "../llmath.h" +#include "../llsimdmath.h" +#include "../llvector4a.h" + +namespace tut +{ + +#define is_aligned(ptr,alignment) ((reinterpret_cast(ptr))%(alignment)==0) + +struct alignment_test {}; + +typedef test_group alignment_test_t; +typedef alignment_test_t::object alignment_test_object_t; +tut::alignment_test_t tut_alignment_test("LLAlignment"); + +LL_ALIGN_PREFIX(16) +class MyVector4a +{ + LLQuad mQ; +} LL_ALIGN_POSTFIX(16); + +LL_ALIGN_PREFIX(64) +class MyBigBlob +{ +public: + ~MyBigBlob() {} +private: + LLQuad mQ[4]; +} LL_ALIGN_POSTFIX(64); + +// In-place allocation of objects and arrays. +template<> template<> +void alignment_test_object_t::test<1>() +{ + ensure("LLAlignment reality is broken: ", (1==1)); + + MyVector4a vec1; + ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); + + MyBigBlob bb1; + ensure("LLAlignment bb1 unaligned", is_aligned(&bb1,64)); + + + MyVector4a veca[12]; + ensure("LLAlignment veca unaligned", is_aligned(veca,16)); + + MyBigBlob bba[12]; + ensure("LLAlignment bba unaligned", is_aligned(bba,64)); +} + +// Heap allocation of objects and arrays. +template<> template<> +void alignment_test_object_t::test<2>() +{ + const int ARR_SIZE = 7; + for(int i=0; i~MyBigBlob(); + _aligned_free(aligned_addr); + } + + ensure("LLAlignment big blob size",sizeof(MyBigBlob)==64); + void *aligned_addr = _aligned_malloc(ARR_SIZE*sizeof(MyBigBlob),64); + MyBigBlob *bba = new(aligned_addr) MyBigBlob[ARR_SIZE]; + std::cout << "aligned_addr " << aligned_addr << std::endl; + std::cout << "bba " << bba << std::endl; + for(int i=0; i Date: Mon, 19 Dec 2011 18:17:18 -0500 Subject: SH-2789 WIP - various fixes to force 16-byte alignment --- indra/llcommon/llmemory.cpp | 9 +++++ indra/llcommon/llmemory.h | 9 +++-- indra/llmath/lloctree.h | 4 +- indra/llmath/llvector4a.cpp | 7 +++- indra/llmath/llvolumeoctree.h | 14 ++++++- indra/llmath/tests/alignment_test.cpp | 74 +++++++++++++++-------------------- indra/newview/lldrawable.h | 10 +++++ indra/newview/lldynamictexture.h | 12 +++++- indra/newview/llface.h | 11 ++++++ indra/newview/llspatialpartition.cpp | 2 +- indra/newview/llspatialpartition.h | 24 +++++++++++- indra/newview/llviewercamera.h | 9 +++++ indra/newview/llvoavatar.h | 10 +++++ indra/newview/llvoavatarself.h | 10 +++++ 14 files changed, 151 insertions(+), 54 deletions(-) mode change 100644 => 100755 indra/llmath/llvector4a.cpp mode change 100644 => 100755 indra/llmath/llvolumeoctree.h mode change 100644 => 100755 indra/newview/lldynamictexture.h mode change 100644 => 100755 indra/newview/llface.h mode change 100644 => 100755 indra/newview/llvoavatarself.h diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 3b9758f996..22204e756a 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -61,6 +61,15 @@ BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE; LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sMemAllocationTracker; #endif +void ll_assert_aligned_func(uintptr_t ptr,U32 alignment) +{ + if (ptr%alignment!=0) + { + llwarns << "alignment check failed" << llendl; + } + llassert(ptr%alignment==0); +} + //static void LLMemory::initClass() { diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index baf91bb96d..c61d06e924 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,7 +27,7 @@ #define LLMEMORY_H #include "llmemtype.h" -#if LL_DEBUG +#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -94,7 +94,8 @@ inline void ll_aligned_free_32(void *p) free(p); // posix_memalign() is compatible with heap deallocator #endif } -#else // LL_DEBUG + +#else // USE_TCMALLOC // ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals) #define ll_aligned_malloc( size, align ) malloc(size) #define ll_aligned_free( ptr ) free(ptr) @@ -514,8 +515,10 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) #define CHECK_ALIGNMENT +LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); + #ifdef CHECK_ALIGNMENT -#define ll_assert_aligned(ptr,alignment) llassert((reinterpret_cast(ptr))%(alignment) == 0) +#define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast(ptr),((U32)alignment)) #else #define ll_assert_aligned(ptr,alignment) #endif diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 3c1ae45d68..374858be51 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -88,7 +88,7 @@ public: typedef LLOctreeNode oct_node; typedef LLOctreeListener oct_listener; - /*void* operator new(size_t size) + void* operator new(size_t size) { return ll_aligned_malloc_16(size); } @@ -96,7 +96,7 @@ public: void operator delete(void* ptr) { ll_aligned_free_16(ptr); - }*/ + } LLOctreeNode( const LLVector4a& center, const LLVector4a& size, diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp old mode 100644 new mode 100755 index 49b8754cd0..7602ef0cb2 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -41,11 +41,15 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F /*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes) { + memcpy((void*)dst,(const void*)src,bytes); +#if 0 assert(src != NULL); assert(dst != NULL); assert(bytes > 0); assert((bytes % sizeof(F32))== 0); - + ll_assert_aligned(src,16); + ll_assert_aligned(dst,16); + F32* end = dst + (bytes / sizeof(F32) ); if (bytes > 64) @@ -87,6 +91,7 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F dst += 4; src += 4; } +#endif } void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec ) diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h old mode 100644 new mode 100755 index 688d91dc40..6de7b223be --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -73,6 +73,16 @@ class LLVolumeOctreeListener : public LLOctreeListener { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); @@ -99,8 +109,8 @@ public: public: - LLVector4a mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) - LLVector4a mExtents[2]; // extents (min, max) of this node and all its children + LL_ALIGN_16(LLVector4a mBounds[2]); // bounding box (center, size) of this node and all its children (tight fit to objects) + LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; class LLOctreeTriangleRayIntersect : public LLOctreeTraveler diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index 6b4a454fd2..51a7051e69 100755 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -34,10 +34,21 @@ #include "../llsimdmath.h" #include "../llvector4a.h" +void* operator new(size_t size) +{ + return ll_aligned_malloc_16(size); +} + +void operator delete(void *p) +{ + ll_aligned_free_16(p); +} + namespace tut { #define is_aligned(ptr,alignment) ((reinterpret_cast(ptr))%(alignment)==0) +#define is_aligned_relative(ptr,base_ptr,alignment) ((reinterpret_cast(ptr)-reinterpret_cast(base_ptr))%(alignment)==0) struct alignment_test {}; @@ -51,38 +62,40 @@ class MyVector4a LLQuad mQ; } LL_ALIGN_POSTFIX(16); -LL_ALIGN_PREFIX(64) -class MyBigBlob +// Verify that aligned allocators perform as advertised. +template<> template<> +void alignment_test_object_t::test<1>() { -public: - ~MyBigBlob() {} -private: - LLQuad mQ[4]; -} LL_ALIGN_POSTFIX(64); + const int num_tests = 7; + void *align_ptr; + for (int i=0; i template<> -void alignment_test_object_t::test<1>() +void alignment_test_object_t::test<2>() { ensure("LLAlignment reality is broken: ", (1==1)); MyVector4a vec1; ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); - MyBigBlob bb1; - ensure("LLAlignment bb1 unaligned", is_aligned(&bb1,64)); - - MyVector4a veca[12]; ensure("LLAlignment veca unaligned", is_aligned(veca,16)); - - MyBigBlob bba[12]; - ensure("LLAlignment bba unaligned", is_aligned(bba,64)); } // Heap allocation of objects and arrays. template<> template<> -void alignment_test_object_t::test<2>() +void alignment_test_object_t::test<3>() { const int ARR_SIZE = 7; for(int i=0; i() } MyVector4a *veca = new MyVector4a[ARR_SIZE]; + ensure("LLAligment veca base", is_aligned(veca,16)); for(int i=0; i~MyBigBlob(); - _aligned_free(aligned_addr); - } - - ensure("LLAlignment big blob size",sizeof(MyBigBlob)==64); - void *aligned_addr = _aligned_malloc(ARR_SIZE*sizeof(MyBigBlob),64); - MyBigBlob *bba = new(aligned_addr) MyBigBlob[ARR_SIZE]; - std::cout << "aligned_addr " << aligned_addr << std::endl; - std::cout << "bba " << bba << std::endl; - for(int i=0; i instance_list_t; static instance_list_t sInstances[ LLViewerDynamicTexture::ORDER_COUNT ]; diff --git a/indra/newview/llface.h b/indra/newview/llface.h old mode 100644 new mode 100755 index 82e4ab61b7..feb6244f72 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -59,6 +59,17 @@ class LLFace { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + + LLFace(const LLFace& rhs) { *this = rhs; diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index a8b5ee47d1..4c45ac6b47 100755 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1196,7 +1196,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mCurUpdatingSlotp(NULL), mCurUpdatingTexture (NULL) { - ll_assert_aligned(this,64); + ll_assert_aligned(this,16); sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index cbd4507f84..22bea69df3 100755 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -68,6 +68,16 @@ protected: ~LLDrawInfo(); public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLDrawInfo(const LLDrawInfo& rhs) { @@ -106,7 +116,7 @@ public: F32 mPartSize; F32 mVSize; LLSpatialGroup* mGroup; - LLFace* mFace; //associated face + LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; @@ -181,7 +191,7 @@ public: }; }; -LL_ALIGN_PREFIX(64) +LL_ALIGN_PREFIX(16) class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; @@ -193,6 +203,16 @@ public: *this = rhs; } + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + const LLSpatialGroup& operator=(const LLSpatialGroup& rhs) { llerrs << "Illegal operation!" << llendl; diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h index 7257297cfd..d2624ba14e 100755 --- a/indra/newview/llviewercamera.h +++ b/indra/newview/llviewercamera.h @@ -55,6 +55,15 @@ LL_ALIGN_PREFIX(16) class LLViewerCamera : public LLCamera, public LLSingleton { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } typedef enum { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 82157436b9..20ea3686d6 100755 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -90,6 +90,16 @@ protected: **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatar(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual void markDead(); static void initClass(); // Initialize data that's only init'd once per class. diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h old mode 100644 new mode 100755 index 74ff47a3e4..23a2025e70 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -48,6 +48,16 @@ class LLVOAvatarSelf : **/ public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVOAvatarSelf(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp); virtual ~LLVOAvatarSelf(); virtual void markDead(); -- cgit v1.2.3 From 461241a6300dcf29b06b2403c824fefd1d91a8fd Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 20 Dec 2011 12:15:29 -0500 Subject: SH-2789 WIP - fixes for 16-byte alignment --- indra/llmath/llvolumeoctree.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index 6de7b223be..dac97b14b5 100755 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -37,6 +37,16 @@ class LLVolumeTriangle : public LLRefCount { public: + void* operator new(size_t size) + { + return ll_aligned_malloc_16(size); + } + + void operator delete(void* ptr) + { + ll_aligned_free_16(ptr); + } + LLVolumeTriangle() { @@ -58,7 +68,7 @@ public: } - LLVector4a mPositionGroup; + LL_ALIGN_16(LLVector4a mPositionGroup); const LLVector4a* mV[3]; U16 mIndex[3]; -- cgit v1.2.3 From c8682722ad6b889b13ce288c417cb6b82ed273ac Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 21 Dec 2011 17:02:47 -0500 Subject: SH-2789 WIP - aligned alloc and realloc --- indra/llcommon/llmemory.h | 15 +++++++++++++-- indra/llmath/llvector4a.cpp | 5 +++-- indra/llmath/llvolume.cpp | 22 +++++++++++++--------- indra/newview/llpolymesh.cpp | 24 ++++++++++++------------ 4 files changed, 41 insertions(+), 25 deletions(-) mode change 100644 => 100755 indra/newview/llpolymesh.cpp diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index c61d06e924..3eaf700bf1 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -46,7 +46,7 @@ inline void ll_aligned_free( void* ptr ) inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { #if defined(LL_WINDOWS) - return _mm_malloc(size, 16); + return _aligned_malloc(size, 16); #elif defined(LL_DARWIN) return malloc(size); // default osx malloc is 16 byte aligned. #else @@ -58,10 +58,21 @@ inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed wi #endif } +inline void* ll_aligned_realloc_16(void* ptr, size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). +{ +#if defined(LL_WINDOWS) + return _aligned_realloc(ptr, size, 16); +#elif defined(LL_DARWIN) + return realloc(ptr,size); // default osx malloc is 16 byte aligned. +#else + return realloc(ptr,size); // FIXME not guaranteed to be aligned. +#endif +} + inline void ll_aligned_free_16(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) return free(p); #else diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index 7602ef0cb2..480ccf4ed9 100755 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -41,14 +41,15 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F /*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes) { - memcpy((void*)dst,(const void*)src,bytes); -#if 0 +// memcpy((void*)dst,(const void*)src,bytes); +#if 1 assert(src != NULL); assert(dst != NULL); assert(bytes > 0); assert((bytes % sizeof(F32))== 0); ll_assert_aligned(src,16); ll_assert_aligned(dst,16); + assert(bytes%16==0); F32* end = dst + (bytes / sizeof(F32) ); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 113d4835bb..9499ca29ac 100755 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6914,14 +6914,17 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con // S32 old_size = mNumVertices*16; //positions - mPositions = (LLVector4a*) realloc(mPositions, new_size); + mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_size); + ll_assert_aligned(mPositions,16); //normals - mNormals = (LLVector4a*) realloc(mNormals, new_size); - + mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_size); + ll_assert_aligned(mNormals,16); + //tex coords new_size = ((new_verts*8)+0xF) & ~0xF; - mTexCoords = (LLVector2*) realloc(mTexCoords, new_size); + mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, new_size); + ll_assert_aligned(mTexCoords,16); //just clear binormals @@ -6974,7 +6977,8 @@ void LLVolumeFace::pushIndex(const U16& idx) S32 old_size = ((mNumIndices*2)+0xF) & ~0xF; if (new_size != old_size) { - mIndices = (U16*) realloc(mIndices, new_size); + mIndices = (U16*) ll_aligned_realloc_16(mIndices, new_size); + ll_assert_aligned(mIndices,16); } mIndices[mNumIndices++] = idx; @@ -7015,11 +7019,11 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat } //allocate new buffer space - mPositions = (LLVector4a*) realloc(mPositions, new_count*sizeof(LLVector4a)); + mPositions = (LLVector4a*) ll_aligned_realloc_16(mPositions, new_count*sizeof(LLVector4a)); ll_assert_aligned(mPositions, 16); - mNormals = (LLVector4a*) realloc(mNormals, new_count*sizeof(LLVector4a)); + mNormals = (LLVector4a*) ll_aligned_realloc_16(mNormals, new_count*sizeof(LLVector4a)); ll_assert_aligned(mNormals, 16); - mTexCoords = (LLVector2*) realloc(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF); + mTexCoords = (LLVector2*) ll_aligned_realloc_16(mTexCoords, (new_count*sizeof(LLVector2)+0xF) & ~0xF); ll_assert_aligned(mTexCoords, 16); mNumVertices = new_count; @@ -7066,7 +7070,7 @@ void LLVolumeFace::appendFace(const LLVolumeFace& face, LLMatrix4& mat_in, LLMat new_count = mNumIndices + face.mNumIndices; //allocate new index buffer - mIndices = (U16*) realloc(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF); + mIndices = (U16*) ll_aligned_realloc_16(mIndices, (new_count*sizeof(U16)+0xF) & ~0xF); //get destination address into new index buffer U16* dst_idx = mIndices+mNumIndices; diff --git a/indra/newview/llpolymesh.cpp b/indra/newview/llpolymesh.cpp old mode 100644 new mode 100755 index 450f9b2be7..0860506086 --- a/indra/newview/llpolymesh.cpp +++ b/indra/newview/llpolymesh.cpp @@ -129,22 +129,22 @@ void LLPolyMeshSharedData::freeMeshData() { mNumVertices = 0; - delete [] mBaseCoords; + ll_aligned_free_16(mBaseCoords); mBaseCoords = NULL; - delete [] mBaseNormals; + ll_aligned_free_16(mBaseNormals); mBaseNormals = NULL; - delete [] mBaseBinormals; + ll_aligned_free_16(mBaseBinormals); mBaseBinormals = NULL; - delete [] mTexCoords; + ll_aligned_free_16(mTexCoords); mTexCoords = NULL; - delete [] mDetailTexCoords; + ll_aligned_free_16(mDetailTexCoords); mDetailTexCoords = NULL; - delete [] mWeights; + ll_aligned_free_16(mWeights); mWeights = NULL; } @@ -229,12 +229,12 @@ U32 LLPolyMeshSharedData::getNumKB() BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices ) { U32 i; - mBaseCoords = new LLVector3[ numVertices ]; - mBaseNormals = new LLVector3[ numVertices ]; - mBaseBinormals = new LLVector3[ numVertices ]; - mTexCoords = new LLVector2[ numVertices ]; - mDetailTexCoords = new LLVector2[ numVertices ]; - mWeights = new F32[ numVertices ]; + mBaseCoords = (LLVector3*) ll_aligned_malloc_16(numVertices*sizeof(LLVector3)); + mBaseNormals = (LLVector3*) ll_aligned_malloc_16(numVertices*sizeof(LLVector3)); + mBaseBinormals = (LLVector3*) ll_aligned_malloc_16(numVertices*sizeof(LLVector3)); + mTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mDetailTexCoords = (LLVector2*) ll_aligned_malloc_16(numVertices*sizeof(LLVector2)); + mWeights = (F32*) ll_aligned_malloc_16(numVertices*sizeof(F32)); for (i = 0; i < numVertices; i++) { mWeights[i] = 0.f; -- cgit v1.2.3 From 1435a8b9e6203911d2ebe9e3ba217f8eb20e3140 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 4 Jan 2012 15:21:23 -0500 Subject: SH-2789 WIP - stricter calling of memcpyNonAliased16 --- indra/llcommon/llmemory.cpp | 3 +++ indra/llcommon/llmemory.h | 12 ++++++------ indra/llmath/llvector4a.cpp | 3 --- indra/llmath/llvector4a.h | 1 + indra/llmath/tests/alignment_test.cpp | 6 ++++-- indra/newview/llfloatermodelpreview.cpp | 3 ++- indra/newview/llviewerjointmesh.cpp | 6 ++++-- 7 files changed, 20 insertions(+), 14 deletions(-) mode change 100644 => 100755 indra/llcommon/llmemory.cpp mode change 100644 => 100755 indra/newview/llviewerjointmesh.cpp diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp old mode 100644 new mode 100755 index 22204e756a..afaf366668 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -63,11 +63,14 @@ LLPrivateMemoryPoolManager::mem_allocation_info_t LLPrivateMemoryPoolManager::sM void ll_assert_aligned_func(uintptr_t ptr,U32 alignment) { +#ifdef SHOW_ASSERT + // Redundant, place to set breakpoints. if (ptr%alignment!=0) { llwarns << "alignment check failed" << llendl; } llassert(ptr%alignment==0); +#endif } //static diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 3eaf700bf1..1b54b56107 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -83,7 +83,7 @@ inline void ll_aligned_free_16(void *p) inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). { #if defined(LL_WINDOWS) - return _mm_malloc(size, 32); + return _aligned_malloc(size, 32); #elif defined(LL_DARWIN) return ll_aligned_malloc( size, 32 ); #else @@ -98,7 +98,7 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi inline void ll_aligned_free_32(void *p) { #if defined(LL_WINDOWS) - _mm_free(p); + _aligned_free(p); #elif defined(LL_DARWIN) ll_aligned_free( p ); #else @@ -107,10 +107,12 @@ inline void ll_aligned_free_32(void *p) } #else // USE_TCMALLOC -// ll_aligned_foo are noops now that we use tcmalloc everywhere (tcmalloc aligns automatically at appropriate intervals) +// ll_aligned_foo are noops now that we use tcmalloc everywhere +// (tcmalloc aligns automatically at appropriate intervals) #define ll_aligned_malloc( size, align ) malloc(size) #define ll_aligned_free( ptr ) free(ptr) #define ll_aligned_malloc_16 malloc +#define ll_aligned_realloc_16 realloc #define ll_aligned_free_16 free #define ll_aligned_malloc_32 malloc #define ll_aligned_free_32 free @@ -524,11 +526,9 @@ void LLPrivateMemoryPoolTester::operator delete[](void* addr) // LLSingleton moved to llsingleton.h -#define CHECK_ALIGNMENT - LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment); -#ifdef CHECK_ALIGNMENT +#ifdef SHOW_ASSERT #define ll_assert_aligned(ptr,alignment) ll_assert_aligned_func(reinterpret_cast(ptr),((U32)alignment)) #else #define ll_assert_aligned(ptr,alignment) diff --git a/indra/llmath/llvector4a.cpp b/indra/llmath/llvector4a.cpp index 480ccf4ed9..6edeb0fefe 100755 --- a/indra/llmath/llvector4a.cpp +++ b/indra/llmath/llvector4a.cpp @@ -41,8 +41,6 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F /*static */void LLVector4a::memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes) { -// memcpy((void*)dst,(const void*)src,bytes); -#if 1 assert(src != NULL); assert(dst != NULL); assert(bytes > 0); @@ -92,7 +90,6 @@ extern const LLVector4a LL_V4A_EPSILON = reinterpret_cast ( F dst += 4; src += 4; } -#endif } void LLVector4a::setRotated( const LLRotation& rot, const LLVector4a& vec ) diff --git a/indra/llmath/llvector4a.h b/indra/llmath/llvector4a.h index 9de0e66774..0526793d3a 100755 --- a/indra/llmath/llvector4a.h +++ b/indra/llmath/llvector4a.h @@ -84,6 +84,7 @@ public: } // Copy words 16-byte blocks from src to dst. Source and destination must not overlap. + // Source and dest must be 16-byte aligned and size must be multiple of 16. static void memcpyNonAliased16(F32* __restrict dst, const F32* __restrict src, size_t bytes); //////////////////////////////////// diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index 51a7051e69..dc9b41957d 100755 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -72,6 +72,10 @@ void alignment_test_object_t::test<1>() { align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a)); ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16)); + + align_ptr = ll_aligned_realloc_16(2*sizeof(MyVector4a)); + ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16)); + ll_aligned_free_16(align_ptr); align_ptr = ll_aligned_malloc_32(sizeof(MyVector4a)); @@ -84,8 +88,6 @@ void alignment_test_object_t::test<1>() template<> template<> void alignment_test_object_t::test<2>() { - ensure("LLAlignment reality is broken: ", (1==1)); - MyVector4a vec1; ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 64bdcccd9f..8aa3b95578 100755 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -4770,7 +4770,8 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) if (vf.mTexCoords) { vb->getTexCoord0Strider(tc_strider); - LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + S32 tex_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tc_strider.get(), (F32*) vf.mTexCoords, tex_size); } if (vf.mNormals) diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp old mode 100644 new mode 100755 index 76f4e18c27..d604687678 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -731,8 +731,10 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w F32* vw = (F32*) vertex_weightsp.get(); F32* cw = (F32*) clothing_weightsp.get(); - LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), num_verts*2*sizeof(F32)); - LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), num_verts*sizeof(F32)); + S32 tc_size = (num_verts*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(tc, (F32*) mMesh->getTexCoords(), tc_size); + S32 vw_size = (num_verts*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16(vw, (F32*) mMesh->getWeights(), vw_size); LLVector4a::memcpyNonAliased16(cw, (F32*) mMesh->getClothingWeights(), num_verts*4*sizeof(F32)); } -- cgit v1.2.3 From 80c884f77d377034852643fadae119342e0b25be Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 4 Jan 2012 17:30:11 -0500 Subject: Fix for build failure --- indra/llmath/tests/alignment_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index dc9b41957d..044e05e961 100755 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -73,7 +73,7 @@ void alignment_test_object_t::test<1>() align_ptr = ll_aligned_malloc_16(sizeof(MyVector4a)); ensure("ll_aligned_malloc_16 failed", is_aligned(align_ptr,16)); - align_ptr = ll_aligned_realloc_16(2*sizeof(MyVector4a)); + align_ptr = ll_aligned_realloc_16(align_ptr,2*sizeof(MyVector4a)); ensure("ll_aligned_realloc_16 failed", is_aligned(align_ptr,16)); ll_aligned_free_16(align_ptr); -- cgit v1.2.3 From ba67b9359f13968b13b1facbb1e4c7948405b767 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 5 Jan 2012 17:37:02 -0500 Subject: SH-2789 WIP - allow building with or without tcmalloc, default to tcmalloc enabled --- indra/cmake/FindGooglePerfTools.cmake | 2 -- indra/cmake/GooglePerfTools.cmake | 38 ++++++++++++++++++++++++++--------- indra/newview/CMakeLists.txt | 13 +++++++----- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/indra/cmake/FindGooglePerfTools.cmake b/indra/cmake/FindGooglePerfTools.cmake index 1c785d3461..bb125d538e 100755 --- a/indra/cmake/FindGooglePerfTools.cmake +++ b/indra/cmake/FindGooglePerfTools.cmake @@ -64,5 +64,3 @@ MARK_AS_ADVANCED( PROFILER_LIBRARY GOOGLE_PERFTOOLS_INCLUDE_DIR ) - -SET(GOOGLE_PERFTOOLS_FOUND "NO") diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index 2e96912769..0c31d73655 100755 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -1,20 +1,32 @@ # -*- cmake -*- include(Prebuilt) +# If you want to enable or disable TCMALLOC in viewer builds, this is the place. +# set ON or OFF as desired. +set (USE_TCMALLOC ON) + if (STANDALONE) include(FindGooglePerfTools) else (STANDALONE) if (WINDOWS) - use_prebuilt_binary(tcmalloc) - set(TCMALLOC_LIBRARIES - debug libtcmalloc_minimal-debug - optimized libtcmalloc_minimal) + if (USE_TCMALLOC) + use_prebuilt_binary(tcmalloc) + set(TCMALLOC_LIBRARIES + debug libtcmalloc_minimal-debug + optimized libtcmalloc_minimal) + else (USE_TCMALLOC) + set(TCMALLOC_LIBRARIES) + endif (USE_TCMALLOC) set(GOOGLE_PERFTOOLS_FOUND "YES") endif (WINDOWS) if (LINUX) - use_prebuilt_binary(tcmalloc) - set(TCMALLOC_LIBRARIES - tcmalloc) + if (USE_TCMALLOC) + use_prebuilt_binary(tcmalloc) + set(TCMALLOC_LIBRARIES + tcmalloc) + else (USE_TCMALLOC) + set(TCMALLOC_LIBRARIES) + endif (USE_TCMALLOC) set(PROFILER_LIBRARIES profiler) set(GOOGLE_PERFTOOLS_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include) @@ -29,13 +41,19 @@ if (GOOGLE_PERFTOOLS_FOUND) endif (GOOGLE_PERFTOOLS_FOUND) if (WINDOWS) - set(USE_GOOGLE_PERFTOOLS OFF) + set(USE_GOOGLE_PERFTOOLS ON) endif (WINDOWS) -if (USE_GOOGLE_PERFTOOLS) +# Apparently buggy - LL_USE_TCMALLOC never gets set. Fix when we have time to test the +# corresponding source code. +if (USE_TCMALLOC) set(TCMALLOC_FLAG -ULL_USE_TCMALLOC=1) +else (USE_TCMALLOC) + set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) +endif (USE_TCMALLOC) + +if (USE_GOOGLE_PERFTOOLS) include_directories(${GOOGLE_PERFTOOLS_INCLUDE_DIR}) set(GOOGLE_PERFTOOLS_LIBRARIES ${TCMALLOC_LIBRARIES} ${STACKTRACE_LIBRARIES} ${PROFILER_LIBRARIES}) else (USE_GOOGLE_PERFTOOLS) - set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) endif (USE_GOOGLE_PERFTOOLS) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 825cbbef8f..00cf1ba8df 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1505,12 +1505,15 @@ set(PACKAGE ON CACHE BOOL "Add a package target that builds an installer package.") if (WINDOWS) + if (USE_TCMALLOC) + set(TCMALLOC_INCLUDE_FLAGS "/INCLUDE:__tcmalloc") + else (USE_TCMALLOC) + set(TCMALLOC_INCLUDE_FLAGS) + endif (USE_TCMALLOC) + set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES - # *TODO -reenable this once we get server usage sorted out - #LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:\"__tcmalloc\"" -# LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_INCLUDE_FLAGS}" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" LINK_FLAGS_RELEASE "" ) @@ -1765,7 +1768,7 @@ target_link_libraries(${VIEWER_BINARY_NAME} ${CRYPTO_LIBRARIES} ${LLLOGIN_LIBRARIES} ${LLCONVEXDECOMP_LIBRARY} -# ${TCMALLOC_LIBRARIES} + ${TCMALLOC_LIBRARIES} ) if (USE_KDU) -- cgit v1.2.3 From d3b0a1375509f772ec3ddbc790b5a5d9f4fa7594 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 5 Jan 2012 18:24:42 -0500 Subject: SH-2789 WIP - fix for linux build failure --- indra/cmake/GooglePerfTools.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index 0c31d73655..834da6d9b8 100755 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -47,7 +47,7 @@ endif (WINDOWS) # Apparently buggy - LL_USE_TCMALLOC never gets set. Fix when we have time to test the # corresponding source code. if (USE_TCMALLOC) - set(TCMALLOC_FLAG -ULL_USE_TCMALLOC=1) + set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) # was -ULL_USE_TCMALLOC=1 which makes no sense. else (USE_TCMALLOC) set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) endif (USE_TCMALLOC) -- cgit v1.2.3 From bfe6e94f5388b887253ba77f633ae332affe9f92 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 6 Jan 2012 13:01:17 -0500 Subject: SH-2789 WIP - fixing the LL_USE_TCMALLOC code, make tests build with the same tcmalloc options as the sl executable --- indra/cmake/GooglePerfTools.cmake | 16 +++++++++------- indra/cmake/LLAddBuildTest.cmake | 9 +++++++++ indra/llcommon/llallocator.cpp | 2 +- indra/newview/CMakeLists.txt | 8 +------- 4 files changed, 20 insertions(+), 15 deletions(-) mode change 100644 => 100755 indra/cmake/LLAddBuildTest.cmake mode change 100644 => 100755 indra/llcommon/llallocator.cpp diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index 834da6d9b8..09501e0406 100755 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -14,8 +14,10 @@ else (STANDALONE) set(TCMALLOC_LIBRARIES debug libtcmalloc_minimal-debug optimized libtcmalloc_minimal) + set(TCMALLOC_LINK_FLAGS "/INCLUDE:__tcmalloc") else (USE_TCMALLOC) set(TCMALLOC_LIBRARIES) + set(TCMALLOC_LINK_FLAGS) endif (USE_TCMALLOC) set(GOOGLE_PERFTOOLS_FOUND "YES") endif (WINDOWS) @@ -44,13 +46,13 @@ if (WINDOWS) set(USE_GOOGLE_PERFTOOLS ON) endif (WINDOWS) -# Apparently buggy - LL_USE_TCMALLOC never gets set. Fix when we have time to test the -# corresponding source code. -if (USE_TCMALLOC) - set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) # was -ULL_USE_TCMALLOC=1 which makes no sense. -else (USE_TCMALLOC) - set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) -endif (USE_TCMALLOC) +if (USE_GOOGLE_PERFTOOLS) + if (USE_TCMALLOC) + set(TCMALLOC_FLAG -DLL_USE_TCMALLOC=1) + else (USE_TCMALLOC) + set(TCMALLOC_FLAG -ULL_USE_TCMALLOC) + endif (USE_TCMALLOC) +endif (USE_GOOGLE_PERFTOOLS) if (USE_GOOGLE_PERFTOOLS) include_directories(${GOOGLE_PERFTOOLS_INCLUDE_DIR}) diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake old mode 100644 new mode 100755 index 08feab6e36..a6f69a09e9 --- a/indra/cmake/LLAddBuildTest.cmake +++ b/indra/cmake/LLAddBuildTest.cmake @@ -205,6 +205,15 @@ FUNCTION(LL_ADD_INTEGRATION_TEST SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}") endif(STANDALONE) + if (WINDOWS) + SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS}" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" + LINK_FLAGS_RELEASE "" + ) + endif (WINDOWS) + # Add link deps to the executable if(TEST_DEBUG) message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})") diff --git a/indra/llcommon/llallocator.cpp b/indra/llcommon/llallocator.cpp old mode 100644 new mode 100755 index 6f6abefc67..87654b5b97 --- a/indra/llcommon/llallocator.cpp +++ b/indra/llcommon/llallocator.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include "llallocator.h" -#if LL_USE_TCMALLOC +#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER) #include "google/heap-profiler.h" #include "google/commandlineflags_public.h" diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 00cf1ba8df..f929e8d379 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1505,15 +1505,9 @@ set(PACKAGE ON CACHE BOOL "Add a package target that builds an installer package.") if (WINDOWS) - if (USE_TCMALLOC) - set(TCMALLOC_INCLUDE_FLAGS "/INCLUDE:__tcmalloc") - else (USE_TCMALLOC) - set(TCMALLOC_INCLUDE_FLAGS) - endif (USE_TCMALLOC) - set_target_properties(${VIEWER_BINARY_NAME} PROPERTIES - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_INCLUDE_FLAGS}" + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${TCMALLOC_LINK_FLAGS}" LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" LINK_FLAGS_RELEASE "" ) -- cgit v1.2.3 From 60a9c8d7abe102cefeb72666b9645a6dd34e84b8 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 11 Jan 2012 15:59:34 -0500 Subject: Fixes for alignment tests with tcmalloc --- indra/llcommon/llmemory.h | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 1b54b56107..9dd776ff57 100755 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -27,7 +27,6 @@ #define LLMEMORY_H #include "llmemtype.h" -#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc( size_t size, int align ) { void* mem = malloc( size + (align - 1) + sizeof(void*) ); @@ -43,6 +42,7 @@ inline void ll_aligned_free( void* ptr ) free( ((void**)ptr)[-1] ); } +#if !LL_USE_TCMALLOC inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16(). { #if defined(LL_WINDOWS) @@ -79,6 +79,12 @@ inline void ll_aligned_free_16(void *p) free(p); // posix_memalign() is compatible with heap deallocator #endif } +#else // USE_TCMALLOC +// ll_aligned_foo_16 are not needed with tcmalloc +#define ll_aligned_malloc_16 malloc +#define ll_aligned_realloc_16 realloc +#define ll_aligned_free_16 free +#endif // USE_TCMALLOC inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32(). { @@ -106,18 +112,6 @@ inline void ll_aligned_free_32(void *p) #endif } -#else // USE_TCMALLOC -// ll_aligned_foo are noops now that we use tcmalloc everywhere -// (tcmalloc aligns automatically at appropriate intervals) -#define ll_aligned_malloc( size, align ) malloc(size) -#define ll_aligned_free( ptr ) free(ptr) -#define ll_aligned_malloc_16 malloc -#define ll_aligned_realloc_16 realloc -#define ll_aligned_free_16 free -#define ll_aligned_malloc_32 malloc -#define ll_aligned_free_32 free -#endif // LL_DEBUG - #ifndef __DEBUG_PRIVATE_MEM__ #define __DEBUG_PRIVATE_MEM__ 0 #endif -- cgit v1.2.3 From c0fffdea8812e5eed8da9f341d3bfc9590301ada Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 12 Jan 2012 16:11:06 -0500 Subject: SH-2789 WIP --- indra/cmake/GooglePerfTools.cmake | 2 +- indra/llui/llview.cpp | 2 +- indra/newview/llappviewerwin32.cpp | 2 +- indra/newview/llface.cpp | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index 09501e0406..73b3642ae6 100755 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -3,7 +3,7 @@ include(Prebuilt) # If you want to enable or disable TCMALLOC in viewer builds, this is the place. # set ON or OFF as desired. -set (USE_TCMALLOC ON) +set (USE_TCMALLOC OFF) if (STANDALONE) include(FindGooglePerfTools) diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp index 542f57ee5f..7abe4ecd9f 100644 --- a/indra/llui/llview.cpp +++ b/indra/llui/llview.cpp @@ -283,7 +283,7 @@ void LLView::moveChildToBackOfTabGroup(LLUICtrl* child) bool LLView::addChild(LLView* child, S32 tab_group) { // NOTE: Changed this to not crash in release mode - llassert(mInDraw == false); + //llassert(mInDraw == false); if (!child) { diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 647ace7ee3..8087453ee5 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -117,7 +117,7 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, // This results in a 2-3x improvement in opening a new Inventory window (which uses a large numebr of allocations) // Note: This won't work when running from the debugger unless the _NO_DEBUG_HEAP environment variable is set to 1 - _CrtSetDbgFlag(0); // default, just making explicit + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // default, just making explicit ULONG ulEnableLFH = 2; HANDLE* hHeaps = new HANDLE[MAX_HEAPS]; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 6dbeae6677..f60f311b9e 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1377,7 +1377,8 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { if (!do_xform) { - LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, num_vertices*2*sizeof(F32)); + S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; + LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); } else { -- cgit v1.2.3 From e0f919711034ee4a112ae4b583486693bc104a7b Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 25 Jan 2012 14:58:47 -0500 Subject: Fix for build failures when tcmalloc disabled --- indra/cmake/Copy3rdPartyLibs.cmake | 4 ++-- indra/newview/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 394db362b1..8e5d901779 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -55,10 +55,10 @@ if(WINDOWS) glod.dll ) - if(USE_GOOGLE_PERFTOOLS) + if(USE_TCMALLOC) set(debug_files ${debug_files} libtcmalloc_minimal-debug.dll) set(release_files ${release_files} libtcmalloc_minimal.dll) - endif(USE_GOOGLE_PERFTOOLS) + endif(USE_TCMALLOC) if (FMOD) set(debug_files ${debug_files} fmod.dll) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index f929e8d379..3e8b365f3a 100755 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1526,7 +1526,7 @@ if (WINDOWS) # In the meantime, if you have any ideas on how to easily maintain one list, either here or in viewer_manifest.py # and have the build deps get tracked *please* tell me about it. - if(USE_GOOGLE_PERFTOOLS) + if(USE_TCMALLOC) # Configure a var for tcmalloc location, if used. # Note the need to specify multiple names explicitly. set(GOOGLE_PERF_TOOLS_SOURCE @@ -1534,7 +1534,7 @@ if (WINDOWS) ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libtcmalloc_minimal.dll ${SHARED_LIB_STAGING_DIR}/Debug/libtcmalloc_minimal-debug.dll ) - endif(USE_GOOGLE_PERFTOOLS) + endif(USE_TCMALLOC) set(COPY_INPUT_DEPENDENCIES -- cgit v1.2.3 From 16b6595fa75047c6c53ee11a6c3004e99ae0937d Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 26 Jan 2012 13:38:11 -0500 Subject: trying to fix linux build error --- indra/cmake/Copy3rdPartyLibs.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 8e5d901779..966300f1c7 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -268,13 +268,16 @@ elseif(LINUX) libopenal.so libopenjpeg.so libssl.so - libtcmalloc_minimal.so libuuid.so.16 libuuid.so.16.0.22 libssl.so.1.0.0 libfontconfig.so.1.4.4 ) + if (USE_TCMALLOC) + set(release_files ${release_files} "libtcmalloc_minimal.so") + endif (USE_TCMALLOC) + if (FMOD) set(release_files ${release_files} "libfmod-3.75.so") endif (FMOD) -- cgit v1.2.3 From 0b16411d302c940ff98ae5529821d9b5a4dbfbd7 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 26 Jan 2012 14:07:37 -0500 Subject: assert fix for mempyNonAliased16 call --- indra/llmath/tests/alignment_test.cpp | 1 + indra/llprimitive/llmodel.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index 044e05e961..8961b9d6d5 100755 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -62,6 +62,7 @@ class MyVector4a LLQuad mQ; } LL_ALIGN_POSTFIX(16); + // Verify that aligned allocators perform as advertised. template<> template<> void alignment_test_object_t::test<1>() diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index cb32a510b8..28ed051c55 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1026,7 +1026,8 @@ void LLModel::setVolumeFaceData( if (tc.get()) { - LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), num_verts*2*sizeof(F32)); + U32 tex_size = (num_verts*2*sizeof(F32)+0xF)&~0xF; + LLVector4a::memcpyNonAliased16((F32*) face.mTexCoords, (F32*) tc.get(), tex_size); } else { -- cgit v1.2.3 From 15ec54b1daef88881b0dc9acb0e14290be8e9e5d Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 27 Jan 2012 11:04:13 -0500 Subject: Fix for linux build failure when tcmalloc disabled --- indra/newview/viewer_manifest.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) mode change 100644 => 100755 indra/newview/viewer_manifest.py diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py old mode 100644 new mode 100755 index 0931c4ec9b..43abae63f1 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1057,9 +1057,15 @@ class Linux_i686Manifest(LinuxManifest): self.path("libopenal.so", "libopenal.so.1") self.path("libopenal.so", "libvivoxoal.so.1") # vivox's sdk expects this soname self.path("libfontconfig.so.1.4.4") - self.path("libtcmalloc.so", "libtcmalloc.so") #formerly called google perf tools - self.path("libtcmalloc.so.0", "libtcmalloc.so.0") #formerly called google perf tools - self.path("libtcmalloc.so.0.1.0", "libtcmalloc.so.0.1.0") #formerly called google perf tools + try: + self.path("libtcmalloc.so", "libtcmalloc.so") #formerly called google perf tools + self.path("libtcmalloc.so.0", "libtcmalloc.so.0") #formerly called google perf tools + self.path("libtcmalloc.so.0.1.0", "libtcmalloc.so.0.1.0") #formerly called google perf tools + pass + except: + print "tcmalloc files not found, skipping" + pass + try: self.path("libfmod-3.75.so") pass -- cgit v1.2.3 From b13fe12fb950f714a2e2fd97708a3baef39ef285 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 3 Feb 2012 14:10:51 -0500 Subject: tcmalloc on by default --- indra/cmake/GooglePerfTools.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake index 73b3642ae6..09501e0406 100755 --- a/indra/cmake/GooglePerfTools.cmake +++ b/indra/cmake/GooglePerfTools.cmake @@ -3,7 +3,7 @@ include(Prebuilt) # If you want to enable or disable TCMALLOC in viewer builds, this is the place. # set ON or OFF as desired. -set (USE_TCMALLOC OFF) +set (USE_TCMALLOC ON) if (STANDALONE) include(FindGooglePerfTools) -- cgit v1.2.3 From d1987a3002efc7252b98e2e570746c66c43e6dd1 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 6 Jun 2012 14:28:21 -0400 Subject: SH-2789 FIX - windows debug heap off by default --- indra/newview/llappviewerwin32.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100644 => 100755 indra/newview/llappviewerwin32.cpp diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp old mode 100644 new mode 100755 index 418df8a5b0..53c77fa22e --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -130,7 +130,9 @@ int APIENTRY WINMAIN(HINSTANCE hInstance, // This results in a 2-3x improvement in opening a new Inventory window (which uses a large numebr of allocations) // Note: This won't work when running from the debugger unless the _NO_DEBUG_HEAP environment variable is set to 1 - _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); // default, just making explicit + // Enable to get mem debugging within visual studio. + //_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + _CrtSetDbgFlag(0); // default, just making explicit ULONG ulEnableLFH = 2; HANDLE* hHeaps = new HANDLE[MAX_HEAPS]; -- cgit v1.2.3 From 89ee86c86c188708234e1bc9c519945ec85ff8ed Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 22 Jun 2012 15:54:53 -0400 Subject: line endings fix --- indra/llmath/tests/alignment_test.cpp | 240 +++++++++++++++++----------------- 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/indra/llmath/tests/alignment_test.cpp b/indra/llmath/tests/alignment_test.cpp index 8961b9d6d5..dbb42c4a3d 100755 --- a/indra/llmath/tests/alignment_test.cpp +++ b/indra/llmath/tests/alignment_test.cpp @@ -1,120 +1,120 @@ -/** - * @file v3dmath_test.cpp - * @author Vir - * @date 2011-12 - * @brief v3dmath test cases. - * - * $LicenseInfo:firstyear=2011&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2011, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -// Tests related to allocating objects with alignment constraints, particularly for SSE support. - -#include "linden_common.h" -#include "../test/lltut.h" -#include "../llmath.h" -#include "../llsimdmath.h" -#include "../llvector4a.h" - -void* operator new(size_t size) -{ - return ll_aligned_malloc_16(size); -} - -void operator delete(void *p) -{ - ll_aligned_free_16(p); -} - -namespace tut -{ - -#define is_aligned(ptr,alignment) ((reinterpret_cast(ptr))%(alignment)==0) -#define is_aligned_relative(ptr,base_ptr,alignment) ((reinterpret_cast(ptr)-reinterpret_cast(base_ptr))%(alignment)==0) - -struct alignment_test {}; - -typedef test_group alignment_test_t; -typedef alignment_test_t::object alignment_test_object_t; -tut::alignment_test_t tut_alignment_test("LLAlignment"); - -LL_ALIGN_PREFIX(16) -class MyVector4a -{ - LLQuad mQ; -} LL_ALIGN_POSTFIX(16); - - -// Verify that aligned allocators perform as advertised. -template<> template<> -void alignment_test_object_t::test<1>() -{ - const int num_tests = 7; - void *align_ptr; - for (int i=0; i template<> -void alignment_test_object_t::test<2>() -{ - MyVector4a vec1; - ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); - - MyVector4a veca[12]; - ensure("LLAlignment veca unaligned", is_aligned(veca,16)); -} - -// Heap allocation of objects and arrays. -template<> template<> -void alignment_test_object_t::test<3>() -{ - const int ARR_SIZE = 7; - for(int i=0; i(ptr))%(alignment)==0) +#define is_aligned_relative(ptr,base_ptr,alignment) ((reinterpret_cast(ptr)-reinterpret_cast(base_ptr))%(alignment)==0) + +struct alignment_test {}; + +typedef test_group alignment_test_t; +typedef alignment_test_t::object alignment_test_object_t; +tut::alignment_test_t tut_alignment_test("LLAlignment"); + +LL_ALIGN_PREFIX(16) +class MyVector4a +{ + LLQuad mQ; +} LL_ALIGN_POSTFIX(16); + + +// Verify that aligned allocators perform as advertised. +template<> template<> +void alignment_test_object_t::test<1>() +{ + const int num_tests = 7; + void *align_ptr; + for (int i=0; i template<> +void alignment_test_object_t::test<2>() +{ + MyVector4a vec1; + ensure("LLAlignment vec1 unaligned", is_aligned(&vec1,16)); + + MyVector4a veca[12]; + ensure("LLAlignment veca unaligned", is_aligned(veca,16)); +} + +// Heap allocation of objects and arrays. +template<> template<> +void alignment_test_object_t::test<3>() +{ + const int ARR_SIZE = 7; + for(int i=0; i Date: Tue, 26 Jun 2012 11:41:22 -0400 Subject: line endings fix --- .../xui/en/floater_texture_fetch_debugger.xml | 682 ++++++++++----------- 1 file changed, 341 insertions(+), 341 deletions(-) diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml index 44b6a63bca..f3f8d4ddca 100644 --- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml +++ b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml @@ -1,341 +1,341 @@ - - - - 1, Total number of fetched textures: [NUM] - - - 2, Total number of fetching requests: [NUM] - - - 3, Total number of cache hits: [NUM] - - - 4, Total number of visible textures: [NUM] - - - 5, Total number of visible texture fetching requests: [NUM] - - - 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels - - - 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB - - - 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels - - - 9, Total time on cache readings: [TIME] seconds - - - 10, Total time on cache writings: [TIME] seconds - - - 11, Total time on decodings: [TIME] seconds - - - 12, Total time on gl texture creation: [TIME] seconds - - - 13, Total time on HTTP fetching: [TIME] seconds - - - 14, Total time on entire fetching: [TIME] seconds - - - 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels - - - 16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels - - - - - - - - - - - - - - - + + + + 1, Total number of fetched textures: [NUM] + + + 2, Total number of fetching requests: [NUM] + + + 3, Total number of cache hits: [NUM] + + + 4, Total number of visible textures: [NUM] + + + 5, Total number of visible texture fetching requests: [NUM] + + + 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels + + + 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB + + + 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels + + + 9, Total time on cache readings: [TIME] seconds + + + 10, Total time on cache writings: [TIME] seconds + + + 11, Total time on decodings: [TIME] seconds + + + 12, Total time on gl texture creation: [TIME] seconds + + + 13, Total time on HTTP fetching: [TIME] seconds + + + 14, Total time on entire fetching: [TIME] seconds + + + 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + + + 16, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels + + + + + + + + + + + + + + + -- cgit v1.2.3 From c9f1b1b5113031d5879e8fcdcec263626a7d3122 Mon Sep 17 00:00:00 2001 From: Oz Linden Date: Wed, 27 Jun 2012 14:15:40 -0400 Subject: tag merge of DRTVWR-167 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 6dd9a0e111..55a5def44a 100644 --- a/.hgtags +++ b/.hgtags @@ -317,3 +317,4 @@ fdcc08a4f20ae9bb060f4693c8980d216534efdf 3.3.3-beta2 af5f3e43e6e4424b1da19d9e16f6b853a7b822ed DRTVWR-169 4b3c68199a86cabaa5d9466d7b0f7e141e901d7a 3.3.3-beta3 6428242e124b523813bfaf4c45b3d422f0298c81 3.3.3-release +005dfe5c4c377207d065fb27858d2eb0b53b143a DRTVWR-167 -- cgit v1.2.3