[llvm-commits] [llvm] r44705 - in /llvm/trunk: include/llvm/Support/StringPool.h lib/Support/StringPool.cpp

Reid Spencer rspencer at reidspencer.com
Sat Dec 8 11:43:57 PST 2007


Hi Gordon,

Nice addition.

Some minor feedback for you below ...

On Sat, 2007-12-08 at 17:07 +0000, Gordon Henriksen wrote:
> Author: gordon
> Date: Sat Dec  8 11:07:47 2007
> New Revision: 44705
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=44705&view=rev
> Log:
> Adding a StringPool data structure, which GC will use.
> 
> Added:
>     llvm/trunk/include/llvm/Support/StringPool.h
>     llvm/trunk/lib/Support/StringPool.cpp
> 
> Added: llvm/trunk/include/llvm/Support/StringPool.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/StringPool.h?rev=44705&view=auto
> 
> ==============================================================================
> --- llvm/trunk/include/llvm/Support/StringPool.h (added)
> +++ llvm/trunk/include/llvm/Support/StringPool.h Sat Dec  8 11:07:47 2007
> @@ -0,0 +1,135 @@
> +//===-- StringPool.h - Interned string pool -------------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file was developed by Gordon Henriksen and is distributed under the
> +// University of Illinois Open Source License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file declares an interned string pool, which helps reduce the cost of
> +// strings by using the same storage for identical strings.
> +// 
> +// To intern a string:
> +// 
> +//   StringPool Pool;
> +//   PooledStringPtr Str = Pool.intern("wakka wakka");
> +// 
> +// To use the value of an interned string, use operator bool and operator*:
> +// 
> +//   if (Str)
> +//     cerr << "the string is" << *Str << "\n";
> +// 
> +// Pooled strings are immutable, but you can change a PooledStringPtr to point
> +// to another instance. So that interned strings can eventually be freed,
> +// strings in the string pool are reference-counted (automatically).
> +// 
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLVM_SUPPORT_STRINGPOOL_H
> +#define LLVM_SUPPORT_STRINGPOOL_H
> +
> +#include <llvm/ADT/StringMap.h>
> +#include <new>
> +#include <cassert>
> +
> +namespace llvm {
> +
> +  class PooledStringPtr;
> +
> +  /// StringPool - An interned string pool. Use the intern method to add a
> +  /// string. Strings are removed automatically as PooledStringPtrs are
> +  /// destroyed.
> +  class StringPool {
> +    struct PooledString {
> +      StringPool *Pool;  ///< So the string can remove itself.
> +      unsigned Refcount; ///< Number of referencing PooledStringPtrs.
> +      
> +    public:
> +      PooledString() : Pool(0), Refcount(0) { }
> +    };

Since you have added doxygen comments for the structure's data members,
why not document the structure itself as well? This will lead to less
confusing documentation.

> +    
> +    friend class PooledStringPtr;
> +    
> +    typedef StringMap<PooledString> table_t;
> +    typedef StringMapEntry<PooledString> entry_t;
> +    table_t InternTable;
> +    
> +  public:
> +    StringPool();
> +    ~StringPool();
> +    
> +    PooledStringPtr intern(const char *Begin, const char *End);
> +    inline PooledStringPtr intern(const char *Str);

These two methods are primary interfaces to the StringPool, aren't they?
Shouldn't they be documented with doxygen comments?
> +  };
> +  
> +  /// PooledStringPtr - A pointer to an interned string. Use operator bool to
> +  /// test whether the pointer is valid, and operator * to get the string if so.
> +  /// This is a lightweight value class with storage requirements equivalent to
> +  /// a single pointer, but it does have reference-counting overhead when
> +  /// copied.
> +  class PooledStringPtr {
> +    typedef StringPool::entry_t entry_t;
> +    entry_t *S;
> +    
> +  public:
> +    PooledStringPtr() : S(0) {}
> +    
> +    explicit PooledStringPtr(entry_t *E) : S(E) {
> +      if (S) ++S->getValue().Refcount;
> +    }
> +    
> +    PooledStringPtr(const PooledStringPtr &That) : S(That.S) {
> +      if (S) ++S->getValue().Refcount;
> +    }
> +    
> +    PooledStringPtr &operator=(const PooledStringPtr &That) {
> +      if (S != That.S) {
> +        clear();
> +        S = That.S;
> +        if (S) ++S->getValue().Refcount;
> +      }
> +      return *this;
> +    }
> +    
> +    void clear() {
> +      if (!S)
> +        return;
> +      if (--S->getValue().Refcount == 0) {
> +        S->getValue().Pool->InternTable.remove(S);
> +        delete S;
> +      }
> +      S = 0;
> +    }
> +    
> +    ~PooledStringPtr() { clear(); }
> +    
> +    inline const char *begin() const {
> +      assert(*this && "Attempt to dereference empty PooledStringPtr!");
> +      return S->getKeyData();
> +    }
> +    
> +    inline const char *end() const {
> +      assert(*this && "Attempt to dereference empty PooledStringPtr!");
> +      return S->getKeyData() + S->getKeyLength();
> +    }
> +    
> +    inline unsigned size() const {
> +      assert(*this && "Attempt to dereference empty PooledStringPtr!");
> +      return S->getKeyLength();
> +    }
> +    
> +    inline const char *operator*() const { return begin(); }
> +    inline operator bool() const { return S != 0; }
> +    
> +    inline bool operator==(const PooledStringPtr &That) { return S == That.S; }
> +    inline bool operator!=(const PooledStringPtr &That) { return S != That.S; }
> +  };
> +  
> +  PooledStringPtr StringPool::intern(const char *Str) {
> +    return intern(Str, Str + strlen(Str));

Maybe use strnlen(3) here to guard against Str not being null
terminated ?

> +  }
> +
> +} // End llvm namespace
> +
> +#endif
> 
> Added: llvm/trunk/lib/Support/StringPool.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringPool.cpp?rev=44705&view=auto
> 
> ==============================================================================
> --- llvm/trunk/lib/Support/StringPool.cpp (added)
> +++ llvm/trunk/lib/Support/StringPool.cpp Sat Dec  8 11:07:47 2007
> @@ -0,0 +1,35 @@
> +//===-- StringPool.cpp - Interned string pool -----------------------------===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file was developed by Gordon Henriksen and is distributed under the
> +// University of Illinois Open Source License. See LICENSE.TXT for details.
> +//
> +//===----------------------------------------------------------------------===//
> +//
> +// This file implements the StringPool class.
> +//
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/Support/StringPool.h"
> +#include "llvm/Support/Streams.h"
> +
> +using namespace llvm;
> +
> +StringPool::StringPool() {}
> +
> +StringPool::~StringPool() {
> +  assert(InternTable.empty() && "PooledStringPtr leaked!");
> +}
> +
> +PooledStringPtr StringPool::intern(const char *Begin, const char *End) {
> +  table_t::iterator I = InternTable.find(Begin, End);
> +  if (I != InternTable.end())
> +    return PooledStringPtr(&*I);
> +  
> +  entry_t *S = entry_t::Create(Begin, End);
> +  S->getValue().Pool = this;
> +  InternTable.insert(S);
> +  
> +  return PooledStringPtr(S);
> +}
> 
> 
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list