111
|
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;
|
|
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 {
|
|
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 };
|
|
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;
|
|
77 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;
|
|
96 static unsigned hash (AllocationSiteKey key) { return (long (key.script->code + key.offset)) ^ key.kind; }
|
|
97 };
|
|
98 void
|
|
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 }
|