[vmkit-commits] [vmkit] r136604 - in /vmkit/trunk: include/j3/JavaAOTCompiler.h include/mvm/MvmDenseSet.h include/mvm/UTF8.h lib/J3/Compiler/JavaAOTCompiler.cpp lib/J3/VMCore/Precompiled.cpp

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sun Jul 31 15:50:08 PDT 2011


Author: geoffray
Date: Sun Jul 31 17:50:08 2011
New Revision: 136604

URL: http://llvm.org/viewvc/llvm-project?rev=136604&view=rev
Log:
Use a set instead of a map for utf8.


Added:
    vmkit/trunk/include/mvm/MvmDenseSet.h
Modified:
    vmkit/trunk/include/j3/JavaAOTCompiler.h
    vmkit/trunk/include/mvm/UTF8.h
    vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp
    vmkit/trunk/lib/J3/VMCore/Precompiled.cpp

Modified: vmkit/trunk/include/j3/JavaAOTCompiler.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/j3/JavaAOTCompiler.h?rev=136604&r1=136603&r2=136604&view=diff
==============================================================================
--- vmkit/trunk/include/j3/JavaAOTCompiler.h (original)
+++ vmkit/trunk/include/j3/JavaAOTCompiler.h Sun Jul 31 17:50:08 2011
@@ -102,7 +102,7 @@
   llvm::Constant* CreateConstantFromClassBytes(ClassBytes* bytes);
   llvm::Constant* CreateConstantFromJavaConstantPool(JavaConstantPool* ctp);
   llvm::Constant* CreateConstantFromClassMap(const mvm::MvmDenseMap<const UTF8*, CommonClass*>& map);
-  llvm::Constant* CreateConstantFromUTF8Map(const mvm::MvmDenseMap<mvm::UTF8MapKey, const UTF8*>& map);
+  llvm::Constant* CreateConstantFromUTF8Map(const mvm::MvmDenseSet<mvm::UTF8MapKey, const UTF8*>& set);
   void AddInitializerToClass(llvm::GlobalVariable* varGV, CommonClass* classDef);
   llvm::Constant* getUTF8(const UTF8* val);
   
@@ -178,6 +178,8 @@
   llvm::Function* RegularObjectTracer;
   llvm::Function* JavaObjectTracer;
   llvm::Function* ReferenceObjectTracer;
+  llvm::GlobalVariable* UTF8TombstoneGV;
+  llvm::GlobalVariable* UTF8EmptyGV;
   
   bool generateStubs;
   bool assumeCompiled;

Added: vmkit/trunk/include/mvm/MvmDenseSet.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/MvmDenseSet.h?rev=136604&view=auto
==============================================================================
--- vmkit/trunk/include/mvm/MvmDenseSet.h (added)
+++ vmkit/trunk/include/mvm/MvmDenseSet.h Sun Jul 31 17:50:08 2011
@@ -0,0 +1,491 @@
+//===- MvmDenseSet.h - Dense probed hash set --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the MvmDenseMap copied from llvm/ADT/DenseMap.h, but
+// without storing pairs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MVM_DENSESET_H
+#define MVM_DENSESET_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include "llvm/Support/type_traits.h"
+#include <algorithm>
+#include <iterator>
+#include <new>
+#include <utility>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+
+namespace mvm {
+
+template<typename ValueT,
+         typename ValueInfoT = MvmDenseMapInfo<ValueT>,
+         bool IsConst = false>
+class MvmDenseSetIterator;
+
+template<typename KeyT, typename ValueT,
+         typename KeyInfoT = MvmDenseMapInfo<KeyT>,
+         typename ValueInfoT = MvmDenseMapInfo<ValueT> >
+class MvmDenseSet {
+public:
+  typedef ValueT BucketT;
+  uint32_t NumBuckets;
+  BucketT *Buckets;
+
+  uint32_t NumEntries;
+  uint32_t NumTombstones;
+  bool IsPrecompiled;
+
+  typedef KeyT key_type;
+  typedef ValueT mapped_type;
+  typedef BucketT value_type;
+
+  explicit MvmDenseSet(unsigned NumInitBuckets = 0) {
+    IsPrecompiled = false;
+    init(NumInitBuckets);
+  }
+
+  ~MvmDenseSet() {
+    const ValueT EmptyValue = getEmptyValue(), TombstoneValue = getTombstoneValue();
+    for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+      if (!ValueInfoT::isEqual(*P, EmptyValue) &&
+          !ValueInfoT::isEqual(*P, TombstoneValue))
+        (*P).~ValueT();
+    }
+#ifndef NDEBUG
+    if (NumBuckets)
+      memset((void*)Buckets, 0x5a, sizeof(BucketT)*NumBuckets);
+#endif
+    if (!IsPrecompiled) {
+      operator delete(Buckets);
+    }
+  }
+
+  typedef MvmDenseSetIterator<ValueT, ValueInfoT> iterator;
+  typedef MvmDenseSetIterator<ValueT, ValueInfoT, true> const_iterator;
+  inline iterator begin() {
+    // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
+    return empty() ? end() : iterator(Buckets, Buckets+NumBuckets);
+  }
+  inline iterator end() {
+    return iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+  }
+  inline const_iterator begin() const {
+    return empty() ? end() : const_iterator(Buckets, Buckets+NumBuckets);
+  }
+  inline const_iterator end() const {
+    return const_iterator(Buckets+NumBuckets, Buckets+NumBuckets);
+  }
+
+  bool empty() const { return NumEntries == 0; }
+  unsigned size() const { return NumEntries; }
+
+  /// Grow the denseset so that it has at least Size buckets. Does not shrink
+  void resize(size_t Size) {
+    if (Size > NumBuckets)
+      grow(Size);
+  }
+
+  void clear() {
+    if (NumEntries == 0 && NumTombstones == 0) return;
+    
+    // If the capacity of the array is huge, and the # elements used is small,
+    // shrink the array.
+    if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
+      shrink_and_clear();
+      return;
+    }
+
+    const ValueT EmptyValue = getEmptyValue(), TombstoneValue = getTombstoneValue();
+    for (BucketT *P = Buckets, *E = Buckets+NumBuckets; P != E; ++P) {
+      if (!ValueInfoT::isEqual(*P, EmptyValue)) {
+        if (!ValueInfoT::isEqual(*P, TombstoneValue)) {
+          P->~ValueT();
+          --NumEntries;
+        }
+        *P = EmptyValue;
+      }
+    }
+    assert(NumEntries == 0 && "Node count imbalance!");
+    NumTombstones = 0;
+  }
+
+  /// count - Return true if the specified key is in the set.
+  bool count(const KeyT &Val) const {
+    BucketT *TheBucket;
+    return LookupBucketFor(Val, TheBucket);
+  }
+
+  iterator find(const KeyT &Val) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return iterator(TheBucket, Buckets+NumBuckets);
+    return end();
+  }
+  const_iterator find(const KeyT &Val) const {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return const_iterator(TheBucket, Buckets+NumBuckets);
+    return end();
+  }
+
+  /// lookup - Return the entry for the specified key, or a default
+  /// constructed value if no such entry exists.
+  ValueT lookup(const KeyT &Val) const {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Val, TheBucket))
+      return *TheBucket;
+    return ValueT();
+  }
+
+  // Inserts key,value pair into the map if the key isn't already in the map.
+  // If the key is already in the map, it returns false and doesn't update the
+  // value.
+  std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(KV.first, TheBucket))
+      return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
+                            false); // Already in map.
+
+    // Otherwise, insert the new element.
+    TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
+    return std::make_pair(iterator(TheBucket, Buckets+NumBuckets),
+                          true);
+  }
+
+  /// insert - Range insertion of pairs.
+  template<typename InputIt>
+  void insert(InputIt I, InputIt E) {
+    for (; I != E; ++I)
+      insert(*I);
+  }
+
+
+  bool erase(const KeyT &Val) {
+    BucketT *TheBucket;
+    if (!LookupBucketFor(Val, TheBucket))
+      return false; // not in map.
+
+    (*TheBucket).~ValueT();
+    *TheBucket = getTombstoneValue();
+    --NumEntries;
+    ++NumTombstones;
+    return true;
+  }
+  void erase(iterator I) {
+    BucketT *TheBucket = &*I;
+    (*TheBucket).~ValueT();
+    *TheBucket = getTombstoneValue();
+    --NumEntries;
+    ++NumTombstones;
+  }
+
+  void swap(MvmDenseSet& RHS) {
+    std::swap(NumBuckets, RHS.NumBuckets);
+    std::swap(Buckets, RHS.Buckets);
+    std::swap(NumEntries, RHS.NumEntries);
+    std::swap(NumTombstones, RHS.NumTombstones);
+  }
+
+  value_type& FindAndConstruct(const KeyT &Key) {
+    BucketT *TheBucket;
+    if (LookupBucketFor(Key, TheBucket))
+      return *TheBucket;
+
+    return *InsertIntoBucket(Key, ValueT(), TheBucket);
+  }
+
+  ValueT &operator[](const KeyT &Key) {
+    return FindAndConstruct(Key);
+  }
+
+  /// isPointerIntoBucketsArray - Return true if the specified pointer points
+  /// somewhere into the MvmDenseSet's array of buckets.
+  bool isPointerIntoBucketsArray(const void *Ptr) const {
+    return Ptr >= Buckets && Ptr < Buckets+NumBuckets;
+  }
+
+  /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
+  /// array.  In conjunction with the previous method, this can be used to
+  /// determine whether an insertion caused the MvmDenseSet to reallocate.
+  const void *getPointerIntoBucketsArray() const { return Buckets; }
+
+private:
+  BucketT *InsertIntoBucket(const KeyT &Key, const ValueT &Value,
+                            BucketT *TheBucket) {
+    // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
+    // the buckets are empty (meaning that many are filled with tombstones),
+    // grow the table.
+    //
+    // The later case is tricky.  For example, if we had one empty bucket with
+    // tons of tombstones, failing lookups (e.g. for insertion) would have to
+    // probe almost the entire table until it found the empty bucket.  If the
+    // table completely filled with tombstones, no lookup would ever succeed,
+    // causing infinite loops in lookup.
+    ++NumEntries;
+    if (NumEntries*4 >= NumBuckets*3) {
+      this->grow(NumBuckets * 2);
+      LookupBucketFor(Key, TheBucket);
+    }
+    if (NumBuckets-(NumEntries+NumTombstones) < NumBuckets/8) {
+      this->grow(NumBuckets);
+      LookupBucketFor(Key, TheBucket);
+    }
+
+    // If we are writing over a tombstone, remember this.
+    if (!ValueInfoT::isEqual(*TheBucket, getEmptyValue()))
+      --NumTombstones;
+
+    new (TheBucket) ValueT(Value);
+    return TheBucket;
+  }
+
+  static unsigned getHashValue(const KeyT &Val) {
+    return KeyInfoT::getHashValue(Val);
+  }
+  static const ValueT getEmptyValue() {
+    return ValueInfoT::getEmptyKey();
+  }
+  static const ValueT getTombstoneValue() {
+    return ValueInfoT::getTombstoneKey();
+  }
+
+  /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
+  /// FoundBucket.  If the bucket contains the key and a value, this returns
+  /// true, otherwise it returns a bucket with an empty marker or tombstone and
+  /// returns false.
+  bool LookupBucketFor(const KeyT &Key, BucketT *&FoundBucket) const {
+    unsigned BucketNo = getHashValue(Key);
+    unsigned ProbeAmt = 1;
+    BucketT *BucketsPtr = Buckets;
+
+    if (NumBuckets == 0) {
+      FoundBucket = 0;
+      return false;
+    }
+
+    // FoundTombstone - Keep track of whether we find a tombstone while probing.
+    BucketT *FoundTombstone = 0;
+    const ValueT EmptyValue = getEmptyValue();
+    const ValueT TombstoneValue = getTombstoneValue();
+
+    while (1) {
+      BucketT *ThisBucket = BucketsPtr + (BucketNo & (NumBuckets-1));
+      // Found Val's bucket?  If so, return it.
+      if (ValueInfoT::isEqualKey(*ThisBucket, Key)) {
+        FoundBucket = ThisBucket;
+        return true;
+      }
+
+      // If we found an empty bucket, the key doesn't exist in the set.
+      // Insert it and return the default value.
+      if (ValueInfoT::isEqual(*ThisBucket, EmptyValue)) {
+        // If we've already seen a tombstone while probing, fill it in instead
+        // of the empty bucket we eventually probed to.
+        if (FoundTombstone) ThisBucket = FoundTombstone;
+        FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
+        return false;
+      }
+
+      // If this is a tombstone, remember it.  If Val ends up not in the map, we
+      // prefer to return it than something that would require more probing.
+      if (ValueInfoT::isEqual(*ThisBucket, TombstoneValue) && !FoundTombstone)
+        FoundTombstone = ThisBucket;  // Remember the first tombstone found.
+
+      // Otherwise, it's a hash collision or a tombstone, continue quadratic
+      // probing.
+      BucketNo += ProbeAmt++;
+    }
+  }
+
+  void init(unsigned InitBuckets) {
+    NumEntries = 0;
+    NumTombstones = 0;
+    NumBuckets = InitBuckets;
+
+    if (InitBuckets == 0) {
+      Buckets = 0;
+      return;
+    }
+
+    assert(InitBuckets && (InitBuckets & (InitBuckets-1)) == 0 &&
+           "# initial buckets must be a power of two!");
+    Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*InitBuckets));
+    // Initialize all the entries to EmptyValue.
+    const ValueT EmptyValue = getEmptyValue();
+    for (unsigned i = 0; i != InitBuckets; ++i)
+      new (&Buckets[i]) ValueT(EmptyValue);
+  }
+
+  void grow(unsigned AtLeast) {
+    unsigned OldNumBuckets = NumBuckets;
+    BucketT *OldBuckets = Buckets;
+
+    if (NumBuckets < 64)
+      NumBuckets = 64;
+
+    // Double the number of buckets.
+    while (NumBuckets < AtLeast)
+      NumBuckets <<= 1;
+    NumTombstones = 0;
+    Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+
+    // Initialize all the values to EmptyValue.
+    const ValueT EmptyValue = getEmptyValue();
+    for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+      new (&Buckets[i]) ValueT(EmptyValue);
+
+    // Insert all the old elements.
+    const ValueT TombstoneValue = getTombstoneValue();
+    for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+      if (!ValueInfoT::isEqual(*B, EmptyValue) &&
+          !ValueInfoT::isEqual(*B, TombstoneValue)) {
+        // Insert the value into the new table.
+        BucketT *DestBucket;
+        KeyT key = ValueInfoT::toKey(*B);
+        bool FoundVal = LookupBucketFor(key, DestBucket);
+        (void)FoundVal; // silence warning.
+        assert(!FoundVal && "Key already in new map?");
+        new (DestBucket) ValueT(*B);
+
+        // Free the value.
+        (*B).~ValueT();
+      }
+    }
+
+#ifndef NDEBUG
+    if (OldNumBuckets)
+      memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+#endif
+    // Free the old table.
+    if (!IsPrecompiled) {
+      operator delete(OldBuckets);
+    } else {
+      IsPrecompiled = false;
+    }
+  }
+
+  void shrink_and_clear() {
+    unsigned OldNumBuckets = NumBuckets;
+    BucketT *OldBuckets = Buckets;
+
+    // Reduce the number of buckets.
+    NumBuckets = NumEntries > 32 ? 1 << (llvm::Log2_32_Ceil(NumEntries) + 1)
+                                 : 64;
+    NumTombstones = 0;
+    Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT)*NumBuckets));
+
+    // Initialize all the entries to EmptyValue.
+    const ValueT EmptyValue = getEmptyValue();
+    for (unsigned i = 0, e = NumBuckets; i != e; ++i)
+      new (&Buckets[i]) ValueT(EmptyValue);
+
+    // Free the old buckets.
+    const ValueT TombstoneValue = getTombstoneValue();
+    for (BucketT *B = OldBuckets, *E = OldBuckets+OldNumBuckets; B != E; ++B) {
+      if (!ValueInfoT::isEqual(*B, EmptyValue) &&
+          !ValueInfoT::isEqual(*B, TombstoneValue)) {
+        // Free the value.
+        (*B).~ValueT();
+      }
+    }
+
+#ifndef NDEBUG
+    memset((void*)OldBuckets, 0x5a, sizeof(BucketT)*OldNumBuckets);
+#endif
+    if (!IsPrecompiled) {
+      // Free the old table.
+      operator delete(OldBuckets);
+    } else {
+      IsPrecompiled = false;
+    }
+
+    NumEntries = 0;
+  }
+  
+public:
+  /// Return the approximate size (in bytes) of the actual map.
+  /// This is just the raw memory used by MvmDenseSet.
+  /// If entries are pointers to objects, the size of the referenced objects
+  /// are not included.
+  size_t getMemorySize() const {
+    return NumBuckets * sizeof(BucketT);
+  }
+};
+
+template<typename ValueT,
+         typename ValueInfoT, bool IsConst>
+class MvmDenseSetIterator {
+  typedef ValueT Bucket;
+  typedef MvmDenseSetIterator<ValueT, ValueInfoT, true> ConstIterator;
+  friend class MvmDenseSetIterator<ValueT, ValueInfoT, true>;
+public:
+  typedef ptrdiff_t difference_type;
+  typedef typename llvm::conditional<IsConst, const Bucket, Bucket>::type value_type;
+  typedef value_type *pointer;
+  typedef value_type &reference;
+  typedef std::forward_iterator_tag iterator_category;
+private:
+  pointer Ptr, End;
+public:
+  MvmDenseSetIterator() : Ptr(0), End(0) {}
+
+  MvmDenseSetIterator(pointer Pos, pointer E) : Ptr(Pos), End(E) {
+    AdvancePastEmptyBuckets();
+  }
+
+  // If IsConst is true this is a converting constructor from iterator to
+  // const_iterator and the default copy constructor is used.
+  // Otherwise this is a copy constructor for iterator.
+  MvmDenseSetIterator(const MvmDenseSetIterator<ValueT, ValueInfoT, false>& I)
+    : Ptr(I.Ptr), End(I.End) {}
+
+  reference operator*() const {
+    return *Ptr;
+  }
+  pointer operator->() const {
+    return Ptr;
+  }
+
+  bool operator==(const ConstIterator &RHS) const {
+    return Ptr == RHS.operator->();
+  }
+  bool operator!=(const ConstIterator &RHS) const {
+    return Ptr != RHS.operator->();
+  }
+
+  inline MvmDenseSetIterator& operator++() {  // Preincrement
+    ++Ptr;
+    AdvancePastEmptyBuckets();
+    return *this;
+  }
+  MvmDenseSetIterator operator++(int) {  // Postincrement
+    MvmDenseSetIterator tmp = *this; ++*this; return tmp;
+  }
+
+private:
+  void AdvancePastEmptyBuckets() {
+    const ValueT Empty = ValueInfoT::getEmptyKey();
+    const ValueT Tombstone = ValueInfoT::getTombstoneKey();
+
+    while (Ptr != End &&
+           (ValueInfoT::isEqual(*Ptr, Empty) ||
+            ValueInfoT::isEqual(*Ptr, Tombstone)))
+      ++Ptr;
+  }
+};
+
+} // end namespace mvm
+
+#endif

Modified: vmkit/trunk/include/mvm/UTF8.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/include/mvm/UTF8.h?rev=136604&r1=136603&r2=136604&view=diff
==============================================================================
--- vmkit/trunk/include/mvm/UTF8.h (original)
+++ vmkit/trunk/include/mvm/UTF8.h Sun Jul 31 17:50:08 2011
@@ -4,6 +4,7 @@
 #include <map>
 #include "mvm/Allocator.h"
 #include "mvm/MvmDenseMap.h"
+#include "mvm/MvmDenseSet.h"
 
 namespace mvm {
 
@@ -68,6 +69,16 @@
 extern "C" const UTF8 TombstoneKey;
 extern "C" const UTF8 EmptyKey;
 
+struct UTF8MapKey {
+  ssize_t length;
+  const uint16_t* data;
+
+  UTF8MapKey(const uint16_t* d, ssize_t l) {
+    data = d;
+    length = l;
+  }
+};
+
 // Provide MvmDenseMapInfo for UTF8.
 template<>
 struct MvmDenseMapInfo<const UTF8*> {
@@ -81,19 +92,15 @@
     return PtrVal->hash();
   }
   static bool isEqual(const UTF8* LHS, const UTF8* RHS) { return LHS->equals(RHS); }
-};
-
-
-struct UTF8MapKey {
-  ssize_t length;
-  const uint16_t* data;
-
-  UTF8MapKey(const uint16_t* d, ssize_t l) {
-    data = d;
-    length = l;
+  static bool isEqualKey(const UTF8* LHS, const UTF8MapKey& Key) {
+    return LHS->equals(Key.data, Key.length);
+  }
+  static UTF8MapKey toKey(const UTF8* utf8) {
+    return UTF8MapKey(utf8->elements, utf8->size);
   }
 };
 
+
 // Provide MvmDenseMapInfo for UTF8MapKey.
 template<>
 struct MvmDenseMapInfo<UTF8MapKey> {
@@ -117,12 +124,11 @@
 
 class UTF8Map : public mvm::PermanentObject {
 public:
-  typedef MvmDenseMap<UTF8MapKey, const UTF8*>::iterator iterator;
+  typedef MvmDenseSet<UTF8MapKey, const UTF8*>::iterator iterator;
   
   LockNormal lock;
   BumpPtrAllocator& allocator;
-  // TODO(ngeoffray): This should really be a set.
-  MvmDenseMap<UTF8MapKey, const UTF8*> map;
+  MvmDenseSet<UTF8MapKey, const UTF8*> map;
 
   const UTF8* lookupOrCreateAsciiz(const char* asciiz); 
   const UTF8* lookupOrCreateReader(const uint16* buf, uint32 size);
@@ -130,12 +136,12 @@
   const UTF8* lookupReader(const uint16* buf, uint32 size);
   
   UTF8Map(BumpPtrAllocator& A) : allocator(A) {}
-  UTF8Map(BumpPtrAllocator& A, MvmDenseMap<UTF8MapKey, const UTF8*>* m)
+  UTF8Map(BumpPtrAllocator& A, MvmDenseSet<UTF8MapKey, const UTF8*>* m)
       : allocator(A), map(*m) {}
 
   ~UTF8Map() {
     for (iterator i = map.begin(), e = map.end(); i!= e; ++i) {
-      allocator.Deallocate((void*)i->second);
+      allocator.Deallocate((void*)*i);
     }
   }
 

Modified: vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp?rev=136604&r1=136603&r2=136604&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp (original)
+++ vmkit/trunk/lib/J3/Compiler/JavaAOTCompiler.cpp Sun Jul 31 17:50:08 2011
@@ -1116,18 +1116,10 @@
     for (uint32 i = 0; i < map.NumBuckets; ++i) {
       mvm::MvmPair<const UTF8*, CommonClass*> pair = map.Buckets[i];
       if (pair.first == &mvm::TombstoneKey) {
-        static GlobalVariable* gv =
-          new GlobalVariable(Mod, JavaIntrinsics.UTF8Type->getContainedType(0),
-                             false, GlobalValue::ExternalLinkage, NULL,
-                             "TombstoneKey");
-        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, gv, JavaIntrinsics.ptrType));
+        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8TombstoneGV, JavaIntrinsics.ptrType));
         TempElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
       } else if (pair.first == &mvm::EmptyKey) {
-        static GlobalVariable* gv =
-          new GlobalVariable(Mod, JavaIntrinsics.UTF8Type->getContainedType(0),
-                             false, GlobalValue::ExternalLinkage, NULL,
-                             "EmptyKey");
-        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, gv, JavaIntrinsics.ptrType));
+        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8EmptyGV, JavaIntrinsics.ptrType));
         TempElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
       } else {
         TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, getUTF8(pair.first), JavaIntrinsics.ptrType));
@@ -1153,39 +1145,27 @@
                             ConstantStruct::get(STy, elements), "ClassMap");
 }
 
-Constant* JavaAOTCompiler::CreateConstantFromUTF8Map(const mvm::MvmDenseMap<mvm::UTF8MapKey, const UTF8*>& map) {
+Constant* JavaAOTCompiler::CreateConstantFromUTF8Map(const mvm::MvmDenseSet<mvm::UTF8MapKey, const UTF8*>& set) {
   StructType* STy = 
     dyn_cast<StructType>(JavaIntrinsics.J3DenseMapType->getContainedType(0));
   Module& Mod = *getLLVMModule();
 
   std::vector<Constant*> elements;
-  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), map.NumBuckets));
+  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), set.NumBuckets));
 
   Constant* buckets;
-  if (map.NumBuckets > 0) {
+  if (set.NumBuckets > 0) {
     std::vector<Constant*> TempElts;
-    ArrayType* ATy = ArrayType::get(JavaIntrinsics.ptrType, map.NumBuckets * 3);
+    ArrayType* ATy = ArrayType::get(JavaIntrinsics.ptrType, set.NumBuckets);
 
-    for (uint32 i = 0; i < map.NumBuckets; ++i) {
-      mvm::MvmPair<mvm::UTF8MapKey, const UTF8*>& pair = map.Buckets[i];
-      TempElts.push_back(ConstantExpr::getCast(
-            Instruction::IntToPtr,
-            ConstantInt::get(JavaIntrinsics.pointerSizeType, pair.first.length),
-            JavaIntrinsics.ptrType));
-
-      if (mvm::MvmDenseMapInfo<mvm::UTF8MapKey>::isEqual(pair.first,
-                mvm::MvmDenseMapInfo<mvm::UTF8MapKey>::getEmptyKey())
-          || mvm::MvmDenseMapInfo<mvm::UTF8MapKey>::isEqual(pair.first,
-                mvm::MvmDenseMapInfo<mvm::UTF8MapKey>::getTombstoneKey())) {
-        TempElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
-        TempElts.push_back(Constant::getNullValue(JavaIntrinsics.ptrType));
+    for (uint32 i = 0; i < set.NumBuckets; ++i) {
+      const UTF8* utf8 = set.Buckets[i];
+      if (utf8 == &mvm::EmptyKey) {
+        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8EmptyGV, JavaIntrinsics.ptrType));
+      } else if (utf8 == &mvm::TombstoneKey) {
+        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, UTF8TombstoneGV, JavaIntrinsics.ptrType));
       } else {
-        Constant* gv = getUTF8(pair.second);
-        Constant* GEP[2] = { JavaIntrinsics.constantZero, JavaIntrinsics.constantOne };
-
-        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast,
-              ConstantExpr::getGetElementPtr(gv, GEP, 2), JavaIntrinsics.ptrType));
-        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, gv, JavaIntrinsics.ptrType));
+        TempElts.push_back(ConstantExpr::getCast(Instruction::BitCast, getUTF8(utf8), JavaIntrinsics.ptrType));
       }
     }
 
@@ -1198,8 +1178,8 @@
   }
 
   elements.push_back(buckets);
-  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), map.NumEntries));
-  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), map.NumTombstones));
+  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), set.NumEntries));
+  elements.push_back(ConstantInt::get(Type::getInt32Ty(getLLVMContext()), set.NumTombstones));
   elements.push_back(ConstantInt::get(Type::getInt1Ty(getLLVMContext()), 1));
 
   return new GlobalVariable(Mod, STy, false,
@@ -1873,6 +1853,16 @@
                                            GlobalValue::ExternalLinkage,
                                            "ReferenceObjectTracer",
                                            getLLVMModule());
+
+  UTF8EmptyGV = new GlobalVariable(*getLLVMModule(),
+                                   JavaIntrinsics.UTF8Type->getContainedType(0),
+                                   false, GlobalValue::ExternalLinkage, NULL,
+                                   "EmptyKey");
+
+  UTF8TombstoneGV = new GlobalVariable(*getLLVMModule(),
+                                       JavaIntrinsics.UTF8Type->getContainedType(0),
+                                       false, GlobalValue::ExternalLinkage, NULL,
+                                       "TombstoneKey");
 }
 
 void JavaAOTCompiler::printStats() {

Modified: vmkit/trunk/lib/J3/VMCore/Precompiled.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/J3/VMCore/Precompiled.cpp?rev=136604&r1=136603&r2=136604&view=diff
==============================================================================
--- vmkit/trunk/lib/J3/VMCore/Precompiled.cpp (original)
+++ vmkit/trunk/lib/J3/VMCore/Precompiled.cpp Sun Jul 31 17:50:08 2011
@@ -313,8 +313,8 @@
   upcalls->OfLong->classLoader = loader;
   upcalls->OfDouble->classLoader = loader;
 
-  mvm::MvmDenseMap<mvm::UTF8MapKey, const UTF8*>* precompiledUTF8Map =
-    reinterpret_cast<mvm::MvmDenseMap<mvm::UTF8MapKey, const UTF8*>*>(dlsym(nativeHandle, "UTF8Map"));
+  mvm::MvmDenseSet<mvm::UTF8MapKey, const UTF8*>* precompiledUTF8Map =
+    reinterpret_cast<mvm::MvmDenseSet<mvm::UTF8MapKey, const UTF8*>*>(dlsym(nativeHandle, "UTF8Map"));
   loader->hashUTF8 = new (loader->allocator, "UTF8Map") UTF8Map(loader->allocator, precompiledUTF8Map);
   
   mvm::MvmDenseMap<const UTF8*, CommonClass*>* precompiledClassMap =





More information about the vmkit-commits mailing list