[cfe-commits] r39078 - in /cfe/cfe/trunk: Lex/IdentifierTable.cpp include/clang/Lex/IdentifierTable.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:27:21 PDT 2007
Author: sabre
Date: Wed Jul 11 11:27:21 2007
New Revision: 39078
URL: http://llvm.org/viewvc/llvm-project?rev=39078&view=rev
Log:
move memory allocation abstraction stuff out into LLVM's libsupport
Modified:
cfe/cfe/trunk/Lex/IdentifierTable.cpp
cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
Modified: cfe/cfe/trunk/Lex/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Lex/IdentifierTable.cpp?rev=39078&r1=39077&r2=39078&view=diff
==============================================================================
--- cfe/cfe/trunk/Lex/IdentifierTable.cpp (original)
+++ cfe/cfe/trunk/Lex/IdentifierTable.cpp Wed Jul 11 11:27:21 2007
@@ -1,4 +1,4 @@
-//===--- Preprocess.cpp - C Language Family Preprocessor Implementation ---===//
+//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -45,85 +45,11 @@
IdentifierVisitor::~IdentifierVisitor() {
}
-//===----------------------------------------------------------------------===//
-// Memory Allocation Support
-//===----------------------------------------------------------------------===//
-
-/// The identifier table has a very simple memory allocation pattern: it just
-/// keeps allocating identifiers, then never frees them unless it frees them
-/// all. As such, we use a simple bump-pointer memory allocator to make
-/// allocation speedy. Shark showed that malloc was 27% of the time spent in
-/// IdentifierTable::getIdentifier with malloc, and takes a 4.3% time with this.
-#define USE_ALLOCATOR 1
-#if USE_ALLOCATOR
-
-namespace {
-class MemRegion {
- unsigned RegionSize;
- MemRegion *Next;
- char *NextPtr;
-public:
- void Init(unsigned size, MemRegion *next) {
- RegionSize = size;
- Next = next;
- NextPtr = (char*)(this+1);
-
- // FIXME: uses GCC extension.
- unsigned Alignment = __alignof__(IdentifierInfo);
- NextPtr = (char*)((intptr_t)(NextPtr+Alignment-1) &
- ~(intptr_t)(Alignment-1));
- }
-
- const MemRegion *getNext() const { return Next; }
- unsigned getNumBytesAllocated() const {
- return NextPtr-(const char*)this;
- }
-
- /// Allocate - Allocate and return at least the specified number of bytes.
- ///
- void *Allocate(unsigned AllocSize, MemRegion **RegPtr) {
- // FIXME: uses GCC extension.
- unsigned Alignment = __alignof__(IdentifierInfo);
- // Round size up to an even multiple of the alignment.
- AllocSize = (AllocSize+Alignment-1) & ~(Alignment-1);
-
- // If there is space in this region for the identifier, return it.
- if (unsigned(NextPtr+AllocSize-(char*)this) <= RegionSize) {
- void *Result = NextPtr;
- NextPtr += AllocSize;
- return Result;
- }
-
- // Otherwise, we have to allocate a new chunk. Create one twice as big as
- // this one.
- MemRegion *NewRegion = (MemRegion *)malloc(RegionSize*2);
- NewRegion->Init(RegionSize*2, this);
-
- // Update the current "first region" pointer to point to the new region.
- *RegPtr = NewRegion;
-
- // Try allocating from it now.
- return NewRegion->Allocate(AllocSize, RegPtr);
- }
-
- /// Deallocate - Release all memory for this region to the system.
- ///
- void Deallocate() {
- MemRegion *next = Next;
- free(this);
- if (next)
- next->Deallocate();
- }
-};
-}
-
-#endif
//===----------------------------------------------------------------------===//
// IdentifierTable Implementation
//===----------------------------------------------------------------------===//
-
/// IdentifierBucket - The hash table consists of an array of these. If Info is
/// non-null, this is an extant entry, otherwise, it is a hole.
struct IdentifierBucket {
@@ -142,10 +68,6 @@
TheTable = TableArray;
NumIdentifiers = 0;
-#if USE_ALLOCATOR
- TheMemory = malloc(8*4096);
- ((MemRegion*)TheMemory)->Init(8*4096, 0);
-#endif
// Populate the identifier table with info about keywords for the current
// language.
@@ -158,16 +80,9 @@
if (IdentifierInfo *Id = TableArray[i].Info) {
// Free memory referenced by the identifier (e.g. macro info).
Id->~IdentifierInfo();
-
-#if !USE_ALLOCATOR
- // Free the memory for the identifier itself.
- free(Id);
-#endif
+ Allocator.Deallocate(Id);
}
}
-#if USE_ALLOCATOR
- ((MemRegion*)TheMemory)->Deallocate();
-#endif
delete [] TableArray;
}
@@ -219,12 +134,11 @@
// fill in. Allocate a new identifier with space for the null-terminated
// string at the end.
unsigned AllocSize = sizeof(IdentifierInfo)+Length+1;
-#if USE_ALLOCATOR
- IdentifierInfo *Identifier = (IdentifierInfo*)
- ((MemRegion*)TheMemory)->Allocate(AllocSize, (MemRegion**)&TheMemory);
-#else
- IdentifierInfo *Identifier = (IdentifierInfo*)malloc(AllocSize);
-#endif
+
+ // FIXME: uses GCC extension.
+ unsigned Alignment = __alignof__(IdentifierInfo);
+ IdentifierInfo *Identifier =
+ (IdentifierInfo*)Allocator.Allocate(AllocSize, Alignment);
new (Identifier) IdentifierInfo();
++NumIdentifiers;
@@ -420,16 +334,7 @@
std::cerr << "Max identifier length: " << MaxIdentifierLength << "\n";
// Compute statistics about the memory allocated for identifiers.
-#if USE_ALLOCATOR
- unsigned BytesUsed = 0;
- unsigned NumRegions = 0;
- const MemRegion *R = (MemRegion*)TheMemory;
- for (; R; R = R->getNext(), ++NumRegions) {
- BytesUsed += R->getNumBytesAllocated();
- }
- std::cerr << "\nNumber of memory regions: " << NumRegions << "\n";
- std::cerr << "Bytes allocated for identifiers: " << BytesUsed << "\n";
-#endif
+ Allocator.PrintStats();
}
Modified: cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h?rev=39078&r1=39077&r2=39078&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h (original)
+++ cfe/cfe/trunk/include/clang/Lex/IdentifierTable.h Wed Jul 11 11:27:21 2007
@@ -16,6 +16,7 @@
#define LLVM_CLANG_IDENTIFIERTABLE_H
#include "clang/Basic/TokenKinds.h"
+#include "llvm/Support/Allocator.h"
#include <string>
namespace llvm {
@@ -106,13 +107,21 @@
virtual void VisitIdentifier(IdentifierInfo &II) const = 0;
};
+
+
/// IdentifierTable - This table implements an efficient mapping from strings to
/// IdentifierInfo nodes. It has no other purpose, but this is an
/// extremely performance-critical piece of the code, as each occurrance of
/// every identifier goes through here when lexed.
class IdentifierTable {
void *TheTable;
- void *TheMemory;
+ // Shark shows that using MallocAllocator is *much* slower than using this
+ // BumpPtrAllocator!
+#if 1
+ BumpPtrAllocator Allocator;
+#else
+ MallocAllocator Allocator;
+#endif
unsigned HashTableSize;
unsigned NumIdentifiers;
public:
More information about the cfe-commits
mailing list