-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathZone-inl.h
141 lines (117 loc) · 4.15 KB
/
Zone-inl.h
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef gc_Zone_inl_h
#define gc_Zone_inl_h
#include "gc/Zone.h"
#ifdef DEBUG
inline bool JS::Zone::requireGCTracer() const {
JSRuntime* rt = runtimeFromAnyThread();
return RuntimeHeapIsMajorCollecting() && !rt->gc.isHeapCompacting() &&
gcState_ != NoGC;
}
#endif
inline void JS::Zone::updateAllGCMallocCountersOnGCStart() {
gcMallocCounter.updateOnGCStart();
jitCodeCounter.updateOnGCStart();
}
inline void JS::Zone::updateAllGCMallocCountersOnGCEnd(
const js::AutoLockGC& lock) {
auto& gc = runtimeFromAnyThread()->gc;
gcMallocCounter.updateOnGCEnd(gc.tunables, lock);
jitCodeCounter.updateOnGCEnd(gc.tunables, lock);
}
inline js::gc::TriggerKind JS::Zone::shouldTriggerGCForTooMuchMalloc() {
auto& gc = runtimeFromAnyThread()->gc;
return std::max(gcMallocCounter.shouldTriggerGC(gc.tunables),
jitCodeCounter.shouldTriggerGC(gc.tunables));
}
/* static */ inline js::HashNumber JS::Zone::UniqueIdToHash(uint64_t uid) {
return mozilla::HashGeneric(uid);
}
inline bool JS::Zone::getHashCode(js::gc::Cell* cell, js::HashNumber* hashp) {
uint64_t uid;
if (!getOrCreateUniqueId(cell, &uid)) {
return false;
}
*hashp = UniqueIdToHash(uid);
return true;
}
inline bool JS::Zone::maybeGetUniqueId(js::gc::Cell* cell, uint64_t* uidp) {
MOZ_ASSERT(uidp);
MOZ_ASSERT(js::CurrentThreadCanAccessZone(this));
// Get an existing uid, if one has been set.
auto p = uniqueIds().lookup(cell);
if (p) {
*uidp = p->value();
}
return p.found();
}
inline bool JS::Zone::getOrCreateUniqueId(js::gc::Cell* cell, uint64_t* uidp) {
MOZ_ASSERT(uidp);
MOZ_ASSERT(js::CurrentThreadCanAccessZone(this) ||
js::CurrentThreadIsPerformingGC());
// Get an existing uid, if one has been set.
auto p = uniqueIds().lookupForAdd(cell);
if (p) {
*uidp = p->value();
return true;
}
MOZ_ASSERT(js::CurrentThreadCanAccessZone(this));
// Set a new uid on the cell.
*uidp = js::gc::NextCellUniqueId(runtimeFromAnyThread());
if (!uniqueIds().add(p, cell, *uidp)) {
return false;
}
// If the cell was in the nursery, hopefully unlikely, then we need to
// tell the nursery about it so that it can sweep the uid if the thing
// does not get tenured.
if (IsInsideNursery(cell) &&
!runtimeFromMainThread()->gc.nursery().addedUniqueIdToCell(cell)) {
uniqueIds().remove(cell);
return false;
}
return true;
}
inline js::HashNumber JS::Zone::getHashCodeInfallible(js::gc::Cell* cell) {
return UniqueIdToHash(getUniqueIdInfallible(cell));
}
inline uint64_t JS::Zone::getUniqueIdInfallible(js::gc::Cell* cell) {
uint64_t uid;
js::AutoEnterOOMUnsafeRegion oomUnsafe;
if (!getOrCreateUniqueId(cell, &uid)) {
oomUnsafe.crash("failed to allocate uid");
}
return uid;
}
inline bool JS::Zone::hasUniqueId(js::gc::Cell* cell) {
MOZ_ASSERT(js::CurrentThreadCanAccessZone(this) ||
js::CurrentThreadIsPerformingGC());
return uniqueIds().has(cell);
}
inline void JS::Zone::transferUniqueId(js::gc::Cell* tgt, js::gc::Cell* src) {
MOZ_ASSERT(src != tgt);
MOZ_ASSERT(!IsInsideNursery(tgt));
MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtimeFromMainThread()));
MOZ_ASSERT(js::CurrentThreadCanAccessZone(this));
MOZ_ASSERT(!uniqueIds().has(tgt));
uniqueIds().rekeyIfMoved(src, tgt);
}
inline void JS::Zone::removeUniqueId(js::gc::Cell* cell) {
MOZ_ASSERT(js::CurrentThreadCanAccessZone(this));
uniqueIds().remove(cell);
}
inline void JS::Zone::adoptUniqueIds(JS::Zone* source) {
js::AutoEnterOOMUnsafeRegion oomUnsafe;
for (js::gc::UniqueIdMap::Enum e(source->uniqueIds()); !e.empty();
e.popFront()) {
MOZ_ASSERT(!uniqueIds().has(e.front().key()));
if (!uniqueIds().put(e.front().key(), e.front().value())) {
oomUnsafe.crash("failed to transfer unique ids from off-thread");
}
}
source->uniqueIds().clear();
}
#endif // gc_Zone_inl_h