Line data Source code
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 : #include "mozilla/DebugOnly.h"
8 :
9 : #include "jscompartment.h"
10 : #include "jsgc.h"
11 :
12 : #include "gc/GCInternals.h"
13 : #include "js/HashTable.h"
14 : #include "vm/Runtime.h"
15 :
16 : #include "jscntxtinlines.h"
17 : #include "jsgcinlines.h"
18 :
19 : using namespace js;
20 : using namespace js::gc;
21 :
22 : static void
23 0 : IterateCompartmentsArenasCellsUnbarriered(JSContext* cx, Zone* zone, void* data,
24 : JSIterateCompartmentCallback compartmentCallback,
25 : IterateArenaCallback arenaCallback,
26 : IterateCellCallback cellCallback)
27 : {
28 0 : for (CompartmentsInZoneIter comp(zone); !comp.done(); comp.next())
29 0 : (*compartmentCallback)(cx, data, comp);
30 :
31 0 : for (auto thingKind : AllAllocKinds()) {
32 0 : JS::TraceKind traceKind = MapAllocToTraceKind(thingKind);
33 0 : size_t thingSize = Arena::thingSize(thingKind);
34 :
35 0 : for (ArenaIter aiter(zone, thingKind); !aiter.done(); aiter.next()) {
36 0 : Arena* arena = aiter.get();
37 0 : (*arenaCallback)(cx->runtime(), data, arena, traceKind, thingSize);
38 0 : for (ArenaCellIterUnbarriered iter(arena); !iter.done(); iter.next())
39 0 : (*cellCallback)(cx->runtime(), data, iter.getCell(), traceKind, thingSize);
40 : }
41 : }
42 0 : }
43 :
44 : void
45 0 : js::IterateHeapUnbarriered(JSContext* cx, void* data,
46 : IterateZoneCallback zoneCallback,
47 : JSIterateCompartmentCallback compartmentCallback,
48 : IterateArenaCallback arenaCallback,
49 : IterateCellCallback cellCallback)
50 : {
51 0 : AutoPrepareForTracing prop(cx, WithAtoms);
52 :
53 0 : for (ZonesIter zone(cx->runtime(), WithAtoms); !zone.done(); zone.next()) {
54 0 : (*zoneCallback)(cx->runtime(), data, zone);
55 0 : IterateCompartmentsArenasCellsUnbarriered(cx, zone, data,
56 0 : compartmentCallback, arenaCallback, cellCallback);
57 : }
58 0 : }
59 :
60 : void
61 0 : js::IterateHeapUnbarrieredForZone(JSContext* cx, Zone* zone, void* data,
62 : IterateZoneCallback zoneCallback,
63 : JSIterateCompartmentCallback compartmentCallback,
64 : IterateArenaCallback arenaCallback,
65 : IterateCellCallback cellCallback)
66 : {
67 0 : AutoPrepareForTracing prop(cx, WithAtoms);
68 :
69 0 : (*zoneCallback)(cx->runtime(), data, zone);
70 : IterateCompartmentsArenasCellsUnbarriered(cx, zone, data,
71 0 : compartmentCallback, arenaCallback, cellCallback);
72 0 : }
73 :
74 : void
75 0 : js::IterateChunks(JSContext* cx, void* data, IterateChunkCallback chunkCallback)
76 : {
77 0 : AutoPrepareForTracing prep(cx, SkipAtoms);
78 :
79 0 : for (auto chunk = cx->runtime()->gc.allNonEmptyChunks(); !chunk.done(); chunk.next())
80 0 : chunkCallback(cx->runtime(), data, chunk);
81 0 : }
82 :
83 : void
84 0 : js::IterateScripts(JSContext* cx, JSCompartment* compartment,
85 : void* data, IterateScriptCallback scriptCallback)
86 : {
87 0 : MOZ_ASSERT(!cx->suppressGC);
88 0 : AutoEmptyNursery empty(cx);
89 0 : AutoPrepareForTracing prep(cx, SkipAtoms);
90 :
91 0 : if (compartment) {
92 0 : Zone* zone = compartment->zone();
93 0 : for (auto script = zone->cellIter<JSScript>(empty); !script.done(); script.next()) {
94 0 : if (script->compartment() == compartment)
95 0 : scriptCallback(cx->runtime(), data, script);
96 : }
97 : } else {
98 0 : for (ZonesIter zone(cx->runtime(), SkipAtoms); !zone.done(); zone.next()) {
99 0 : for (auto script = zone->cellIter<JSScript>(empty); !script.done(); script.next())
100 0 : scriptCallback(cx->runtime(), data, script);
101 : }
102 : }
103 0 : }
104 :
105 : static void
106 0 : IterateGrayObjects(Zone* zone, GCThingCallback cellCallback, void* data)
107 : {
108 0 : for (auto kind : ObjectAllocKinds()) {
109 0 : for (GrayObjectIter obj(zone, kind); !obj.done(); obj.next()) {
110 0 : if (obj->asTenured().isMarkedGray())
111 0 : cellCallback(data, JS::GCCellPtr(obj.get()));
112 : }
113 : }
114 0 : }
115 :
116 : void
117 0 : js::IterateGrayObjects(Zone* zone, GCThingCallback cellCallback, void* data)
118 : {
119 0 : MOZ_ASSERT(!JS::CurrentThreadIsHeapBusy());
120 0 : AutoPrepareForTracing prep(TlsContext.get(), SkipAtoms);
121 0 : ::IterateGrayObjects(zone, cellCallback, data);
122 0 : }
123 :
124 : void
125 0 : js::IterateGrayObjectsUnderCC(Zone* zone, GCThingCallback cellCallback, void* data)
126 : {
127 0 : mozilla::DebugOnly<JSRuntime*> rt = zone->runtimeFromActiveCooperatingThread();
128 0 : MOZ_ASSERT(JS::CurrentThreadIsHeapCycleCollecting());
129 0 : MOZ_ASSERT(!rt->gc.isIncrementalGCInProgress());
130 0 : ::IterateGrayObjects(zone, cellCallback, data);
131 0 : }
132 :
133 : JS_PUBLIC_API(void)
134 231 : JS_IterateCompartments(JSContext* cx, void* data,
135 : JSIterateCompartmentCallback compartmentCallback)
136 : {
137 462 : AutoTraceSession session(cx->runtime());
138 :
139 51975 : for (CompartmentsIter c(cx->runtime(), WithAtoms); !c.done(); c.next())
140 51744 : (*compartmentCallback)(cx, data, c);
141 231 : }
|