1 // PR debug/55717
2 // { dg-do compile }
3 // { dg-options "-O -g" }
4
5 struct DebugOnly {};
6 template <class T>
7 struct StripConst { typedef T result; };
8 class TempAllocPolicy {};
9 template <class T>
10 class HashTableEntry
11 {
12 unsigned keyHash;
13 template <class, class, class>
14 friend class HashTable;
15 T t;
setLive(unsigned hn)16 void setLive (unsigned hn) { keyHash = hn; }
17 };
18 template <class T, class HashPolicy, class>
19 struct HashTable
20 {
21 typedef typename HashPolicy::KeyType Key;
22 typedef typename HashPolicy::Lookup Lookup;
23 typedef HashTableEntry <T> Entry;
24 struct Range
25 {
RangeHashTable::Range26 Range () {}
27 Entry *cur, end;
emptyHashTable::Range28 bool empty () { return false; }
frontHashTable::Range29 T front () { return T (); }
30 };
31 struct Enum : public Range
32 {
33 HashTable table;
34 bool removed;
35 template <class Map>
EnumHashTable::Enum36 Enum (Map map) : Range (map.all ()), table (map.impl), removed () {}
rekeyFrontHashTable::Enum37 void rekeyFront (Lookup l, Key)
38 {
39 T t = this->cur->t;
40 table.putNewInfallible (l, t);
41 }
rekeyFrontHashTable::Enum42 void rekeyFront (Key k)
43 {
44 rekeyFront (k, k);
45 }
46 };
47 unsigned entryCount;
48 unsigned sCollisionBit;
prepareHashHashTable49 unsigned prepareHash (Lookup l)
50 {
51 unsigned keyHash (HashPolicy::hash (l));
52 return keyHash & sCollisionBit;
53 }
54 static Entry *entryp;
findFreeEntryHashTable55 Entry *findFreeEntry (unsigned) { return entryp; }
putNewInfallibleHashTable56 void putNewInfallible (Lookup l, T)
57 {
58 unsigned keyHash = prepareHash (l);
59 Entry *entry = findFreeEntry (keyHash);
60 entry->setLive (keyHash);
61 entryCount++;
62 }
63 };
64 template <class Key>
65 struct HashMapEntry { Key key; };
66 template <class Key, class Value, class HashPolicy = DebugOnly, class AllocPolicy = TempAllocPolicy>
67 struct 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;
allHashMap77 Range all () { return Range (); }
78 typedef typename Impl::Enum Enum;
79 };
80 class FreeOp;
81 struct AllocationSiteKey;
82 typedef HashMap <AllocationSiteKey, DebugOnly, AllocationSiteKey, TempAllocPolicy> AllocationSiteTable;
83 struct TypeCompartment
84 {
85 AllocationSiteTable *allocationSiteTable;
86 void sweep (FreeOp *);
87 };
88 struct JSScript { unsigned *code; };
89 bool IsScriptMarked (JSScript **);
90 struct AllocationSiteKey
91 {
92 JSScript *script;
93 unsigned offset : 24;
94 int kind;
95 typedef AllocationSiteKey Lookup;
hashAllocationSiteKey96 static unsigned hash (AllocationSiteKey key) { return (long (key.script->code + key.offset)) ^ key.kind; }
97 };
98 void
sweep(FreeOp *)99 TypeCompartment::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