1// PR debug/55717
2// { dg-do compile }
3// { dg-options "-O -g" }
4
5struct DebugOnly {};
6template <class T>
7struct StripConst { typedef T result; };
8class TempAllocPolicy {};
9template <class T>
10class HashTableEntry
11{
12  unsigned keyHash;
13  template <class, class, class>
14  friend class HashTable;
15  T t;
16  void setLive (unsigned hn) { keyHash = hn; }
17};
18template <class T, class HashPolicy, class>
19struct HashTable
20{
21  typedef typename HashPolicy::KeyType Key;
22  typedef typename HashPolicy::Lookup Lookup;
23  typedef HashTableEntry <T> Entry;
24  struct Range
25  {
26    Range () {}
27    Entry *cur, end;
28    bool empty () { return false; }
29    T front () { return T (); }
30  };
31  struct Enum : public Range
32  {
33    HashTable table;
34    bool removed;
35    template <class Map>
36    Enum (Map map) : Range (map.all ()), table (map.impl), removed () {}
37    void rekeyFront (Lookup l, Key)
38    {
39      T t = this->cur->t;
40      table.putNewInfallible (l, t);
41    }
42    void rekeyFront (Key k)
43    {
44      rekeyFront (k, k);
45    }
46  };
47  unsigned entryCount;
48  unsigned sCollisionBit;
49  unsigned prepareHash (Lookup l)
50  {
51    unsigned keyHash (HashPolicy::hash (l));
52    return keyHash & sCollisionBit;
53  }
54  static Entry *entryp;
55  Entry *findFreeEntry (unsigned) { return entryp; }
56  void putNewInfallible (Lookup l, T)
57  {
58    unsigned keyHash = prepareHash (l);
59    Entry *entry = findFreeEntry (keyHash);
60    entry->setLive (keyHash);
61    entryCount++;
62  }
63};
64template <class Key>
65struct HashMapEntry { Key key; };
66template <class Key, class Value, class HashPolicy = DebugOnly, class AllocPolicy = TempAllocPolicy>
67struct HashMap
68{
69  typedef HashMapEntry <Key> Entry;
70  struct MapHashPolicy : HashPolicy
71  {
72    typedef Key KeyType;
73  };
74  typedef HashTable <Entry, MapHashPolicy, AllocPolicy> Impl;
75  Impl impl;
76  typedef typename Impl::Range Range;
77  Range all () { return Range (); }
78  typedef typename Impl::Enum Enum;
79};
80class FreeOp;
81struct AllocationSiteKey;
82typedef HashMap <AllocationSiteKey, DebugOnly, AllocationSiteKey, TempAllocPolicy> AllocationSiteTable;
83struct TypeCompartment
84{
85  AllocationSiteTable *allocationSiteTable;
86  void sweep (FreeOp *);
87};
88struct JSScript { unsigned *code; };
89bool IsScriptMarked (JSScript **);
90struct AllocationSiteKey
91{
92  JSScript *script;
93  unsigned offset : 24;
94  int kind;
95  typedef AllocationSiteKey Lookup;
96  static unsigned hash (AllocationSiteKey key) { return (long (key.script->code + key.offset)) ^ key.kind; }
97};
98void
99TypeCompartment::sweep (FreeOp *)
100{
101  for (AllocationSiteTable::Enum e (*allocationSiteTable); !e.empty ();)
102    {
103      AllocationSiteKey key = e.front ().key;
104      IsScriptMarked (&key.script);
105      e.rekeyFront (key);
106    }
107}
108