mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-09-21 20:06:40 +00:00
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.
This commit is contained in:
@@ -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)
|
||||
|
||||
+3
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 <boost/filesystem.hpp>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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<UnalignedWriter> PUnalignedWriter;
|
||||
|
||||
#endif // #ifndef INCLUDED_WRITE_BUFFER
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user