1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
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/. */
7 /* Shadow definition of |JS::Zone| innards. Do not use this directly! */
9 #ifndef js_shadow_Zone_h
10 #define js_shadow_Zone_h
12 #include "mozilla/Assertions.h" // MOZ_ASSERT
13 #include "mozilla/Atomics.h"
15 #include <stdint.h> // uint8_t, uint32_t
17 #include "jspubtd.h" // js::CurrentThreadCanAccessRuntime
18 #include "jstypes.h" // js::Bit
20 struct JS_PUBLIC_API JSRuntime
;
21 class JS_PUBLIC_API JSTracer
;
28 enum GCState
: uint32_t {
41 using BarrierState
= mozilla::Atomic
<uint32_t, mozilla::Relaxed
>;
43 enum Kind
: uint8_t { NormalZone
, AtomsZone
, SystemZone
};
46 JSRuntime
* const runtime_
;
47 JSTracer
* const barrierTracer_
; // A pointer to the JSRuntime's |gcMarker|.
48 BarrierState needsIncrementalBarrier_
;
49 GCState gcState_
= NoGC
;
52 Zone(JSRuntime
* runtime
, JSTracer
* barrierTracerArg
, Kind kind
)
53 : runtime_(runtime
), barrierTracer_(barrierTracerArg
), kind_(kind
) {
54 MOZ_ASSERT(!needsIncrementalBarrier());
58 bool needsIncrementalBarrier() const { return needsIncrementalBarrier_
; }
60 JSTracer
* barrierTracer() {
61 MOZ_ASSERT(needsIncrementalBarrier_
);
62 MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_
));
63 return barrierTracer_
;
66 JSRuntime
* runtimeFromMainThread() const {
67 MOZ_ASSERT(js::CurrentThreadCanAccessRuntime(runtime_
));
71 // Note: Unrestricted access to the zone's runtime from an arbitrary
72 // thread can easily lead to races. Use this method very carefully.
73 JSRuntime
* runtimeFromAnyThread() const { return runtime_
; }
75 GCState
gcState() const { return GCState(uint32_t(gcState_
)); }
77 static constexpr uint32_t gcStateMask(GCState state
) {
78 static_assert(uint32_t(Limit
) < 32);
79 return js::Bit(state
);
82 bool hasAnyGCState(uint32_t stateMask
) const {
83 return js::Bit(gcState_
) & stateMask
;
86 bool wasGCStarted() const { return gcState() != NoGC
; }
87 bool isGCPreparing() const { return gcState() == Prepare
; }
88 bool isGCMarkingBlackOnly() const { return gcState() == MarkBlackOnly
; }
89 bool isGCMarkingBlackAndGray() const { return gcState() == MarkBlackAndGray
; }
90 bool isGCSweeping() const { return gcState() == Sweep
; }
91 bool isGCFinished() const { return gcState() == Finished
; }
92 bool isGCCompacting() const { return gcState() == Compact
; }
93 bool isGCMarking() const {
94 return hasAnyGCState(gcStateMask(MarkBlackOnly
) |
95 gcStateMask(MarkBlackAndGray
));
97 bool isGCMarkingOrSweeping() const {
98 return hasAnyGCState(gcStateMask(MarkBlackOnly
) |
99 gcStateMask(MarkBlackAndGray
) | gcStateMask(Sweep
));
101 bool isGCMarkingOrVerifyingPreBarriers() const {
102 return hasAnyGCState(gcStateMask(MarkBlackOnly
) |
103 gcStateMask(MarkBlackAndGray
) |
104 gcStateMask(VerifyPreBarriers
));
106 bool isGCSweepingOrCompacting() const {
107 return hasAnyGCState(gcStateMask(Sweep
) | gcStateMask(Compact
));
109 bool isVerifyingPreBarriers() const { return gcState() == VerifyPreBarriers
; }
111 bool isAtomsZone() const { return kind_
== AtomsZone
; }
112 bool isSystemZone() const { return kind_
== SystemZone
; }
114 static shadow::Zone
* from(JS::Zone
* zone
) {
115 return reinterpret_cast<shadow::Zone
*>(zone
);
117 static const shadow::Zone
* from(const JS::Zone
* zone
) {
118 return reinterpret_cast<const shadow::Zone
*>(zone
);
122 } // namespace shadow
126 #endif // js_shadow_Zone_h