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