On 16.04.2018 15:08, Stephan Bergmann wrote:
On 17/02/17 11:48, Alex Peshkoff wrote:
On 02/16/17 15:52, Stephan Bergmann wrote:
Forgive me if this has already been discussed or even fixed in later
versions: At least the Firebird 3.0 we build as part of LibreOffice
defines global operator new replacement functions in
src/common/classes/alloc.h (forwarding to MemoryPool) that do not in
general fulfil the alignment requirements for such functions.
Came across this when Firebird compiled with a recent trunk Clang (with
-O, and DEBUG_GDS_ALLOC being undefined) on x86_64-unknown-linux-gnu
causes SEGV from misaligned MOVAPS instructions.
Yes - allocated memory is aligned at 8 bytes boundary now.
I've tried to set alignment to 16 but looks like that's far not 5 lines
patch - sometimes we were choosing between 4/8 bytes alignment, but last
years only 8 bytes alignment was used.
May be finding specific compiler flag to avoid this instruction is
simpler choice for today?
Has this meanwhile been addressed in Firebird? LibreOffice still uses
Firebird 3.0.0, and the issue I've described now also hits with recent
Apple Xcode Clang on macOS (see
<https://gerrit.libreoffice.org/#/c/52956/> "external/firebird: Better
workaround for Clang alignment expectations").
The issue is fixed in master branch (fb4). Not sure that we are ready to
change memory allocator in FB3 but patch needed for it is here. It's
from master but applies fine to 3.0 too. Tracker item is
http://tracker.firebirdsql.org/browse/CORE-5865
BTW - you say you still use Firebird 3.0.0. If it's not mistype that's
far not best choice - first release is last beta :). Current stable
3.0.3 is much better.
A.
diff --git a/src/common/classes/alloc.cpp b/src/common/classes/alloc.cpp
index 63250ae..1a8ae99 100644
--- a/src/common/classes/alloc.cpp
+++ b/src/common/classes/alloc.cpp
@@ -99,7 +99,7 @@ static void* stopAddress = (void*) 0x2254938;
#endif
#ifdef MEM_DEBUG
-static const int GUARD_BYTES = Firebird::ALLOC_ALIGNMENT; // * 2048;
+static const int GUARD_BYTES = ALLOC_ALIGNMENT; // * 2048;
static const UCHAR INIT_BYTE = 0xCC;
static const UCHAR GUARD_BYTE = 0xDD;
static const UCHAR DEL_BYTE = 0xEE;
@@ -218,7 +218,7 @@ namespace SemiDoubleLink
#ifdef USE_VALGRIND
// Size of Valgrind red zone applied before and after memory block allocated for user
-#define VALGRIND_REDZONE 8
+#define VALGRIND_REDZONE MEM_ALIGN
#undef MEM_DEBUG // valgrind works instead
#else
#define VALGRIND_REDZONE 0
@@ -253,6 +253,8 @@ public:
#ifdef DEBUG_GDS_ALLOC
INT32 lineNumber;
const char *fileName;
+#elif (SIZEOF_VOID_P == 4) && (ALLOC_ALIGNMENT == 16)
+ FB_UINT64 dummyAlign;
#endif
#if defined(USE_VALGRIND) && (VALGRIND_REDZONE != 0)
char mbk_valgrind_redzone[VALGRIND_REDZONE];
@@ -540,10 +542,11 @@ public:
MemBigHunk* next;
MemBigHunk** prev;
const size_t length;
- MemBlock block;
+ MemBlock* block;
MemBigHunk(MemBigHunk** top, size_t l)
- : next(NULL), prev(NULL), length(l), block(MemBlock::HUGE_BLOCK, length - hdrSize())
+ : next(NULL), prev(NULL), length(l),
+ block(new(((UCHAR*) this) + hdrSize()) MemBlock(MemBlock::HUGE_BLOCK, length - hdrSize()))
{
SemiDoubleLink::push(top, this);
}
@@ -553,8 +556,8 @@ public:
const char* filter_path, const size_t filter_len) FB_NOTHROW
{
fprintf(file, "Big hunk %p: memory=%p length=%" SIZEFORMAT "\n",
- this, &block, length);
- block.print_contents(true, file, used_only, filter_path, filter_len);
+ this, block, length);
+ block->print_contents(true, file, used_only, filter_path, filter_len);
if (next)
next->print_contents(file, pool, used_only, filter_path, filter_len);
}
@@ -562,20 +565,21 @@ public:
static size_t hdrSize()
{
- return offsetof(MemBigHunk, block);
+ return MEM_ALIGN(sizeof(MemBigHunk));
}
void validate()
{
SemiDoubleLink::validate(this);
- block.assertBig();
- fb_assert(block.getSize() + hdrSize() == length);
+ block->assertBig();
+ fb_assert(block->getSize() + hdrSize() == length);
}
};
enum GetSlotFor { SLOT_ALLOC, SLOT_FREE };
+#if ALLOC_ALIGNMENT == 8
const unsigned char lowSlots[] =
{
0, // 24
@@ -739,6 +743,106 @@ const unsigned short lowLimits[] =
1024, // 28
};
+const int SLOT_SHIFT = 3;
+#elif ALLOC_ALIGNMENT == 16
+const unsigned char lowSlots[] =
+{
+ 0, // 32
+ 1, // 48
+ 2, // 64
+ 3, // 80
+ 4, // 96
+ 5, // 112
+ 6, // 128
+ 7, // 144
+ 8, // 160
+ 9, // 176
+ 9, // 192
+ 10, // 208
+ 10, // 224
+ 11, // 240
+ 11, // 256
+ 12, // 272
+ 12, // 288
+ 13, // 304
+ 13, // 320
+ 14, // 336
+ 14, // 352
+ 14, // 368
+ 15, // 384
+ 15, // 400
+ 15, // 416
+ 16, // 432
+ 16, // 448
+ 16, // 464
+ 17, // 480
+ 17, // 496
+ 17, // 512
+ 17, // 528
+ 18, // 544
+ 18, // 560
+ 18, // 576
+ 18, // 592
+ 19, // 608
+ 19, // 624
+ 19, // 640
+ 19, // 656
+ 19, // 672
+ 20, // 688
+ 20, // 704
+ 20, // 720
+ 20, // 736
+ 20, // 752
+ 21, // 768
+ 21, // 784
+ 21, // 800
+ 21, // 816
+ 21, // 832
+ 21, // 848
+ 22, // 864
+ 22, // 880
+ 22, // 896
+ 22, // 912
+ 22, // 928
+ 22, // 944
+ 23, // 960
+ 23, // 976
+ 23, // 992
+ 23, // 1008
+ 23, // 1024
+};
+
+const unsigned short lowLimits[] =
+{
+ 32, // 0
+ 48, // 1
+ 64, // 2
+ 80, // 3
+ 96, // 4
+ 112, // 5
+ 128, // 6
+ 144, // 7
+ 160, // 8
+ 192, // 9
+ 224, // 10
+ 256, // 11
+ 288, // 12
+ 320, // 13
+ 368, // 14
+ 416, // 15
+ 464, // 16
+ 528, // 17
+ 592, // 18
+ 672, // 19
+ 752, // 20
+ 848, // 21
+ 944, // 22
+ 1024, // 23
+};
+
+const int SLOT_SHIFT = 4;
+#endif
+
const size_t TINY_SLOTS = FB_NELEM(lowLimits);
const unsigned short* TINY_BLOCK_LIMIT = &lowLimits[TINY_SLOTS - 1];
@@ -747,7 +851,11 @@ const unsigned short* TINY_BLOCK_LIMIT = &lowLimits[TINY_SLOTS - 1];
class LowLimits
{
public:
+#if ALLOC_ALIGNMENT == 8
static const unsigned TOTAL_ELEMENTS = 29; // TINY_SLOTS
+#elif ALLOC_ALIGNMENT == 16
+ static const unsigned TOTAL_ELEMENTS = 24; // TINY_SLOTS
+#endif
static const unsigned TOP_LIMIT = 1024; // TINY_BLOCK_LIMIT
static unsigned getSlot(size_t size, GetSlotFor mode)
@@ -762,7 +870,7 @@ public:
size = LOW_LIMIT;
fb_assert(MEM_ALIGN(size) == size);
- unsigned slot = lowSlots[(size - LOW_LIMIT) >> 3];
+ unsigned slot = lowSlots[(size - LOW_LIMIT) >> SLOT_SHIFT];
fb_assert(size <= lowLimits[slot]);
if (lowLimits[slot] > size && mode == SLOT_FREE)
{
@@ -1548,7 +1656,7 @@ public:
private:
static const size_t minAllocation = 65536;
- static const size_t roundingSize = 8;
+ static const size_t roundingSize = ALLOC_ALIGNMENT;
FreeObjects<LinkedList, LowLimits> smallObjects;
Vector<MemBlock*, 16> parentRedirected;
@@ -1868,6 +1976,7 @@ void MemoryPool::cleanup()
MemPool::MemPool()
: pool_destroying(false), parent_redirect(false), stats(MemoryPool::default_stats_group), parent(NULL)
{
+ fb_assert(offsetof(MemBlock, body) == MEM_ALIGN(offsetof(MemBlock, body)));
initialize();
}
@@ -2080,7 +2189,7 @@ MemBlock* MemPool::alloc(size_t from, size_t& length, bool flagRedirect) FB_THRO
// Allocate the new hunk
MemBigHunk* hunk = new(allocRaw(hunkLength)) MemBigHunk(&bigHunks, hunkLength);
- return &hunk->block;
+ return hunk->block;
}
MemBlock* MemPool::allocate2(size_t from, size_t& size
@@ -2112,6 +2221,7 @@ MemBlock* MemPool::allocate2(size_t from, size_t& size
++blocksAllocated;
++blocksActive;
+ fb_assert((U_IPTR)(&memory->body) % ALLOC_ALIGNMENT == 0);
return memory;
}
diff --git a/src/common/classes/alloc.h b/src/common/classes/alloc.h
index e04520f..9e92570 100644
--- a/src/common/classes/alloc.h
+++ b/src/common/classes/alloc.h
@@ -79,7 +79,7 @@
namespace Firebird {
// Alignment for all memory blocks
-const size_t ALLOC_ALIGNMENT = 8;
+#define ALLOC_ALIGNMENT 16
static inline size_t MEM_ALIGN(size_t value)
{
diff --git a/src/common/classes/misc/lowtab.c b/src/common/classes/misc/lowtab.c
index 1aa02d0..8529881 100644
--- a/src/common/classes/misc/lowtab.c
+++ b/src/common/classes/misc/lowtab.c
@@ -27,13 +27,13 @@
#include <stdio.h>
-main(int ac, char** av)
+int main(int ac, char** av)
{
int mode = ac < 2 ? 0 : ((*av[1]) - '0');
- int cur = 24;
+ int cur = 32;
int prev = 0;
- const int dstep = 8;
+ const int dstep = 16;
int limit = 1024;
int slot = 0;
@@ -55,4 +55,6 @@ main(int ac, char** av)
if (mode == 1)
printf ("\t%d, // %d\n", cur, slot);
+
+ return 0;
}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
Firebird-Devel mailing list, web interface at
https://lists.sourceforge.net/lists/listinfo/firebird-devel