#At file:///G:/bzr/mysql-6.0-falcon-team/
2808 Vladislav Vaintroub 2008-09-03
Bug#38598 - Falcon overrides C++ new and delete operators
Problem : even with the best attempt to make Falcon-special
"global" new and delete inline and used only in Falcon-related
context ,there are compilers that would ignore this attempt
and generate a global function (SunStudio). This makes Falcon
new and delete used by C++ runtime and other storage engines,
which is bad . Especially bad for allocations/deallocations of
static objects, where Falcon allocator classes possibly do not
exist anymore.
Fix: Instead of defining global new and delete, introduce template
class Allocator with own new and delete operators. This template is
currently used to define RecordAllocator: base class for everything
related to the record cache (Record, Value and objects dynamically
allocated in Value, i.e AsciiBlob, BinaryBlob and BigInt).
There is also GeneralAllocator thought for all other classes but
currently used only as an example in Falcon SQL parser (NNode and
derivates)
modified:
storage/falcon/AsciiBlob.h
storage/falcon/BigInt.h
storage/falcon/BinaryBlob.h
storage/falcon/IO.cpp
storage/falcon/MemMgr.cpp
storage/falcon/MemMgr.h
storage/falcon/MemoryManager.h
storage/falcon/NNode.h
storage/falcon/Record.cpp
storage/falcon/Record.h
storage/falcon/Table.cpp
storage/falcon/Table.h
storage/falcon/Value.cpp
storage/falcon/Value.h
=== modified file 'storage/falcon/AsciiBlob.h'
--- a/storage/falcon/AsciiBlob.h 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/AsciiBlob.h 2008-09-02 22:41:50 +0000
@@ -34,7 +34,7 @@
class Dbb;
class Section;
-class AsciiBlob : public Clob, public Stream
+class AsciiBlob : public Clob, public Stream, public RecordAllocator
{
public:
AsciiBlob(Dbb * db, int32 recNumber, Section *blobSection);
=== modified file 'storage/falcon/BigInt.h'
--- a/storage/falcon/BigInt.h 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/BigInt.h 2008-09-02 22:41:50 +0000
@@ -24,6 +24,8 @@
#pragma once
#endif // _MSC_VER > 1000
+#include "MemoryManager.h"
+
static const int maxBigWords = 10;
static const int bigWordBits = 32;
static const int maxPowerOfTen = 65;
@@ -36,7 +38,7 @@ static const int maxPowerOfTen = 65;
typedef uint32 BigWord;
typedef uint64 BigDWord;
-class BigInt
+class BigInt: public RecordAllocator
{
public:
BigInt (BigInt *bigInt);
=== modified file 'storage/falcon/BinaryBlob.h'
--- a/storage/falcon/BinaryBlob.h 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/BinaryBlob.h 2008-09-02 22:41:50 +0000
@@ -36,7 +36,7 @@ class Dbb;
class AsciiBlob;
class Section;
-class BinaryBlob : public Blob, public Stream
+class BinaryBlob : public Blob, public Stream, public RecordAllocator
{
public:
BinaryBlob (Blob *blob);
=== modified file 'storage/falcon/IO.cpp'
--- a/storage/falcon/IO.cpp 2008-08-29 20:41:13 +0000
+++ b/storage/falcon/IO.cpp 2008-09-02 22:41:50 +0000
@@ -228,7 +228,7 @@ bool IO::createFile(const char *name)
for (int attempt = 0; attempt < 3; ++attempt)
{
fileId = ::open (fileName,
- getWriteMode(attempt) | O_CREAT | O_RDWR | O_RANDOM | O_TRUNC | O_BINARY,
+ getWriteMode(attempt) | O_CREAT | O_RDWR | O_RANDOM | O_EXCL | O_BINARY,
S_IREAD | S_IWRITE | S_IRGRP | S_IWGRP);
if (fileId >= 0)
=== modified file 'storage/falcon/MemMgr.cpp'
--- a/storage/falcon/MemMgr.cpp 2008-08-20 16:28:44 +0000
+++ b/storage/falcon/MemMgr.cpp 2008-09-02 22:41:50 +0000
@@ -127,9 +127,7 @@ struct Client {
void* MemMgrAllocateDebug (unsigned int s, const char *file, int line)
{
- if(!memoryManagerAlive)
- return malloc(s);
-
+ ASSERT(memoryManagerAlive);
void *object = memoryManager.allocateDebug(s, file, line);
if (object == stopAddress)
@@ -580,14 +578,7 @@ void MemMgr::release(void* object)
if (object)
{
MemBlock *block = (MemBlock*) ((UCHAR*) object - OFFSET(MemBlock*, body));
-
- if (block->pool == NULL)
- {
- free(block); // releaseRaw(block);
-
- return;
- }
-
+ ASSERT(block->pool == this);
block->pool->releaseBlock(block);
}
}
@@ -599,6 +590,7 @@ void MemMgr::releaseBlock(MemBlock *bloc
if (block->pool->signature != defaultSignature)
corrupt("bad block released");
+ ASSERT(block->pool == this);
#ifdef MEM_DEBUG
for (const UCHAR *end = (UCHAR*) block + ABS(block->length), *p = end - guardBytes; p < end;)
@@ -1207,3 +1199,19 @@ void MemMgr::validateBlock(MemBlock *blo
corrupt ("guard bytes overwritten");
#endif
}
+
+
+MemoryManager *getMemoryManager(AllocType type)
+{
+ switch(type)
+ {
+ case AllocTypeRecord:
+ return &memoryManager;
+ case AllocTypeGeneral:
+ return &recordManager;
+ default:
+ ASSERT(0);
+ }
+ return NULL;
+}
+
=== modified file 'storage/falcon/MemMgr.h'
--- a/storage/falcon/MemMgr.h 2008-08-06 11:53:21 +0000
+++ b/storage/falcon/MemMgr.h 2008-09-02 22:41:50 +0000
@@ -103,7 +103,7 @@ public:
MemBigHeader blocks;
};
-class MemMgr
+class MemMgr: public MemoryManager
{
public:
MemMgr(int rounding=defaultRounding, int cutoff=defaultCutoff,
@@ -159,10 +159,22 @@ public:
virtual void* memoryIsExhausted(void);
- static void release(void* block);
+ void release(void* block);
static void validate(void *object);
static void validateBlock (void *object);
+ void *memalloc(size_t size)
+ {
+ return allocate((int) size);
+ }
+ void *memalloc(size_t size, char * file, int line)
+ {
+ return allocateDebug((int)size, file, line);
+ }
+ virtual void memfree(void *p)
+ {
+ return release(p);
+ }
};
#endif
=== modified file 'storage/falcon/MemoryManager.h'
--- a/storage/falcon/MemoryManager.h 2008-05-14 18:39:57 +0000
+++ b/storage/falcon/MemoryManager.h 2008-09-02 22:41:50 +0000
@@ -16,23 +16,16 @@
#ifndef _MEMORY_MANAGER_H
#define _MEMORY_MANAGER_H
-#ifdef _WIN32
-#define THROWS_NOTHING
-#define THROWS_BAD_ALLOC
-#define WINSTATIC static
-#else
-#include <new>
-#define THROWS_NOTHING throw()
-#define THROWS_BAD_ALLOC //throw (std::bad_alloc)
-#define WINSTATIC
-#endif
-#define _MFC_OVERRIDES_NEW
+#ifndef ALWAYS_INLINE
#ifdef _WIN32
#define ALWAYS_INLINE inline /* for windows */
-#else
+#elif __GNUC__
#define ALWAYS_INLINE extern inline __attribute__ ((always_inline)) /* for gcc */
+#else
+#define ALWAYS_INLINE
+#endif
#endif
class Stream;
@@ -40,66 +33,90 @@ class InfoTable;
class MemMgr;
struct MemObject;
-#ifdef _DEBUG
- extern void* MemMgrAllocateDebug (unsigned int s, const char *file, int line);
- extern void* MemMgrPoolAllocateDebug (MemMgr *pool, unsigned int s, const char *file, int line);
-
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s) THROWS_BAD_ALLOC
- { return MemMgrAllocateDebug ((unsigned int) s, __FILE__, __LINE__); }
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s, const int &n)
- { return MemMgrAllocateDebug ((unsigned int) s, __FILE__, __LINE__); }
-
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s, const char *file, int line)
- { return MemMgrAllocateDebug ((unsigned int) s, file, line); }
-
- WINSTATIC ALWAYS_INLINE void* operator new[](size_t s) THROWS_BAD_ALLOC
- { return MemMgrAllocateDebug ((unsigned int) s, __FILE__, __LINE__); }
-
- WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, const char *file, int line) THROWS_BAD_ALLOC
- { return MemMgrAllocateDebug ((unsigned int) s, file, line); }
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s, MemMgr *pool) THROWS_BAD_ALLOC
- { return MemMgrPoolAllocateDebug (pool, (unsigned int) s, __FILE__, __LINE__); }
-
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s, MemMgr *pool, const char *file, int line)
- { return MemMgrPoolAllocateDebug (pool, (unsigned int) s, file, line); }
- WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, MemMgr *pool) THROWS_BAD_ALLOC
- { return MemMgrPoolAllocateDebug (pool, (unsigned int) s, __FILE__, __LINE__); }
-
- WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, MemMgr *pool, const char *file, int line)
- { return MemMgrPoolAllocateDebug (pool, (unsigned int) s, file, line); }
-#define POOL_NEW(arg) new(arg, THIS_FILE, __LINE__)
-#define NEW new (THIS_FILE, __LINE__)
+class MemoryManager
+{
+public:
+ virtual void *memalloc(size_t size) = 0;
+ virtual void *memalloc(size_t size, const char * file, int line)
+ {
+ return memalloc(size);
+ }
+ virtual void memfree(void *p) = 0;
+};
+
+enum AllocType
+{
+ AllocTypeGeneral = 0,
+ AllocTypeRecord = 1
+};
+
+extern MemoryManager *getMemoryManager(AllocType type);
+
+template<AllocType type> class Allocator
+{
+public:
+ static void* operator new(size_t size)
+ {
+ return getMemoryManager(type)->memalloc(size);
+ }
+
+ static void operator delete(void *p)
+ {
+ getMemoryManager(type)->memfree(p);
+ }
+
+ static ALWAYS_INLINE void* operator new(size_t size, const char * file, int line)
+ {
+ return getMemoryManager(type)->memalloc(size, file, line);
+ }
+
+ static void* operator new[](size_t size)
+ {
+ return getMemoryManager(type)->memalloc(size);
+ };
+ static void* operator new[](size_t size, const char *file, int line)
+ {
+ return getMemoryManager(type)->memalloc(size, file, line);
+ }
+
+ static void operator delete(void *p, const char *file, int line)
+ {
+ return getMemoryManager(type)->memfree(p);
+ }
+
+ static void operator delete[](void *p)
+ {
+ getMemoryManager(type)->memfree(p);
+ }
+ static void operator delete[](void *p, const char *file, int line)
+ {
+ getMemoryManager(type)->memfree(p);
+ }
+ static void *malloc(size_t size)
+ {
+ return getMemoryManager(type)->memalloc(size);
+ }
+ static void *malloc(size_t size, const char *file, int line)
+ {
+ return getMemoryManager(type)->memalloc(size,file, line);
+ }
+ static void free(void *p)
+ {
+ getMemoryManager(type)->memfree(p);
+ }
-#ifndef new
-#define new NEW
-#endif
+};
-#else
- extern void* MemMgrAllocate (unsigned int s);
- extern void* MemMgrPoolAllocate (MemMgr *pool, unsigned int s);
-
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s) THROWS_BAD_ALLOC
- { return MemMgrAllocate (s); }
-
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s, MemMgr *pool) THROWS_BAD_ALLOC
- { return ::MemMgrPoolAllocate (pool, s); }
+typedef Allocator<AllocTypeRecord> RecordAllocator;
+typedef Allocator<AllocTypeGeneral> GeneralAllocator;
- WINSTATIC ALWAYS_INLINE void* operator new[](size_t s, MemMgr *pool) THROWS_BAD_ALLOC
- { return ::MemMgrPoolAllocate (pool, s); }
+#define NEW new
- WINSTATIC ALWAYS_INLINE void* operator new(size_t s, const int &n) THROWS_BAD_ALLOC
- { return ::MemMgrAllocate (s); }
- WINSTATIC ALWAYS_INLINE void* operator new[](size_t s) THROWS_BAD_ALLOC
- { return ::MemMgrAllocate (s); }
-
-#define POOL_NEW(arg) new(arg)
-#define NEW new
-#endif
enum MemMgrWhat {
MemMgrSystemSummary,
@@ -120,27 +137,7 @@ extern void* MemMgrRecordAllocate (int s
extern void MemMgrRecordDelete (char *record);
extern void MemMgrSetMaxRecordMember (long long size);
extern MemMgr* MemMgrGetFixedPool (int id);
-
extern MemObject* MemMgrFindPriorBlock (void *block);
-
-WINSTATIC ALWAYS_INLINE void operator delete(void *object) THROWS_NOTHING
- { MemMgrRelease (object); }
-
-WINSTATIC ALWAYS_INLINE void operator delete(void *object, const char *file, int line)
- { MemMgrRelease (object); }
-
-WINSTATIC ALWAYS_INLINE void operator delete[](void *object) THROWS_NOTHING
- { MemMgrRelease (object); }
-
-WINSTATIC ALWAYS_INLINE void operator delete[](void *object, const char *file, int line)
- { MemMgrRelease (object); }
-
-WINSTATIC ALWAYS_INLINE void operator delete(void *object, MemMgr *pool) THROWS_NOTHING
- { MemMgrRelease (object); }
-
-WINSTATIC ALWAYS_INLINE void operator delete(void *object, MemMgr *pool, const char *file, int line)
- { MemMgrRelease (object); }
-
extern void MemMgrValidate ();
#endif
=== modified file 'storage/falcon/NNode.h'
--- a/storage/falcon/NNode.h 2007-09-20 15:44:25 +0000
+++ b/storage/falcon/NNode.h 2008-09-02 22:41:50 +0000
@@ -112,7 +112,7 @@ enum NType {
Lower,
};
-class NNode
+class NNode: public GeneralAllocator
{
public:
virtual bool isUniqueIndex();
=== modified file 'storage/falcon/Record.cpp'
--- a/storage/falcon/Record.cpp 2008-05-09 19:58:50 +0000
+++ b/storage/falcon/Record.cpp 2008-09-02 22:41:50 +0000
@@ -36,6 +36,7 @@
#include "EncodedRecord.h"
#include "Field.h"
#include "Serialize.h"
+#include "MemoryManager.h"
#undef new
@@ -918,7 +919,7 @@ char* Record::allocRecordData(int length
for (int n = 0;; ++n)
try
{
- return POOL_NEW(format->table->database->recordDataPool) char[length];
+ return (char *)RecordAllocator::malloc(length);
}
catch (SQLException& exception)
{
=== modified file 'storage/falcon/Record.h'
--- a/storage/falcon/Record.h 2008-05-09 19:58:50 +0000
+++ b/storage/falcon/Record.h 2008-09-02 22:41:50 +0000
@@ -23,9 +23,9 @@
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
-
-#define ALLOCATE_RECORD(n) (char*) MemMgrRecordAllocate (n, __FILE__, __LINE__)
-#define DELETE_RECORD(record) MemMgrRecordDelete (record);
+#include "MemoryManager.h"
+#define ALLOCATE_RECORD(n) (char*) RecordAllocator::malloc(n, __FILE__, __LINE__)
+#define DELETE_RECORD(record) RecordAllocator::free(record);
#define CHECK_RECORD_ACTIVITY
@@ -65,10 +65,8 @@ class Serialize;
class SyncObject;
CLASS(Field);
-extern char *RecordAllocate (int size, const char *file, int line);
-extern void RecordDelete (char *record);
-class Record
+class Record: public RecordAllocator
{
public:
virtual Transaction* getTransaction();
=== modified file 'storage/falcon/Table.cpp'
--- a/storage/falcon/Table.cpp 2008-08-18 05:45:29 +0000
+++ b/storage/falcon/Table.cpp 2008-09-02 22:41:50 +0000
@@ -120,8 +120,6 @@ Table::~Table()
formats [n] = format->hash;
delete format;
}
-
- delete [] formats;
for (Index *index; (index = indexes);)
{
@@ -840,7 +838,6 @@ void Table::init(int id, const char *sch
markedForDelete = false;
activeVersions = false;
primaryKey = NULL;
- formats = NEW Format* [FORMAT_HASH_SIZE];
static char name[SYNC_VERSIONS_SIZE][64];
for (int n = 0; n < SYNC_VERSIONS_SIZE; n++)
@@ -3646,7 +3643,7 @@ RecordVersion* Table::allocRecordVersion
for (int n = 0;; ++n)
try
{
- return POOL_NEW(database->recordDataPool) RecordVersion(this, format, transaction, priorVersion);
+ return new RecordVersion(this, format, transaction, priorVersion);
}
catch (SQLException& exception)
{
@@ -3664,7 +3661,7 @@ Record* Table::allocRecord(int recordNum
for (int n = 0;; ++n)
try
{
- return POOL_NEW(database->recordDataPool) Record (this, recordNumber, stream);
+ return new Record (this, recordNumber, stream);
}
catch (SQLException& exception)
{
=== modified file 'storage/falcon/Table.h'
--- a/storage/falcon/Table.h 2008-08-18 05:45:29 +0000
+++ b/storage/falcon/Table.h 2008-09-02 22:41:50 +0000
@@ -239,7 +239,7 @@ public:
Index *indexes;
ForeignKey *foreignKeys;
LinkedList attachments;
- Format **formats;
+ Format *formats[FORMAT_HASH_SIZE];
Format *format;
RecordSection *records;
Index *primaryKey;
=== modified file 'storage/falcon/Value.cpp'
--- a/storage/falcon/Value.cpp 2008-04-28 20:47:43 +0000
+++ b/storage/falcon/Value.cpp 2008-09-02 22:41:50 +0000
@@ -91,7 +91,7 @@ void Value::setString(const char * strin
if (copy)
{
- data.string.string = new char [data.string.length + 1];
+ data.string.string = (char *)RecordAllocator::malloc(data.string.length + 1);
strcpy(data.string.string, string);
}
else
@@ -194,7 +194,7 @@ void Value::setString(int length, const
if (copy)
{
- data.string.string = new char [length + 1];
+ data.string.string = (char *)RecordAllocator::malloc(length + 1);
memcpy(data.string.string, string, length);
data.string.string [length] = 0;
}
@@ -217,7 +217,7 @@ void Value::setString(const WCString *va
copyFlag = true;
data.string.length = Unicode::getUtf8Length(value->count, value->string);
- char *p = data.string.string = new char [data.string.length + 1];
+ char *p = data.string.string = (char *)RecordAllocator::malloc(data.string.length + 1);
Unicode::convert(value->count, value->string, p);
p[data.string.length] = 0;
}
@@ -775,7 +775,7 @@ const char* Value::getString(char **temp
if (data.string.string [data.string.length] == 0)
return data.string.string;
- *tempPtr = new char [data.string.length + 1];
+ *tempPtr = (char *)RecordAllocator::malloc(data.string.length + 1);
memcpy(*tempPtr, data.string.string, data.string.length);
(*tempPtr)[data.string.length] = 0;
@@ -820,7 +820,7 @@ const char* Value::getString(char **temp
if (length < 0)
throw SQLError(LOST_BLOB, "repository blob has been lost");
- *tempPtr = new char [length + 1];
+ *tempPtr = (char *)RecordAllocator::malloc(length + 1);
data.blob->getBytes(0, length, *tempPtr);
(*tempPtr) [length] = 0;
@@ -837,7 +837,7 @@ const char* Value::getString(char **temp
if (length < 0)
throw SQLError(LOST_BLOB, "repository blob has been lost");
- *tempPtr = new char [length + 1];
+ *tempPtr = (char *)RecordAllocator::malloc(length + 1);
data.clob->getSubString(0, length, *tempPtr);
(*tempPtr) [length] = 0;
@@ -855,9 +855,9 @@ const char* Value::getString(char **temp
UIPTR length = strlen(temp);
if (*tempPtr)
- delete *tempPtr;
+ RecordAllocator::free(*tempPtr);
- *tempPtr = new char [length + 1];
+ *tempPtr = (char *)RecordAllocator::malloc(length + 1);
strcpy(*tempPtr, temp);
return *tempPtr;
@@ -1074,7 +1074,7 @@ char* Value::allocString(Type typ, int l
clear();
type = typ;
data.string.length = length;
- data.string.string = new char [length + 1];
+ data.string.string = (char *)RecordAllocator::malloc(length + 1);
data.string.string [length] = 0;
return data.string.string;
=== modified file 'storage/falcon/Value.h'
--- a/storage/falcon/Value.h 2008-02-13 20:22:39 +0000
+++ b/storage/falcon/Value.h 2008-09-02 22:41:50 +0000
@@ -32,11 +32,12 @@
#include "Stream.h"
#include "BigInt.h"
#include "Blob.h"
+#include "MemoryManager.h"
class Blob;
class Clob;
-class Value
+class Value: public RecordAllocator
{
public:
Value (const char *string);
@@ -120,7 +121,7 @@ public:
case Varchar:
if (copyFlag && data.string.string)
{
- delete [] data.string.string;
+ RecordAllocator::free(data.string.string);
data.string.string = NULL;
}
break;
Thread |
---|
• bzr commit into mysql-6.0-falcon branch (vvaintroub:2808) Bug#38598 | Vladislav Vaintroub | 3 Sep |