List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:September 2 2008 10:42pm
Subject:bzr commit into mysql-6.0-falcon branch (vvaintroub:2808) Bug#38598
View as plain text  
#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#38598Vladislav Vaintroub3 Sep