Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / gcc / testsuite / g++.dg / opt / pr55717.C
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 }