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