From fbb02475dae7e39e7b29341a8b62031cb68f2420 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Sun, 16 Apr 2017 22:39:50 -0700 Subject: [PATCH] VFS: Optimize expanding in-memory files --- CHANGES | 1 + src/util/vfs/vfs-mem.c | 29 +++++++++++++++++++---------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/CHANGES b/CHANGES index e24c84992..5c9f39755 100644 --- a/CHANGES +++ b/CHANGES @@ -103,6 +103,7 @@ Misc: - Feature: Make -l option explicit - Core: Ability to enumerate and modify video and audio channels - Debugger: Make attaching a backend idempotent + - VFS: Optimize expanding in-memory files 0.5.2: (2016-12-31) Bugfixes: diff --git a/src/util/vfs/vfs-mem.c b/src/util/vfs/vfs-mem.c index 7264577cf..2ccdc339c 100644 --- a/src/util/vfs/vfs-mem.c +++ b/src/util/vfs/vfs-mem.c @@ -4,12 +4,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include #include struct VFileMem { struct VFile d; void* mem; size_t size; + size_t bufferSize; size_t offset; }; @@ -40,6 +42,7 @@ struct VFile* VFileFromMemory(void* mem, size_t size) { vfm->mem = mem; vfm->size = size; + vfm->bufferSize = size; vfm->offset = 0; vfm->d.close = _vfmClose; vfm->d.seek = _vfmSeek; @@ -67,6 +70,7 @@ struct VFile* VFileFromConstMemory(const void* mem, size_t size) { vfm->mem = (void*) mem; vfm->size = size; + vfm->bufferSize = size; vfm->offset = 0; vfm->d.close = _vfmClose; vfm->d.seek = _vfmSeek; @@ -89,8 +93,9 @@ struct VFile* VFileMemChunk(const void* mem, size_t size) { } vfm->size = size; + vfm->bufferSize = toPow2(size); if (size) { - vfm->mem = anonymousMemoryMap(size); + vfm->mem = anonymousMemoryMap(vfm->bufferSize); if (mem) { memcpy(vfm->mem, mem, size); } @@ -113,15 +118,19 @@ struct VFile* VFileMemChunk(const void* mem, size_t size) { } void _vfmExpand(struct VFileMem* vfm, size_t newSize) { - void* oldBuf = vfm->mem; - vfm->mem = anonymousMemoryMap(newSize); - if (oldBuf) { - if (newSize < vfm->size) { - memcpy(vfm->mem, oldBuf, newSize); - } else { - memcpy(vfm->mem, oldBuf, vfm->size); + size_t alignedSize = toPow2(newSize); + if (alignedSize > vfm->bufferSize) { + void* oldBuf = vfm->mem; + vfm->mem = anonymousMemoryMap(alignedSize); + if (oldBuf) { + if (newSize < vfm->size) { + memcpy(vfm->mem, oldBuf, newSize); + } else { + memcpy(vfm->mem, oldBuf, vfm->size); + } + mappedMemoryFree(oldBuf, vfm->bufferSize); } - mappedMemoryFree(oldBuf, vfm->size); + vfm->bufferSize = alignedSize; } vfm->size = newSize; } @@ -135,7 +144,7 @@ bool _vfmClose(struct VFile* vf) { bool _vfmCloseFree(struct VFile* vf) { struct VFileMem* vfm = (struct VFileMem*) vf; - mappedMemoryFree(vfm->mem, vfm->size); + mappedMemoryFree(vfm->mem, vfm->bufferSize); vfm->mem = 0; free(vfm); return true;