فهرست منبع

Apply patch "More efficient SoundData allocator" that allocates memory less often, and shrinks to minimum size afterwards

Bart van Strien 13 سال پیش
والد
کامیت
eb7a758691
1فایلهای تغییر یافته به همراه19 افزوده شده و 2 حذف شده
  1. 19 2
      src/modules/sound/SoundData.cpp

+ 19 - 2
src/modules/sound/SoundData.cpp

@@ -36,16 +36,22 @@ namespace sound
 	SoundData::SoundData(Decoder * decoder)
 	SoundData::SoundData(Decoder * decoder)
 		: data(0), size(0), sampleRate(Decoder::DEFAULT_SAMPLE_RATE), bits(0), channels(0)
 		: data(0), size(0), sampleRate(Decoder::DEFAULT_SAMPLE_RATE), bits(0), channels(0)
 	{
 	{
+		size_t bufferSize = 524288;
 		int decoded = decoder->decode();
 		int decoded = decoder->decode();
 
 
 		while (decoded > 0)
 		while (decoded > 0)
 		{
 		{
 			// Expand or allocate buffer. Note that realloc may move
 			// Expand or allocate buffer. Note that realloc may move
 			// memory to other locations.
 			// memory to other locations.
-			data = (char*)realloc(data, size + decoder->getSize());
+			if (!data || bufferSize < (size_t) size + decoded)
+			{
+				while (bufferSize < (size_t) size + decoded)
+					bufferSize <<= 1;
+				data = (char*)realloc(data, bufferSize);
+			}
 
 
 			if (!data)
 			if (!data)
-				throw love::Exception("Not enough memory."); // I know, I know, little memory, creating objects..
+				throw love::Exception("Not enough memory.");
 
 
 			// Copy memory into new part of memory.
 			// Copy memory into new part of memory.
 			memcpy(data + size, decoder->getBuffer(), decoded);
 			memcpy(data + size, decoder->getBuffer(), decoded);
@@ -53,9 +59,20 @@ namespace sound
 			// Keep this up to date.
 			// Keep this up to date.
 			size += decoded;
 			size += decoded;
 
 
+			// Overflow check.
+			if (size < 0)
+			{
+				free(data);
+				throw love::Exception("Not enough memory.");
+			}
+
 			decoded = decoder->decode();
 			decoded = decoder->decode();
 		}
 		}
 
 
+		// Shrink buffer if necessary.
+		if (data && bufferSize > (size_t) size)
+			data = (char*) realloc(data, size);
+
 		channels = decoder->getChannels();
 		channels = decoder->getChannels();
 		bits = decoder->getBits();
 		bits = decoder->getBits();
 		sampleRate = decoder->getSampleRate();
 		sampleRate = decoder->getSampleRate();