/src/mozilla-central/js/src/gc/Zone.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
2 | | * vim: set ts=8 sts=4 et sw=4 tw=99: |
3 | | * This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef gc_Zone_h |
8 | | #define gc_Zone_h |
9 | | |
10 | | #include "mozilla/Atomics.h" |
11 | | #include "mozilla/HashFunctions.h" |
12 | | |
13 | | #include "gc/FindSCCs.h" |
14 | | #include "js/GCHashTable.h" |
15 | | #include "vm/MallocProvider.h" |
16 | | #include "vm/Runtime.h" |
17 | | #include "vm/TypeInference.h" |
18 | | |
19 | | namespace js { |
20 | | |
21 | | class Debugger; |
22 | | class RegExpZone; |
23 | | |
24 | | namespace jit { |
25 | | class JitZone; |
26 | | } // namespace jit |
27 | | |
28 | | namespace gc { |
29 | | |
30 | | struct ZoneComponentFinder : public ComponentFinder<JS::Zone, ZoneComponentFinder> |
31 | | { |
32 | | ZoneComponentFinder(uintptr_t sl, JS::Zone* maybeAtomsZone) |
33 | | : ComponentFinder<JS::Zone, ZoneComponentFinder>(sl), maybeAtomsZone(maybeAtomsZone) |
34 | 18 | {} |
35 | | |
36 | | JS::Zone* maybeAtomsZone; |
37 | | }; |
38 | | |
39 | | struct UniqueIdGCPolicy { |
40 | | static bool needsSweep(Cell** cell, uint64_t* value); |
41 | | }; |
42 | | |
43 | | // Maps a Cell* to a unique, 64bit id. |
44 | | using UniqueIdMap = GCHashMap<Cell*, |
45 | | uint64_t, |
46 | | PointerHasher<Cell*>, |
47 | | SystemAllocPolicy, |
48 | | UniqueIdGCPolicy>; |
49 | | |
50 | | extern uint64_t NextCellUniqueId(JSRuntime* rt); |
51 | | |
52 | | template <typename T> |
53 | | class ZoneCellIter; |
54 | | |
55 | | } // namespace gc |
56 | | |
57 | | class MOZ_NON_TEMPORARY_CLASS ExternalStringCache |
58 | | { |
59 | | static const size_t NumEntries = 4; |
60 | | mozilla::Array<JSString*, NumEntries> entries_; |
61 | | |
62 | | ExternalStringCache(const ExternalStringCache&) = delete; |
63 | | void operator=(const ExternalStringCache&) = delete; |
64 | | |
65 | | public: |
66 | 9 | ExternalStringCache() { purge(); } |
67 | 27 | void purge() { mozilla::PodArrayZero(entries_); } |
68 | | |
69 | | MOZ_ALWAYS_INLINE JSString* lookup(const char16_t* chars, size_t len) const; |
70 | | MOZ_ALWAYS_INLINE void put(JSString* s); |
71 | | }; |
72 | | |
73 | | class MOZ_NON_TEMPORARY_CLASS FunctionToStringCache |
74 | | { |
75 | | struct Entry { |
76 | | JSScript* script; |
77 | | JSString* string; |
78 | | |
79 | 0 | void set(JSScript* scriptArg, JSString* stringArg) { |
80 | 0 | script = scriptArg; |
81 | 0 | string = stringArg; |
82 | 0 | } |
83 | | }; |
84 | | static const size_t NumEntries = 2; |
85 | | mozilla::Array<Entry, NumEntries> entries_; |
86 | | |
87 | | FunctionToStringCache(const FunctionToStringCache&) = delete; |
88 | | void operator=(const FunctionToStringCache&) = delete; |
89 | | |
90 | | public: |
91 | 9 | FunctionToStringCache() { purge(); } |
92 | 29 | void purge() { mozilla::PodArrayZero(entries_); } |
93 | | |
94 | | MOZ_ALWAYS_INLINE JSString* lookup(JSScript* script) const; |
95 | | MOZ_ALWAYS_INLINE void put(JSScript* script, JSString* string); |
96 | | }; |
97 | | |
98 | | } // namespace js |
99 | | |
100 | | namespace JS { |
101 | | |
102 | | // [SMDOC] GC Zones |
103 | | // |
104 | | // A zone is a collection of compartments. Every compartment belongs to exactly |
105 | | // one zone. In Firefox, there is roughly one zone per tab along with a system |
106 | | // zone for everything else. Zones mainly serve as boundaries for garbage |
107 | | // collection. Unlike compartments, they have no special security properties. |
108 | | // |
109 | | // Every GC thing belongs to exactly one zone. GC things from the same zone but |
110 | | // different compartments can share an arena (4k page). GC things from different |
111 | | // zones cannot be stored in the same arena. The garbage collector is capable of |
112 | | // collecting one zone at a time; it cannot collect at the granularity of |
113 | | // compartments. |
114 | | // |
115 | | // GC things are tied to zones and compartments as follows: |
116 | | // |
117 | | // - JSObjects belong to a compartment and cannot be shared between |
118 | | // compartments. If an object needs to point to a JSObject in a different |
119 | | // compartment, regardless of zone, it must go through a cross-compartment |
120 | | // wrapper. Each compartment keeps track of its outgoing wrappers in a table. |
121 | | // JSObjects find their compartment via their ObjectGroup. |
122 | | // |
123 | | // - JSStrings do not belong to any particular compartment, but they do belong |
124 | | // to a zone. Thus, two different compartments in the same zone can point to a |
125 | | // JSString. When a string needs to be wrapped, we copy it if it's in a |
126 | | // different zone and do nothing if it's in the same zone. Thus, transferring |
127 | | // strings within a zone is very efficient. |
128 | | // |
129 | | // - Shapes and base shapes belong to a zone and are shared between compartments |
130 | | // in that zone where possible. Accessor shapes store getter and setter |
131 | | // JSObjects which belong to a single compartment, so these shapes and all |
132 | | // their descendants can't be shared with other compartments. |
133 | | // |
134 | | // - Scripts are also compartment-local and cannot be shared. A script points to |
135 | | // its compartment. |
136 | | // |
137 | | // - ObjectGroup and JitCode objects belong to a compartment and cannot be |
138 | | // shared. There is no mechanism to obtain the compartment from a JitCode |
139 | | // object. |
140 | | // |
141 | | // A zone remains alive as long as any GC things in the zone are alive. A |
142 | | // compartment remains alive as long as any JSObjects, scripts, shapes, or base |
143 | | // shapes within it are alive. |
144 | | // |
145 | | // We always guarantee that a zone has at least one live compartment by refusing |
146 | | // to delete the last compartment in a live zone. |
147 | | class Zone : public JS::shadow::Zone, |
148 | | public js::gc::GraphNodeBase<JS::Zone>, |
149 | | public js::MallocProvider<JS::Zone> |
150 | | { |
151 | | public: |
152 | | explicit Zone(JSRuntime* rt); |
153 | | ~Zone(); |
154 | | MOZ_MUST_USE bool init(bool isSystem); |
155 | | void destroy(js::FreeOp *fop); |
156 | | |
157 | | private: |
158 | | enum class HelperThreadUse : uint32_t { |
159 | | None, |
160 | | Pending, |
161 | | Active |
162 | | }; |
163 | | mozilla::Atomic<HelperThreadUse, mozilla::SequentiallyConsistent, |
164 | | mozilla::recordreplay::Behavior::DontPreserve> helperThreadUse_; |
165 | | |
166 | | // The helper thread context with exclusive access to this zone, if |
167 | | // usedByHelperThread(), or nullptr when on the main thread. |
168 | | js::UnprotectedData<JSContext*> helperThreadOwnerContext_; |
169 | | |
170 | | public: |
171 | | bool ownedByCurrentHelperThread(); |
172 | | void setHelperThreadOwnerContext(JSContext* cx); |
173 | | |
174 | | // Whether this zone was created for use by a helper thread. |
175 | 639 | bool createdForHelperThread() const { |
176 | 639 | return helperThreadUse_ != HelperThreadUse::None; |
177 | 639 | } |
178 | | // Whether this zone is currently in use by a helper thread. |
179 | 30.9M | bool usedByHelperThread() { |
180 | 30.9M | MOZ_ASSERT_IF(isAtomsZone(), helperThreadUse_ == HelperThreadUse::None); |
181 | 30.9M | return helperThreadUse_ == HelperThreadUse::Active; |
182 | 30.9M | } |
183 | 0 | void setCreatedForHelperThread() { |
184 | 0 | MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::None); |
185 | 0 | helperThreadUse_ = HelperThreadUse::Pending; |
186 | 0 | } |
187 | 0 | void setUsedByHelperThread() { |
188 | 0 | MOZ_ASSERT(helperThreadUse_ == HelperThreadUse::Pending); |
189 | 0 | helperThreadUse_ = HelperThreadUse::Active; |
190 | 0 | } |
191 | 0 | void clearUsedByHelperThread() { |
192 | 0 | MOZ_ASSERT(helperThreadUse_ != HelperThreadUse::None); |
193 | 0 | helperThreadUse_ = HelperThreadUse::None; |
194 | 0 | } |
195 | | |
196 | | void findOutgoingEdges(js::gc::ZoneComponentFinder& finder); |
197 | | |
198 | | void discardJitCode(js::FreeOp* fop, bool discardBaselineCode = true); |
199 | | |
200 | | void addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, |
201 | | size_t* typePool, |
202 | | size_t* regexpZone, |
203 | | size_t* jitZone, |
204 | | size_t* baselineStubsOptimized, |
205 | | size_t* cachedCFG, |
206 | | size_t* uniqueIdMap, |
207 | | size_t* shapeTables, |
208 | | size_t* atomsMarkBitmaps, |
209 | | size_t* compartmentObjects, |
210 | | size_t* crossCompartmentWrappersTables, |
211 | | size_t* compartmentsPrivateData); |
212 | | |
213 | | // Iterate over all cells in the zone. See the definition of ZoneCellIter |
214 | | // in gc/GC-inl.h for the possible arguments and documentation. |
215 | | template <typename T, typename... Args> |
216 | 8 | js::gc::ZoneCellIter<T> cellIter(Args&&... args) { |
217 | 8 | return js::gc::ZoneCellIter<T>(const_cast<Zone*>(this), std::forward<Args>(args)...); |
218 | 8 | } js::gc::ZoneCellIter<JSScript> JS::Zone::cellIter<JSScript>() Line | Count | Source | 216 | 8 | js::gc::ZoneCellIter<T> cellIter(Args&&... args) { | 217 | 8 | return js::gc::ZoneCellIter<T>(const_cast<Zone*>(this), std::forward<Args>(args)...); | 218 | 8 | } |
Unexecuted instantiation: js::gc::ZoneCellIter<js::jit::JitCode> JS::Zone::cellIter<js::jit::JitCode>() Unexecuted instantiation: js::gc::ZoneCellIter<JSObject> JS::Zone::cellIter<JSObject, js::gc::AllocKind&>(js::gc::AllocKind&) Unexecuted instantiation: js::gc::ZoneCellIter<js::ObjectGroup> JS::Zone::cellIter<js::ObjectGroup>() Unexecuted instantiation: js::gc::ZoneCellIter<JSObject> JS::Zone::cellIter<JSObject, js::gc::AllocKind&, js::gc::AutoAssertEmptyNursery&>(js::gc::AllocKind&, js::gc::AutoAssertEmptyNursery&) Unexecuted instantiation: js::gc::ZoneCellIter<js::BaseShape> JS::Zone::cellIter<js::BaseShape>() Unexecuted instantiation: js::gc::ZoneCellIter<JSScript> JS::Zone::cellIter<JSScript, js::gc::AutoEmptyNursery&>(js::gc::AutoEmptyNursery&) Unexecuted instantiation: js::gc::ZoneCellIter<js::LazyScript> JS::Zone::cellIter<js::LazyScript, js::gc::AutoEmptyNursery&>(js::gc::AutoEmptyNursery&) |
219 | | |
220 | | MOZ_MUST_USE void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes, |
221 | | void* reallocPtr = nullptr); |
222 | | void reportAllocationOverflow(); |
223 | | |
224 | | void beginSweepTypes(bool releaseTypes); |
225 | | |
226 | | bool hasMarkedRealms(); |
227 | | |
228 | 300 | void scheduleGC() { MOZ_ASSERT(!RuntimeHeapIsBusy()); gcScheduled_ = true; } |
229 | 300 | void unscheduleGC() { gcScheduled_ = false; } |
230 | 636 | bool isGCScheduled() { return gcScheduled_; } |
231 | | |
232 | 68 | void setPreservingCode(bool preserving) { gcPreserveCode_ = preserving; } |
233 | 47 | bool isPreservingCode() const { return gcPreserveCode_; } |
234 | | |
235 | | // Whether this zone can currently be collected. This doesn't take account |
236 | | // of AutoKeepAtoms for the atoms zone. |
237 | | bool canCollect(); |
238 | | |
239 | 108 | void changeGCState(GCState prev, GCState next) { |
240 | 108 | MOZ_ASSERT(RuntimeHeapIsBusy()); |
241 | 108 | MOZ_ASSERT(gcState() == prev); |
242 | 108 | MOZ_ASSERT_IF(next != NoGC, canCollect()); |
243 | 108 | gcState_ = next; |
244 | 108 | } |
245 | | |
246 | 18.4k | bool isCollecting() const { |
247 | 18.4k | MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtimeFromMainThread())); |
248 | 18.4k | return isCollectingFromAnyThread(); |
249 | 18.4k | } |
250 | | |
251 | 20.5k | bool isCollectingFromAnyThread() const { |
252 | 20.5k | if (RuntimeHeapIsCollecting()) { |
253 | 2.43k | return gcState_ != NoGC; |
254 | 18.1k | } else { |
255 | 18.1k | return needsIncrementalBarrier(); |
256 | 18.1k | } |
257 | 20.5k | } |
258 | | |
259 | 3.44M | bool shouldMarkInZone() const { |
260 | 3.44M | return needsIncrementalBarrier() || isGCMarking(); |
261 | 3.44M | } |
262 | | |
263 | | // Get a number that is incremented whenever this zone is collected, and |
264 | | // possibly at other times too. |
265 | | uint64_t gcNumber(); |
266 | | |
267 | | void setNeedsIncrementalBarrier(bool needs); |
268 | 3 | const uint32_t* addressOfNeedsIncrementalBarrier() const { return &needsIncrementalBarrier_; } |
269 | | |
270 | 4 | js::jit::JitZone* getJitZone(JSContext* cx) { return jitZone_ ? jitZone_ : createJitZone(cx); } |
271 | 723 | js::jit::JitZone* jitZone() { return jitZone_; } |
272 | | |
273 | 3.65M | bool isAtomsZone() const { return runtimeFromAnyThread()->isAtomsZone(this); } |
274 | 0 | bool isSelfHostingZone() const { return runtimeFromAnyThread()->isSelfHostingZone(this); } |
275 | | |
276 | | void prepareForCompacting(); |
277 | | |
278 | | #ifdef DEBUG |
279 | | // If this returns true, all object tracing must be done with a GC marking |
280 | | // tracer. |
281 | | bool requireGCTracer() const; |
282 | | |
283 | | // For testing purposes, return the index of the sweep group which this zone |
284 | | // was swept in in the last GC. |
285 | | unsigned lastSweepGroupIndex() { return gcLastSweepGroupIndex; } |
286 | | #endif |
287 | | |
288 | | void sweepBreakpoints(js::FreeOp* fop); |
289 | | void sweepUniqueIds(); |
290 | | void sweepWeakMaps(); |
291 | | void sweepCompartments(js::FreeOp* fop, bool keepAtleastOne, bool lastGC); |
292 | | |
293 | | using DebuggerVector = js::Vector<js::Debugger*, 0, js::SystemAllocPolicy>; |
294 | | |
295 | | private: |
296 | | js::ZoneData<DebuggerVector*> debuggers; |
297 | | |
298 | | js::jit::JitZone* createJitZone(JSContext* cx); |
299 | | |
300 | 0 | bool isQueuedForBackgroundSweep() { |
301 | 0 | return isOnList(); |
302 | 0 | } |
303 | | |
304 | | // Side map for storing a unique ids for cells, independent of address. |
305 | | js::ZoneOrGCTaskData<js::gc::UniqueIdMap> uniqueIds_; |
306 | | |
307 | 40.9M | js::gc::UniqueIdMap& uniqueIds() { return uniqueIds_.ref(); } |
308 | | |
309 | | public: |
310 | 0 | bool hasDebuggers() const { return debuggers && debuggers->length(); } |
311 | 0 | DebuggerVector* getDebuggers() const { return debuggers; } |
312 | | DebuggerVector* getOrCreateDebuggers(JSContext* cx); |
313 | | |
314 | | void notifyObservingDebuggers(); |
315 | | |
316 | | void clearTables(); |
317 | | |
318 | | /* |
319 | | * When true, skip calling the metadata callback. We use this: |
320 | | * - to avoid invoking the callback recursively; |
321 | | * - to avoid observing lazy prototype setup (which confuses callbacks that |
322 | | * want to use the types being set up!); |
323 | | * - to avoid attaching allocation stacks to allocation stack nodes, which |
324 | | * is silly |
325 | | * And so on. |
326 | | */ |
327 | | js::ZoneData<bool> suppressAllocationMetadataBuilder; |
328 | | |
329 | | js::gc::ArenaLists arenas; |
330 | | |
331 | | private: |
332 | | // Number of allocations since the most recent minor GC for this thread. |
333 | | mozilla::Atomic<uint32_t, mozilla::Relaxed, mozilla::recordreplay::Behavior::DontPreserve> |
334 | | tenuredAllocsSinceMinorGC_; |
335 | | |
336 | | public: |
337 | 40.5M | void addTenuredAllocsSinceMinorGC(uint32_t allocs) { |
338 | 40.5M | tenuredAllocsSinceMinorGC_ += allocs; |
339 | 40.5M | } |
340 | | |
341 | 249 | uint32_t getAndResetTenuredAllocsSinceMinorGC() { |
342 | 249 | return tenuredAllocsSinceMinorGC_.exchange(0); |
343 | 249 | } |
344 | | |
345 | | js::TypeZone types; |
346 | | |
347 | | private: |
348 | | /* Live weakmaps in this zone. */ |
349 | | js::ZoneOrGCTaskData<mozilla::LinkedList<js::WeakMapBase>> gcWeakMapList_; |
350 | | public: |
351 | 91 | mozilla::LinkedList<js::WeakMapBase>& gcWeakMapList() { return gcWeakMapList_.ref(); } |
352 | | |
353 | | typedef js::Vector<JS::Compartment*, 1, js::SystemAllocPolicy> CompartmentVector; |
354 | | |
355 | | private: |
356 | | // The set of compartments in this zone. |
357 | | js::MainThreadOrGCTaskData<CompartmentVector> compartments_; |
358 | | public: |
359 | 4.18k | CompartmentVector& compartments() { return compartments_.ref(); } |
360 | | |
361 | | // This zone's gray roots. |
362 | | typedef js::Vector<js::gc::Cell*, 0, js::SystemAllocPolicy> GrayRootVector; |
363 | | private: |
364 | | js::ZoneOrGCTaskData<GrayRootVector> gcGrayRoots_; |
365 | | public: |
366 | 162 | GrayRootVector& gcGrayRoots() { return gcGrayRoots_.ref(); } |
367 | | |
368 | | // This zone's weak edges found via graph traversal during marking, |
369 | | // preserved for re-scanning during sweeping. |
370 | | using WeakEdges = js::Vector<js::gc::TenuredCell**, 0, js::SystemAllocPolicy>; |
371 | | private: |
372 | | js::ZoneOrGCTaskData<WeakEdges> gcWeakRefs_; |
373 | | public: |
374 | 36 | WeakEdges& gcWeakRefs() { return gcWeakRefs_.ref(); } |
375 | | |
376 | | private: |
377 | | // List of non-ephemeron weak containers to sweep during beginSweepingSweepGroup. |
378 | | js::ZoneOrGCTaskData<mozilla::LinkedList<detail::WeakCacheBase>> weakCaches_; |
379 | | public: |
380 | 103 | mozilla::LinkedList<detail::WeakCacheBase>& weakCaches() { return weakCaches_.ref(); } |
381 | 67 | void registerWeakCache(detail::WeakCacheBase* cachep) { |
382 | 67 | weakCaches().insertBack(cachep); |
383 | 67 | } |
384 | | |
385 | | private: |
386 | | /* |
387 | | * Mapping from not yet marked keys to a vector of all values that the key |
388 | | * maps to in any live weak map. |
389 | | */ |
390 | | js::ZoneOrGCTaskData<js::gc::WeakKeyTable> gcWeakKeys_; |
391 | | public: |
392 | 81 | js::gc::WeakKeyTable& gcWeakKeys() { return gcWeakKeys_.ref(); } |
393 | | |
394 | | private: |
395 | | // A set of edges from this zone to other zones. |
396 | | // |
397 | | // This is used during GC while calculating sweep groups to record edges |
398 | | // that can't be determined by examining this zone by itself. |
399 | | js::MainThreadData<ZoneSet> gcSweepGroupEdges_; |
400 | | |
401 | | public: |
402 | 36 | ZoneSet& gcSweepGroupEdges() { return gcSweepGroupEdges_.ref(); } |
403 | | |
404 | | // Keep track of all TypeDescr and related objects in this compartment. |
405 | | // This is used by the GC to trace them all first when compacting, since the |
406 | | // TypedObject trace hook may access these objects. |
407 | | // |
408 | | // There are no barriers here - the set contains only tenured objects so no |
409 | | // post-barrier is required, and these are weak references so no pre-barrier |
410 | | // is required. |
411 | | using TypeDescrObjectSet = js::GCHashSet<JSObject*, |
412 | | js::MovableCellHasher<JSObject*>, |
413 | | js::SystemAllocPolicy>; |
414 | | private: |
415 | | js::ZoneData<JS::WeakCache<TypeDescrObjectSet>> typeDescrObjects_; |
416 | | |
417 | | // Malloc counter to measure memory pressure for GC scheduling. This |
418 | | // counter should be used only when it's not possible to know the size of |
419 | | // a free. |
420 | | js::gc::MemoryCounter gcMallocCounter; |
421 | | |
422 | | // Counter of JIT code executable memory for GC scheduling. Also imprecise, |
423 | | // since wasm can generate code that outlives a zone. |
424 | | js::gc::MemoryCounter jitCodeCounter; |
425 | | |
426 | 8.12M | void updateMemoryCounter(js::gc::MemoryCounter& counter, size_t nbytes) { |
427 | 8.12M | JSRuntime* rt = runtimeFromAnyThread(); |
428 | 8.12M | |
429 | 8.12M | counter.update(nbytes); |
430 | 8.12M | auto trigger = counter.shouldTriggerGC(rt->gc.tunables); |
431 | 8.12M | if (MOZ_LIKELY(trigger == js::gc::NoTrigger) || trigger <= counter.triggered()) { |
432 | 8.12M | return; |
433 | 8.12M | } |
434 | 0 | |
435 | 0 | maybeTriggerGCForTooMuchMalloc(counter, trigger); |
436 | 0 | } |
437 | | |
438 | | void maybeTriggerGCForTooMuchMalloc(js::gc::MemoryCounter& counter, |
439 | | js::gc::TriggerKind trigger); |
440 | | |
441 | | js::MainThreadData<js::UniquePtr<js::RegExpZone>> regExps_; |
442 | | |
443 | | public: |
444 | 0 | js::RegExpZone& regExps() { return *regExps_.ref(); } |
445 | | |
446 | 0 | JS::WeakCache<TypeDescrObjectSet>& typeDescrObjects() { return typeDescrObjects_.ref(); } |
447 | | |
448 | | bool addTypeDescrObject(JSContext* cx, HandleObject obj); |
449 | | |
450 | 18 | void setGCMaxMallocBytes(size_t value, const js::AutoLockGC& lock) { |
451 | 18 | gcMallocCounter.setMax(value, lock); |
452 | 18 | } |
453 | 8.12M | void updateMallocCounter(size_t nbytes) { |
454 | 8.12M | updateMemoryCounter(gcMallocCounter, nbytes); |
455 | 8.12M | } |
456 | 0 | void adoptMallocBytes(Zone* other) { |
457 | 0 | gcMallocCounter.adopt(other->gcMallocCounter); |
458 | 0 | } |
459 | 0 | size_t GCMaxMallocBytes() const { return gcMallocCounter.maxBytes(); } |
460 | 0 | size_t GCMallocBytes() const { return gcMallocCounter.bytes(); } |
461 | | |
462 | 140 | void updateJitCodeMallocBytes(size_t nbytes) { |
463 | 140 | updateMemoryCounter(jitCodeCounter, nbytes); |
464 | 140 | } |
465 | | |
466 | | void updateAllGCMallocCountersOnGCStart(); |
467 | | void updateAllGCMallocCountersOnGCEnd(const js::AutoLockGC& lock); |
468 | | js::gc::TriggerKind shouldTriggerGCForTooMuchMalloc(); |
469 | | |
470 | 16 | void keepAtoms() { |
471 | 16 | keepAtomsCount++; |
472 | 16 | } |
473 | | void releaseAtoms(); |
474 | 52 | bool hasKeptAtoms() const { |
475 | 52 | return keepAtomsCount; |
476 | 52 | } |
477 | | |
478 | | private: |
479 | | // Bitmap of atoms marked by this zone. |
480 | | js::ZoneOrGCTaskData<js::SparseBitmap> markedAtoms_; |
481 | | |
482 | | // Set of atoms recently used by this Zone. Purged on GC unless |
483 | | // keepAtomsCount is non-zero. |
484 | | js::ZoneOrGCTaskData<js::AtomSet> atomCache_; |
485 | | |
486 | | // Cache storing allocated external strings. Purged on GC. |
487 | | js::ZoneOrGCTaskData<js::ExternalStringCache> externalStringCache_; |
488 | | |
489 | | // Cache for Function.prototype.toString. Purged on GC. |
490 | | js::ZoneOrGCTaskData<js::FunctionToStringCache> functionToStringCache_; |
491 | | |
492 | | // Count of AutoKeepAtoms instances for this zone. When any instances exist, |
493 | | // atoms in the runtime will be marked from this zone's atom mark bitmap, |
494 | | // rather than when traced in the normal way. Threads parsing off the main |
495 | | // thread do not increment this value, but the presence of any such threads |
496 | | // also inhibits collection of atoms. We don't scan the stacks of exclusive |
497 | | // threads, so we need to avoid collecting their objects in another way. The |
498 | | // only GC thing pointers they have are to their exclusive compartment |
499 | | // (which is not collected) or to the atoms compartment. Therefore, we avoid |
500 | | // collecting the atoms zone when exclusive threads are running. |
501 | | js::ZoneOrGCTaskData<unsigned> keepAtomsCount; |
502 | | |
503 | | // Whether purging atoms was deferred due to keepAtoms being set. If this |
504 | | // happen then the cache will be purged when keepAtoms drops to zero. |
505 | | js::ZoneOrGCTaskData<bool> purgeAtomsDeferred; |
506 | | |
507 | | public: |
508 | 885 | js::SparseBitmap& markedAtoms() { return markedAtoms_.ref(); } |
509 | | |
510 | 49.1k | js::AtomSet& atomCache() { return atomCache_.ref(); } |
511 | | |
512 | | void traceAtomCache(JSTracer* trc); |
513 | | void purgeAtomCacheOrDefer(); |
514 | | void purgeAtomCache(); |
515 | | |
516 | 21 | js::ExternalStringCache& externalStringCache() { return externalStringCache_.ref(); }; |
517 | | |
518 | 20 | js::FunctionToStringCache& functionToStringCache() { return functionToStringCache_.ref(); } |
519 | | |
520 | | // Track heap usage under this Zone. |
521 | | js::gc::HeapUsage usage; |
522 | | |
523 | | // Thresholds used to trigger GC. |
524 | | js::gc::ZoneHeapThreshold threshold; |
525 | | |
526 | | // Amount of data to allocate before triggering a new incremental slice for |
527 | | // the current GC. |
528 | | js::UnprotectedData<size_t> gcDelayBytes; |
529 | | |
530 | | js::ZoneData<uint32_t> tenuredStrings; |
531 | | js::ZoneData<bool> allocNurseryStrings; |
532 | | |
533 | | private: |
534 | | // Shared Shape property tree. |
535 | | js::ZoneData<js::PropertyTree> propertyTree_; |
536 | | public: |
537 | 3.25M | js::PropertyTree& propertyTree() { return propertyTree_.ref(); } |
538 | | |
539 | | private: |
540 | | // Set of all unowned base shapes in the Zone. |
541 | | js::ZoneData<js::BaseShapeSet> baseShapes_; |
542 | | public: |
543 | 1.62M | js::BaseShapeSet& baseShapes() { return baseShapes_.ref(); } |
544 | | |
545 | | private: |
546 | | // Set of initial shapes in the Zone. For certain prototypes -- namely, |
547 | | // those of various builtin classes -- there are two entries: one for a |
548 | | // lookup via TaggedProto, and one for a lookup via JSProtoKey. See |
549 | | // InitialShapeProto. |
550 | | js::ZoneData<js::InitialShapeSet> initialShapes_; |
551 | | public: |
552 | 8.16M | js::InitialShapeSet& initialShapes() { return initialShapes_.ref(); } |
553 | | |
554 | | private: |
555 | | // List of shapes that may contain nursery pointers. |
556 | | using NurseryShapeVector = js::Vector<js::AccessorShape*, 0, js::SystemAllocPolicy>; |
557 | | js::ZoneData<NurseryShapeVector> nurseryShapes_; |
558 | | public: |
559 | 52 | NurseryShapeVector& nurseryShapes() { return nurseryShapes_.ref(); } |
560 | | |
561 | | #ifdef JSGC_HASH_TABLE_CHECKS |
562 | | void checkInitialShapesTableAfterMovingGC(); |
563 | | void checkBaseShapeTableAfterMovingGC(); |
564 | | #endif |
565 | | void fixupInitialShapeTable(); |
566 | | void fixupAfterMovingGC(); |
567 | | |
568 | | // Per-zone data for use by an embedder. |
569 | | js::ZoneData<void*> data; |
570 | | |
571 | | js::ZoneData<bool> isSystem; |
572 | | |
573 | | #ifdef DEBUG |
574 | | js::MainThreadData<unsigned> gcLastSweepGroupIndex; |
575 | | #endif |
576 | | |
577 | | static js::HashNumber UniqueIdToHash(uint64_t uid); |
578 | | |
579 | | // Creates a HashNumber based on getUniqueId. Returns false on OOM. |
580 | | MOZ_MUST_USE bool getHashCode(js::gc::Cell* cell, js::HashNumber* hashp); |
581 | | |
582 | | // Gets an existing UID in |uidp| if one exists. |
583 | | MOZ_MUST_USE bool maybeGetUniqueId(js::gc::Cell* cell, uint64_t* uidp); |
584 | | |
585 | | // Puts an existing UID in |uidp|, or creates a new UID for this Cell and |
586 | | // puts that into |uidp|. Returns false on OOM. |
587 | | MOZ_MUST_USE bool getOrCreateUniqueId(js::gc::Cell* cell, uint64_t* uidp); |
588 | | |
589 | | js::HashNumber getHashCodeInfallible(js::gc::Cell* cell); |
590 | | uint64_t getUniqueIdInfallible(js::gc::Cell* cell); |
591 | | |
592 | | // Return true if this cell has a UID associated with it. |
593 | | MOZ_MUST_USE bool hasUniqueId(js::gc::Cell* cell); |
594 | | |
595 | | // Transfer an id from another cell. This must only be called on behalf of a |
596 | | // moving GC. This method is infallible. |
597 | | void transferUniqueId(js::gc::Cell* tgt, js::gc::Cell* src); |
598 | | |
599 | | // Remove any unique id associated with this Cell. |
600 | | void removeUniqueId(js::gc::Cell* cell); |
601 | | |
602 | | // When finished parsing off-thread, transfer any UIDs we created in the |
603 | | // off-thread zone into the target zone. |
604 | | void adoptUniqueIds(JS::Zone* source); |
605 | | |
606 | | #ifdef JSGC_HASH_TABLE_CHECKS |
607 | | // Assert that the UniqueId table has been redirected successfully. |
608 | | void checkUniqueIdTableAfterMovingGC(); |
609 | | #endif |
610 | | |
611 | 3.25M | bool keepShapeTables() const { |
612 | 3.25M | return keepShapeTables_; |
613 | 3.25M | } |
614 | 6.50M | void setKeepShapeTables(bool b) { |
615 | 6.50M | keepShapeTables_ = b; |
616 | 6.50M | } |
617 | | |
618 | | // Delete an empty compartment after its contents have been merged. |
619 | | void deleteEmptyCompartment(JS::Compartment* comp); |
620 | | |
621 | | // Non-zero if the storage underlying any typed object in this zone might |
622 | | // be detached. This is stored in Zone because IC stubs bake in a pointer |
623 | | // to this field and Baseline IC code is shared across realms within a |
624 | | // Zone. Furthermore, it's not entirely clear if this flag is ever set to |
625 | | // a non-zero value since bug 1458011. |
626 | | uint32_t detachedTypedObjects = 0; |
627 | | |
628 | | private: |
629 | | js::ZoneOrGCTaskData<js::jit::JitZone*> jitZone_; |
630 | | |
631 | | js::MainThreadData<bool> gcScheduled_; |
632 | | js::MainThreadData<bool> gcScheduledSaved_; |
633 | | js::MainThreadData<bool> gcPreserveCode_; |
634 | | js::ZoneData<bool> keepShapeTables_; |
635 | | |
636 | | // Allow zones to be linked into a list |
637 | | friend class js::gc::ZoneList; |
638 | | static Zone * const NotOnList; |
639 | | js::MainThreadOrGCTaskData<Zone*> listNext_; |
640 | | bool isOnList() const; |
641 | | Zone* nextZone() const; |
642 | | |
643 | | friend bool js::CurrentThreadCanAccessZone(Zone* zone); |
644 | | friend class js::gc::GCRuntime; |
645 | | }; |
646 | | |
647 | | } // namespace JS |
648 | | |
649 | | namespace js { |
650 | | |
651 | | /* |
652 | | * Allocation policy that uses Zone::pod_malloc and friends, so that memory |
653 | | * pressure is accounted for on the zone. This is suitable for memory associated |
654 | | * with GC things allocated in the zone. |
655 | | * |
656 | | * Since it doesn't hold a JSContext (those may not live long enough), it can't |
657 | | * report out-of-memory conditions itself; the caller must check for OOM and |
658 | | * take the appropriate action. |
659 | | * |
660 | | * FIXME bug 647103 - replace these *AllocPolicy names. |
661 | | */ |
662 | | class ZoneAllocPolicy |
663 | | { |
664 | | JS::Zone* const zone; |
665 | | |
666 | | public: |
667 | 14 | MOZ_IMPLICIT ZoneAllocPolicy(JS::Zone* z) : zone(z) {} |
668 | | |
669 | 1 | template <typename T> T* maybe_pod_malloc(size_t numElems) { |
670 | 1 | return zone->maybe_pod_malloc<T>(numElems); |
671 | 1 | } Unexecuted instantiation: mozilla::detail::HashTableEntry<js::ReadBarriered<js::RegExpShared*> const>* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<js::ReadBarriered<js::RegExpShared*> const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JS::Value> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JS::Value> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<unsigned long const>* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<unsigned long const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<jsid, js::IndirectBindingMap::Binding> >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<jsid, js::IndirectBindingMap::Binding> > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JSObject*> > > >(unsigned long) mozilla::detail::HashTableEntry<mozilla::HashMapEntry<unsigned int, js::ReadBarriered<js::jit::JitCode*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<unsigned int, js::ReadBarriered<js::jit::JitCode*> > > >(unsigned long) Line | Count | Source | 669 | 1 | template <typename T> T* maybe_pod_malloc(size_t numElems) { | 670 | 1 | return zone->maybe_pod_malloc<T>(numElems); | 671 | 1 | } |
Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Zone*, unsigned long> >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Zone*, unsigned long> > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::WasmInstanceObject*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::WasmInstanceObject*>, js::HeapPtr<JSObject*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::LazyScript*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::LazyScript*>, js::HeapPtr<JSObject*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSScript*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSScript*>, js::HeapPtr<JSObject*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<js::ReadBarriered<js::GlobalObject*> const>* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<js::ReadBarriered<js::GlobalObject*> const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::AbstractFramePtr, js::HeapPtr<js::DebuggerFrame*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::AbstractFramePtr, js::HeapPtr<js::DebuggerFrame*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<JS::Realm* const>* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<JS::Realm* const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Realm*, JSScript*> >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Realm*, JSScript*> > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<JSObject* const>* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<JSObject* const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::MissingEnvironmentKey, js::ReadBarriered<js::DebugEnvironmentProxy*> > >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::MissingEnvironmentKey, js::ReadBarriered<js::DebugEnvironmentProxy*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::ReadBarriered<JSObject*>, js::LiveEnvironmentVal> >* js::ZoneAllocPolicy::maybe_pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::ReadBarriered<JSObject*>, js::LiveEnvironmentVal> > >(unsigned long) |
672 | | template <typename T> T* maybe_pod_calloc(size_t numElems) { |
673 | | return zone->maybe_pod_calloc<T>(numElems); |
674 | | } |
675 | | template <typename T> T* maybe_pod_realloc(T* p, size_t oldSize, size_t newSize) { |
676 | | return zone->maybe_pod_realloc<T>(p, oldSize, newSize); |
677 | | } |
678 | 3 | template <typename T> T* pod_malloc(size_t numElems) { |
679 | 3 | return zone->pod_malloc<T>(numElems); |
680 | 3 | } Unexecuted instantiation: mozilla::detail::HashTableEntry<js::ReadBarriered<js::RegExpShared*> const>* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<js::ReadBarriered<js::RegExpShared*> const> >(unsigned long) mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JS::Value> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JS::Value> > > >(unsigned long) Line | Count | Source | 678 | 1 | template <typename T> T* pod_malloc(size_t numElems) { | 679 | 1 | return zone->pod_malloc<T>(numElems); | 680 | 1 | } |
Unexecuted instantiation: mozilla::detail::HashTableEntry<unsigned long const>* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<unsigned long const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<jsid, js::IndirectBindingMap::Binding> >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<jsid, js::IndirectBindingMap::Binding> > >(unsigned long) Unexecuted instantiation: js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data** js::ZoneAllocPolicy::pod_malloc<js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data*>(unsigned long) Unexecuted instantiation: js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data* js::ZoneAllocPolicy::pod_malloc<js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data>(unsigned long) Unexecuted instantiation: js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data** js::ZoneAllocPolicy::pod_malloc<js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data*>(unsigned long) Unexecuted instantiation: js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data* js::ZoneAllocPolicy::pod_malloc<js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data>(unsigned long) Unexecuted instantiation: js::FunctionDeclaration* js::ZoneAllocPolicy::pod_malloc<js::FunctionDeclaration>(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JSObject*> > > >(unsigned long) mozilla::detail::HashTableEntry<mozilla::HashMapEntry<unsigned int, js::ReadBarriered<js::jit::JitCode*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<unsigned int, js::ReadBarriered<js::jit::JitCode*> > > >(unsigned long) Line | Count | Source | 678 | 2 | template <typename T> T* pod_malloc(size_t numElems) { | 679 | 2 | return zone->pod_malloc<T>(numElems); | 680 | 2 | } |
Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Zone*, unsigned long> >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Zone*, unsigned long> > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::WasmInstanceObject*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::WasmInstanceObject*>, js::HeapPtr<JSObject*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::LazyScript*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::LazyScript*>, js::HeapPtr<JSObject*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSScript*>, js::HeapPtr<JSObject*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSScript*>, js::HeapPtr<JSObject*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<js::ReadBarriered<js::GlobalObject*> const>* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<js::ReadBarriered<js::GlobalObject*> const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::AbstractFramePtr, js::HeapPtr<js::DebuggerFrame*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::AbstractFramePtr, js::HeapPtr<js::DebuggerFrame*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<JS::Realm* const>* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<JS::Realm* const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Realm*, JSScript*> >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Realm*, JSScript*> > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<JSObject* const>* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<JSObject* const> >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::MissingEnvironmentKey, js::ReadBarriered<js::DebugEnvironmentProxy*> > >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::MissingEnvironmentKey, js::ReadBarriered<js::DebugEnvironmentProxy*> > > >(unsigned long) Unexecuted instantiation: mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::ReadBarriered<JSObject*>, js::LiveEnvironmentVal> >* js::ZoneAllocPolicy::pod_malloc<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::ReadBarriered<JSObject*>, js::LiveEnvironmentVal> > >(unsigned long) |
681 | | template <typename T> T* pod_calloc(size_t numElems) { |
682 | | return zone->pod_calloc<T>(numElems); |
683 | | } |
684 | | template <typename T> T* pod_realloc(T* p, size_t oldSize, size_t newSize) { |
685 | | return zone->pod_realloc<T>(p, oldSize, newSize); |
686 | | } |
687 | | |
688 | 4 | template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); } void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JS::Value> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JS::Value> > >*, unsigned long) Line | Count | Source | 688 | 1 | template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); } |
Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<js::ReadBarriered<js::RegExpShared*> const> >(mozilla::detail::HashTableEntry<js::ReadBarriered<js::RegExpShared*> const>*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<unsigned long const> >(mozilla::detail::HashTableEntry<unsigned long const>*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<jsid, js::IndirectBindingMap::Binding> > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<jsid, js::IndirectBindingMap::Binding> >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data*>(js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data**, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data>(js::detail::OrderedHashTable<js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::Entry, js::OrderedHashMap<js::HashableValue, js::HeapPtr<JS::Value>, js::HashableValue::Hasher, js::ZoneAllocPolicy>::MapOps, js::ZoneAllocPolicy>::Data*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data*>(js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data**, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data>(js::detail::OrderedHashTable<js::HashableValue, js::OrderedHashSet<js::HashableValue, js::HashableValue::Hasher, js::ZoneAllocPolicy>::SetOps, js::ZoneAllocPolicy>::Data*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<js::FunctionDeclaration>(js::FunctionDeclaration*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JSObject*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSObject*>, js::HeapPtr<JSObject*> > >*, unsigned long) void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<unsigned int, js::ReadBarriered<js::jit::JitCode*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<unsigned int, js::ReadBarriered<js::jit::JitCode*> > >*, unsigned long) Line | Count | Source | 688 | 3 | template <typename T> void free_(T* p, size_t numElems = 0) { js_free(p); } |
Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Zone*, unsigned long> > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Zone*, unsigned long> >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::WasmInstanceObject*>, js::HeapPtr<JSObject*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::WasmInstanceObject*>, js::HeapPtr<JSObject*> > >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::LazyScript*>, js::HeapPtr<JSObject*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<js::LazyScript*>, js::HeapPtr<JSObject*> > >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSScript*>, js::HeapPtr<JSObject*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::HeapPtr<JSScript*>, js::HeapPtr<JSObject*> > >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::AbstractFramePtr, js::HeapPtr<js::DebuggerFrame*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::AbstractFramePtr, js::HeapPtr<js::DebuggerFrame*> > >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<js::ReadBarriered<js::GlobalObject*> const> >(mozilla::detail::HashTableEntry<js::ReadBarriered<js::GlobalObject*> const>*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<JS::Realm* const> >(mozilla::detail::HashTableEntry<JS::Realm* const>*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Realm*, JSScript*> > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<JS::Realm*, JSScript*> >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<JSObject* const> >(mozilla::detail::HashTableEntry<JSObject* const>*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::ReadBarriered<JSObject*>, js::LiveEnvironmentVal> > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::ReadBarriered<JSObject*>, js::LiveEnvironmentVal> >*, unsigned long) Unexecuted instantiation: void js::ZoneAllocPolicy::free_<mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::MissingEnvironmentKey, js::ReadBarriered<js::DebugEnvironmentProxy*> > > >(mozilla::detail::HashTableEntry<mozilla::HashMapEntry<js::MissingEnvironmentKey, js::ReadBarriered<js::DebugEnvironmentProxy*> > >*, unsigned long) |
689 | 0 | void reportAllocOverflow() const {} |
690 | | |
691 | 38 | MOZ_MUST_USE bool checkSimulatedOOM() const { |
692 | 38 | return !js::oom::ShouldFailWithOOM(); |
693 | 38 | } |
694 | | }; |
695 | | |
696 | | } // namespace js |
697 | | |
698 | | #endif // gc_Zone_h |