diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llcommon/llhash.h | 15 | ||||
| -rw-r--r-- | indra/llcommon/llsdserialize_xml.cpp | 176 | ||||
| -rw-r--r-- | indra/llmessage/llmessagethrottle.cpp | 4 | ||||
| -rw-r--r-- | indra/llprimitive/llprimitive.cpp | 13 | ||||
| -rw-r--r-- | indra/test/llblowfish_tut.cpp | 24 | 
5 files changed, 177 insertions, 55 deletions
| diff --git a/indra/llcommon/llhash.h b/indra/llcommon/llhash.h index 08299f5ddc..ee327be8c9 100644 --- a/indra/llcommon/llhash.h +++ b/indra/llcommon/llhash.h @@ -53,15 +53,20 @@  #error Please define your platform.  #endif -template<class T> inline size_t llhash(T value)  -{  +// Warning - an earlier template-based version of this routine did not do +// the correct thing on Windows.   Since this is only used to get +// a string hash, it was converted to a regular routine and +// unit tests added. + +inline size_t llhash( const char * value ) +{  #if LL_WINDOWS -	return stdext::hash_value<T>(value); +	return stdext::hash_value(value);  #elif ( (defined _STLPORT_VERSION) || ((LL_LINUX) && (__GNUC__ <= 2)) ) -	std::hash<T> H; +	std::hash<const char *> H;  	return H(value);  #elif LL_DARWIN || LL_LINUX || LL_SOLARIS -	__gnu_cxx::hash<T> H; +	__gnu_cxx::hash<const char *> H;  	return H(value);  #else  #error Please define your platform. diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index edcc244f58..ecb5b73fcd 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -318,8 +318,8 @@ private:  	bool mSkipping;  	int mSkipThrough; -	std::string mCurrentKey; -	std::ostringstream mCurrentContent; +	std::string mCurrentKey;		// Current XML <tag> +	std::string mCurrentContent;	// String data between <tag> and </tag>  }; @@ -556,16 +556,50 @@ void LLSDXMLParser::Impl::parsePart(const char* buf, int len)  	}  } +// Performance testing code +//#define	XML_PARSER_PERFORMANCE_TESTS + +#ifdef XML_PARSER_PERFORMANCE_TESTS + +extern U64 totalTime(); +U64	readElementTime = 0; +U64 startElementTime = 0; +U64 endElementTime = 0; +U64 charDataTime = 0; +U64 parseTime = 0; + +class XML_Timer +{ +public: +	XML_Timer( U64 * sum ) : mSum( sum ) +	{ +		mStart = totalTime(); +	} +	~XML_Timer() +	{ +		*mSum += (totalTime() - mStart); +	} + +	U64 * mSum; +	U64 mStart; +}; +#endif // XML_PARSER_PERFORMANCE_TESTS +  void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Char** attributes)  { +	#ifdef XML_PARSER_PERFORMANCE_TESTS +	XML_Timer timer( &startElementTime ); +	#endif // XML_PARSER_PERFORMANCE_TESTS +	  	++mDepth;  	if (mSkipping)  	{  		return;  	} -	 +  	Element element = readElement(name); -	mCurrentContent.str(""); +	 +	mCurrentContent.clear();  	switch (element)  	{ @@ -645,6 +679,10 @@ void LLSDXMLParser::Impl::startElementHandler(const XML_Char* name, const XML_Ch  void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)  { +	#ifdef XML_PARSER_PERFORMANCE_TESTS +	XML_Timer timer( &endElementTime ); +	#endif // XML_PARSER_PERFORMANCE_TESTS +  	--mDepth;  	if (mSkipping)  	{ @@ -669,7 +707,7 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)  			return;  		case ELEMENT_KEY: -			mCurrentKey = mCurrentContent.str(); +			mCurrentKey = mCurrentContent;  			return;  		default: @@ -682,9 +720,6 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)  	LLSD& value = *mStack.back();  	mStack.pop_back(); -	std::string content = mCurrentContent.str(); -	mCurrentContent.str(""); -  	switch (element)  	{  		case ELEMENT_UNDEF: @@ -692,39 +727,59 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)  			break;  		case ELEMENT_BOOL: -			value = content == "true" || content == "1"; +			value = (mCurrentContent == "true" || mCurrentContent == "1");  			break;  		case ELEMENT_INTEGER: -			value = LLSD(content).asInteger(); +			{ +				S32 i; +				if ( sscanf(mCurrentContent.c_str(), "%d", &i ) == 1 ) +				{	// See if sscanf works - it's faster +					value = i; +				} +				else +				{ +					value = LLSD(mCurrentContent).asInteger(); +				} +			}  			break;  		case ELEMENT_REAL: -			value = LLSD(content).asReal(); +			{ +				F64 r; +				if ( sscanf(mCurrentContent.c_str(), "%lf", &r ) == 1 ) +				{	// See if sscanf works - it's faster +					value = r; +				} +				else +				{ +					value = LLSD(mCurrentContent).asReal(); +				} +			}  			break;  		case ELEMENT_STRING: -			value = content; +			value = mCurrentContent;  			break;  		case ELEMENT_UUID: -			value = LLSD(content).asUUID(); +			value = LLSD(mCurrentContent).asUUID();  			break;  		case ELEMENT_DATE: -			value = LLSD(content).asDate(); +			value = LLSD(mCurrentContent).asDate();  			break;  		case ELEMENT_URI: -			value = LLSD(content).asURI(); +			value = LLSD(mCurrentContent).asURI();  			break;  		case ELEMENT_BINARY:  		{ -			S32 len = apr_base64_decode_len(content.c_str()); +			S32 len = apr_base64_decode_len(mCurrentContent.c_str());  			std::vector<U8> data;  			data.resize(len); -			len = apr_base64_decode_binary(&data[0], content.c_str()); +			len = apr_base64_decode_binary(&data[0], mCurrentContent.c_str());  			data.resize(len);  			value = data;  			break; @@ -738,11 +793,17 @@ void LLSDXMLParser::Impl::endElementHandler(const XML_Char* name)  			// other values, map and array, have already been set  			break;  	} + +	mCurrentContent.clear();  }  void LLSDXMLParser::Impl::characterDataHandler(const XML_Char* data, int length)  { -	mCurrentContent.write(data, length); +	#ifdef XML_PARSER_PERFORMANCE_TESTS +	XML_Timer timer( &charDataTime ); +	#endif	// XML_PARSER_PERFORMANCE_TESTS + +	mCurrentContent.append(data, length);  } @@ -765,22 +826,69 @@ void LLSDXMLParser::Impl::sCharacterDataHandler(  } +/* +	This code is time critical + +	This is a sample of tag occurances of text in simstate file with ~8000 objects. +	A tag pair (<key>something</key>) counts is counted as two: + +		key     - 2680178 +		real    - 1818362 +		integer -  906078 +		array   -  295682 +		map     -  191818 +		uuid    -  177903 +		binary  -  175748 +		string  -   53482 +		undef   -   40353 +		boolean -   33874 +		llsd    -   16332 +		uri     -      38 +		date    -       1 +*/  LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* name)  { -	if (strcmp(name, "llsd") == 0) { return ELEMENT_LLSD; } -	if (strcmp(name, "undef") == 0) { return ELEMENT_UNDEF; } -	if (strcmp(name, "boolean") == 0) { return ELEMENT_BOOL; } -	if (strcmp(name, "integer") == 0) { return ELEMENT_INTEGER; } -	if (strcmp(name, "real") == 0) { return ELEMENT_REAL; } -	if (strcmp(name, "string") == 0) { return ELEMENT_STRING; } -	if (strcmp(name, "uuid") == 0) { return ELEMENT_UUID; } -	if (strcmp(name, "date") == 0) { return ELEMENT_DATE; } -	if (strcmp(name, "uri") == 0) { return ELEMENT_URI; } -	if (strcmp(name, "binary") == 0) { return ELEMENT_BINARY; } -	if (strcmp(name, "map") == 0) { return ELEMENT_MAP; } -	if (strcmp(name, "array") == 0) { return ELEMENT_ARRAY; } -	if (strcmp(name, "key") == 0) { return ELEMENT_KEY; } -	 +	#ifdef XML_PARSER_PERFORMANCE_TESTS +	XML_Timer timer( &readElementTime ); +	#endif // XML_PARSER_PERFORMANCE_TESTS + +	XML_Char c = *name; +	switch (c) +	{ +		case 'k': +			if (strcmp(name, "key") == 0) { return ELEMENT_KEY; } +			break; +		case 'r': +			if (strcmp(name, "real") == 0) { return ELEMENT_REAL; } +			break; +		case 'i': +			if (strcmp(name, "integer") == 0) { return ELEMENT_INTEGER; } +			break; +		case 'a': +			if (strcmp(name, "array") == 0) { return ELEMENT_ARRAY; } +			break; +		case 'm': +			if (strcmp(name, "map") == 0) { return ELEMENT_MAP; } +			break; +		case 'u': +			if (strcmp(name, "uuid") == 0) { return ELEMENT_UUID; } +			if (strcmp(name, "undef") == 0) { return ELEMENT_UNDEF; } +			if (strcmp(name, "uri") == 0) { return ELEMENT_URI; } +			break; +		case 'b': +			if (strcmp(name, "binary") == 0) { return ELEMENT_BINARY; } +			if (strcmp(name, "boolean") == 0) { return ELEMENT_BOOL; } +			break; +		case 's': +			if (strcmp(name, "string") == 0) { return ELEMENT_STRING; } +			break; +		case 'l': +			if (strcmp(name, "llsd") == 0) { return ELEMENT_LLSD; } +			break; +		case 'd': +			if (strcmp(name, "date") == 0) { return ELEMENT_DATE; } +			break; +	}  	return ELEMENT_UNKNOWN;  } @@ -808,6 +916,10 @@ void LLSDXMLParser::parsePart(const char *buf, int len)  // virtual  S32 LLSDXMLParser::doParse(std::istream& input, LLSD& data) const  { +	#ifdef XML_PARSER_PERFORMANCE_TESTS +	XML_Timer timer( &parseTime ); +	#endif	// XML_PARSER_PERFORMANCE_TESTS +  	if (mParseLines)  	{  		// Use line-based reading (faster code) diff --git a/indra/llmessage/llmessagethrottle.cpp b/indra/llmessage/llmessagethrottle.cpp index 846d4067ad..db2cc28501 100644 --- a/indra/llmessage/llmessagethrottle.cpp +++ b/indra/llmessage/llmessagethrottle.cpp @@ -119,7 +119,7 @@ BOOL LLMessageThrottle::addViewerAlert(const LLUUID& to, const std::string& mesg  	full_mesg << to << mesg;  	// Create an entry for this message. -	size_t hash = llhash<const char*> (full_mesg.str().c_str()); +	size_t hash = llhash(full_mesg.str().c_str());  	LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());  	// Check if this message is already in the list. @@ -153,7 +153,7 @@ BOOL LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, c  	full_mesg << agent << task << mesg;  	// Create an entry for this message. -	size_t hash = llhash<const char*> (full_mesg.str().c_str()); +	size_t hash = llhash(full_mesg.str().c_str());  	LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());  	// Check if this message is already in the list. diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 90292d8f78..0039cca222 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -114,6 +114,11 @@ const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;  const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; +// Texture rotations are sent over the wire as a S16.  This is used to scale the actual float +// value to a S16.   Don't use 7FFF as it introduces some odd rounding with 180 since it  +// can't be divided by 2.   See DEV-19108 +const F32	TEXTURE_ROTATION_PACK_FACTOR = ((F32) 0x08000); +  //static   // LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global  // TODO -- eliminate this global from the codebase! @@ -1373,7 +1378,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const  			scale_t[face_index] = (F32) te->mScaleT;  			offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;  			offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; -			image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF)); +			image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));  			bump[face_index] = te->getBumpShinyFullbright();  			media_flags[face_index] = te->getMediaTexGen();  			glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); @@ -1452,7 +1457,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const  			scale_t[face_index] = (F32) te->mScaleT;  			offset_s[face_index] = (S16) llround((llclamp(te->mOffsetS,-1.0f,1.0f) * (F32)0x7FFF)) ;  			offset_t[face_index] = (S16) llround((llclamp(te->mOffsetT,-1.0f,1.0f) * (F32)0x7FFF)) ; -			image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF)); +			image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * TEXTURE_ROTATION_PACK_FACTOR));  			bump[face_index] = te->getBumpShinyFullbright();  			media_flags[face_index] = te->getMediaTexGen();              glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF)); @@ -1566,7 +1571,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con  		retval |= setTETexture(i, ((LLUUID*)image_data)[i]);  		retval |= setTEScale(i, scale_s[i], scale_t[i]);  		retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); -		retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI); +		retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);  		retval |= setTEBumpShinyFullbright(i, bump[i]);  		retval |= setTEMediaTexGen(i, media_flags[i]);  		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); @@ -1660,7 +1665,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)  		retval |= setTETexture(i, image_ids[i]);  		retval |= setTEScale(i, scale_s[i], scale_t[i]);  		retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF); -		retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI); +		retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);  		retval |= setTEBumpShinyFullbright(i, bump[i]);  		retval |= setTEMediaTexGen(i, media_flags[i]);  		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF); diff --git a/indra/test/llblowfish_tut.cpp b/indra/test/llblowfish_tut.cpp index eb2e4ed0f8..97ed2be760 100644 --- a/indra/test/llblowfish_tut.cpp +++ b/indra/test/llblowfish_tut.cpp @@ -93,9 +93,7 @@ namespace tut  	template<> template<>  	void blowfish_object::test<1>()  	{ -#if LL_WINDOWS -		skip_fail("Blowfish only supported on Linux."); -#else +#if LL_LINUX  		LLUUID blank;  		LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -108,15 +106,15 @@ namespace tut  		dst_len = cipher.requiredEncryptionSpace(8);  		ensure("encryption space 8",  				(dst_len == 16)  ); -#endif // LL_WINDOWS +#else +		skip_fail("Blowfish only supported on Linux."); +#endif // LL_LINUX  	}  	template<> template<>  	void blowfish_object::test<2>()  	{ -#if LL_WINDOWS -		skip_fail("Blowfish only supported on Linux."); -#else +#if LL_LINUX  		LLUUID blank;  		LLBlowfishCipher cipher(&blank.mData[0], UUID_BYTES); @@ -130,15 +128,15 @@ namespace tut  		result.resize(count);  		ensure("encrypt null key", matchFile("blowfish.1.bin", result)); -#endif // LL_WINDOWS +#else +		skip_fail("Blowfish only supported on Linux."); +#endif // LL_LINUX  	}  	template<> template<>  	void blowfish_object::test<3>()  	{ -#if LL_WINDOWS -        skip_fail("Blowfish only supported on Linux."); -#else +#if LL_LINUX          // same as base64 test id  		LLUUID id("526a1e07-a19d-baed-84c4-ff08a488d15e");  		LLBlowfishCipher cipher(&id.mData[0], UUID_BYTES); @@ -153,6 +151,8 @@ namespace tut  		result.resize(count);  		ensure("encrypt real key", matchFile("blowfish.2.bin", result)); -#endif // LL_WINDOWS +#else +        skip_fail("Blowfish only supported on Linux."); +#endif // LL_LINUX  	}  } | 
