From 028a92375fa6fc0d1f0ee23311ee55c8d2c041c9 Mon Sep 17 00:00:00 2001 From: janwas Date: Mon, 16 Jun 2008 18:36:36 +0000 Subject: [PATCH] fixes from work: - aligned_allocator.h: use _mm_malloc instead of _aligned_malloc (somewhat more portable) bits: fix incorrect handling of bit_mask(0) - archive_zip.cpp: fix ArchiveWriter_Zip (wasn't opening its output file, ECDR record wasn't at end of file due to padding) - io_align.cpp: move routines to header (DLL export) - wdbg_heap.cpp: avoid crash in report hook if CRT memory block is invalid This was SVN commit r6030. --- source/lib/allocators/aligned_allocator.h | 4 +-- source/lib/bits.h | 4 ++- source/lib/file/archive/archive_zip.cpp | 23 +++++++++---- source/lib/file/archive/archive_zip.h | 4 +-- source/lib/file/io/io_align.cpp | 21 ------------ source/lib/file/io/io_align.h | 22 +++++++++--- source/lib/file/io/write_buffer.h | 12 ++++--- source/lib/sysdep/win/wdbg_heap.cpp | 42 ++++++++++++++--------- 8 files changed, 74 insertions(+), 58 deletions(-) diff --git a/source/lib/allocators/aligned_allocator.h b/source/lib/allocators/aligned_allocator.h index c1d42b5b6a..b74018bdfa 100644 --- a/source/lib/allocators/aligned_allocator.h +++ b/source/lib/allocators/aligned_allocator.h @@ -93,14 +93,14 @@ public: const size_type alignment = x86_x64_L1CacheLineSize(); const size_type elementSize = round_up(sizeof(T), alignment); const size_type size = numElements * elementSize; - pointer p = (pointer)_aligned_malloc(size, alignment); + pointer p = (pointer)_mm_malloc(size, alignment); return p; } // deallocate storage of elements that have been destroyed void deallocate(pointer p, size_type num) { - _aligned_free((void*)p); + _mm_free((void*)p); } void construct(pointer p, const T& value) diff --git a/source/lib/bits.h b/source/lib/bits.h index a330e1073d..92a5afb27e 100644 --- a/source/lib/bits.h +++ b/source/lib/bits.h @@ -51,7 +51,9 @@ T bit_mask(size_t numBits) // note: the perhaps more intuitive (1 << numBits)-1 cannot // handle numBits == bitsInT, but this implementation does. const T bitsInT = sizeof(T)*CHAR_BIT; - return ~T(0) >> T(bitsInT-numBits); + T mask = ~T(0); + mask >>= T(bitsInT-numBits); + return mask; } diff --git a/source/lib/file/archive/archive_zip.cpp b/source/lib/file/archive/archive_zip.cpp index cc2d2bdff4..b8fbcc947b 100644 --- a/source/lib/file/archive/archive_zip.cpp +++ b/source/lib/file/archive/archive_zip.cpp @@ -503,7 +503,8 @@ class ArchiveWriter_Zip : public IArchiveWriter { public: ArchiveWriter_Zip(const Path& archivePathname) - : m_fileSize(0), m_unalignedWriter(m_file, 0) + : m_file(CreateFile_Posix()), m_fileSize(0) + , m_unalignedWriter(new UnalignedWriter(m_file, 0)) , m_numEntries(0) { THROW_ERR(m_file->Open(archivePathname, 'w')); @@ -518,12 +519,20 @@ public: ECDR* ecdr = (ECDR*)pool_alloc(&m_cdfhPool, sizeof(ECDR)); if(!ecdr) throw std::bad_alloc(); - ecdr->Init(m_numEntries, m_fileSize, cd_size); + const size_t cd_ofs = m_fileSize; + ecdr->Init(m_numEntries, cd_ofs, cd_size); - m_unalignedWriter.Append(m_cdfhPool.da.base, cd_size+sizeof(ECDR)); - m_unalignedWriter.Flush(); + m_unalignedWriter->Append(m_cdfhPool.da.base, cd_size+sizeof(ECDR)); + m_unalignedWriter->Flush(); + m_unalignedWriter.reset(); (void)pool_destroy(&m_cdfhPool); + + const Path pathname = m_file->Pathname(); + m_file.reset(); + + m_fileSize += cd_size+sizeof(ECDR); + truncate(pathname.string().c_str(), m_fileSize); } LibError AddFile(const Path& pathname) @@ -597,12 +606,12 @@ public: // write LFH, pathname and cdata to file const size_t packageSize = sizeof(LFH) + pathnameLength + csize; - RETURN_ERR(m_unalignedWriter.Append(buf.get(), (off_t)packageSize)); + RETURN_ERR(m_unalignedWriter->Append(buf.get(), (off_t)packageSize)); m_fileSize += (off_t)packageSize; return INFO::OK; } -#include + private: static bool IsFileTypeIncompressible(const Path& pathname) { @@ -627,7 +636,7 @@ private: PIFile m_file; off_t m_fileSize; - UnalignedWriter m_unalignedWriter; + PUnalignedWriter m_unalignedWriter; Pool m_cdfhPool; size_t m_numEntries; diff --git a/source/lib/file/archive/archive_zip.h b/source/lib/file/archive/archive_zip.h index ffd1c641fa..48dd0b15e1 100644 --- a/source/lib/file/archive/archive_zip.h +++ b/source/lib/file/archive/archive_zip.h @@ -13,7 +13,7 @@ #include "archive.h" -PIArchiveReader CreateArchiveReader_Zip(const Path& archivePathname); -PIArchiveWriter CreateArchiveWriter_Zip(const Path& archivePathname); +LIB_API PIArchiveReader CreateArchiveReader_Zip(const Path& archivePathname); +LIB_API PIArchiveWriter CreateArchiveWriter_Zip(const Path& archivePathname); #endif // #ifndef INCLUDED_ARCHIVE_ZIP diff --git a/source/lib/file/io/io_align.cpp b/source/lib/file/io/io_align.cpp index a6869c0bc4..fe425a9ae3 100644 --- a/source/lib/file/io/io_align.cpp +++ b/source/lib/file/io/io_align.cpp @@ -1,23 +1,2 @@ #include "precompiled.h" #include "io_align.h" - - -bool IsAligned_Offset(off_t ofs) -{ - return IsAligned(ofs, BLOCK_SIZE); -} - -off_t AlignedOffset(off_t ofs) -{ - return round_down(ofs, (off_t)BLOCK_SIZE); -} - -off_t AlignedSize(off_t size) -{ - return round_up(size, (off_t)BLOCK_SIZE); -} - -off_t PaddedSize(off_t size, off_t ofs) -{ - return round_up(size + ofs - AlignedOffset(ofs), (off_t)BLOCK_SIZE); -} diff --git a/source/lib/file/io/io_align.h b/source/lib/file/io/io_align.h index 9c4cba9e8b..76e0becfa1 100644 --- a/source/lib/file/io/io_align.h +++ b/source/lib/file/io/io_align.h @@ -25,11 +25,25 @@ bool IsAligned_Data(T* address) return IsAligned((uintptr_t)address, SECTOR_SIZE); } -extern bool IsAligned_Offset(off_t ofs); +static bool IsAligned_Offset(off_t ofs) +{ + return IsAligned(ofs, BLOCK_SIZE); +} -extern off_t AlignedOffset(off_t ofs); -extern off_t AlignedSize(off_t size); -extern off_t PaddedSize(off_t size, off_t ofs); +static off_t AlignedOffset(off_t ofs) +{ + return round_down(ofs, (off_t)BLOCK_SIZE); +} + +static off_t AlignedSize(off_t size) +{ + return round_up(size, (off_t)BLOCK_SIZE); +} + +static off_t PaddedSize(off_t size, off_t ofs) +{ + return round_up(size + ofs - AlignedOffset(ofs), (off_t)BLOCK_SIZE); +} #endif // #ifndef INCLUDED_IO_ALIGN diff --git a/source/lib/file/io/write_buffer.h b/source/lib/file/io/write_buffer.h index 7ae1fe9009..cde4b9accf 100644 --- a/source/lib/file/io/write_buffer.h +++ b/source/lib/file/io/write_buffer.h @@ -36,14 +36,14 @@ public: ~UnalignedWriter(); /** - * add data to the align buffer, writing it out to disk if full. - **/ + * add data to the align buffer, writing it out to disk if full. + **/ LibError Append(const u8* data, size_t size) const; /** - * zero-initialize any remaining space in the align buffer and write - * it to the file. this is called by the destructor. - **/ + * zero-initialize any remaining space in the align buffer and write + * it to the file. this is called by the destructor. + **/ void Flush() const; private: @@ -55,4 +55,6 @@ private: mutable size_t m_bytesUsed; }; +typedef shared_ptr PUnalignedWriter; + #endif // #ifndef INCLUDED_WRITE_BUFFER diff --git a/source/lib/sysdep/win/wdbg_heap.cpp b/source/lib/sysdep/win/wdbg_heap.cpp index daf084b43b..9c27fe8eec 100644 --- a/source/lib/sysdep/win/wdbg_heap.cpp +++ b/source/lib/sysdep/win/wdbg_heap.cpp @@ -839,35 +839,45 @@ static int __cdecl ReportHook(int reportType, char* message, int* out) static enum { WaitingForDump, - WaitingForLeakAddress, - IsLeakAddress + WaitingForBlock, + IsBlock } state = WaitingForDump; switch(state) { case WaitingForDump: if(!strcmp(message, "Dumping objects ->\n")) - state = WaitingForLeakAddress; + state = WaitingForBlock; return ret; - case WaitingForLeakAddress: + case IsBlock: + { + // common case: "normal block at 0xPPPPPPPP, N bytes long". + const char* addressString = strstr(message, "0x"); + if(addressString) + { + const uintptr_t address = strtoul(addressString, 0, 0); + _CrtMemBlockHeader* header = HeaderFromData((void*)address); + uintptr_t callers[maxCallers]; size_t numCallers; + RetrieveCallers(header, callers, numCallers); + PrintCallStack(callers, numCallers); + + state = WaitingForBlock; + return ret; + } + // else: for reasons unknown, there's apparently no information + // about the block; fall through to the previous state. + } + + case WaitingForBlock: if(message[0] == '{') - state = IsLeakAddress; + state = IsBlock; + // suppress messages containing "file" and "line" since the normal + // interpretation of those header fields is invalid. else if(strchr(message, '(')) message[0] = '\0'; return ret; - case IsLeakAddress: - { - const char* addressString = strstr(message, "0x"); - const uintptr_t address = strtoul(addressString, 0, 0); - _CrtMemBlockHeader* header = HeaderFromData((void*)address); - uintptr_t callers[maxCallers]; size_t numCallers; - RetrieveCallers(header, callers, numCallers); - PrintCallStack(callers, numCallers); - } - state = WaitingForLeakAddress; - return ret; default: wdbg_assert(0); // unreachable