Bug Summary

File:root/firefox-clang/js/src/gc/ParallelMarking.h
Warning:line 84, column 23
Excessive padding in 'class js::gc::ParallelMarker' (105 padding bytes, where 41 is optimal). Optimal fields order: tasks, gc, waitingTasks, activeTasks, color, markingDeferredWeakmaps, consider reordering the fields or adding explicit padding members

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O3 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_js_src_gc1.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/js/src/gc -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/js/src/gc -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D WASM_SUPPORTS_HUGE_MEMORY -D JS_CACHEIR_SPEW -D JS_STRUCTURED_SPEW -D JS_HAS_CTYPES -D FFI_BUILDING -D EXPORT_JS_API -D MOZ_HAS_MOZGLUE -D MOZ_SUPPORT_LEAKCHECKING -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/js/src -I /root/firefox-clang/js/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c++ Unified_cpp_js_src_gc1.cpp
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5#ifndef gc_ParallelMarking_h
6#define gc_ParallelMarking_h
7
8#include "mozilla/Atomics.h"
9#include "mozilla/BitSet.h"
10#include "mozilla/Maybe.h"
11#include "mozilla/TimeStamp.h"
12
13#include "gc/GCMarker.h"
14#include "gc/GCParallelTask.h"
15#include "js/HeapAPI.h"
16#include "js/SliceBudget.h"
17#include "threading/ConditionVariable.h"
18#include "threading/ProtectedData.h"
19
20namespace js {
21
22class AutoLockHelperThreadState;
23
24namespace gc {
25
26class ParallelMarker;
27
28using ParallelTaskBitset = mozilla::BitSet<MaxParallelWorkers, uint32_t>;
29
30// A helper thread task that performs parallel marking.
31class alignas(TypicalCacheLineSize) ParallelMarkTask : public GCParallelTask {
32 public:
33 friend class ParallelMarker;
34
35 ParallelMarkTask(ParallelMarker* pm, GCMarker* marker, MarkColor color,
36 uint32_t id, const JS::SliceBudget& budget);
37 ~ParallelMarkTask();
38
39 void run(AutoLockHelperThreadState& lock) override;
40
41 using AtomicCount = mozilla::Atomic<uint32_t, mozilla::Relaxed>;
42 AtomicCount& waitingTaskCountRef();
43
44 void donateWork();
45
46 void recordDuration() override;
47
48 private:
49 bool tryMarking(AutoLockHelperThreadState& lock);
50 bool requestWork(AutoLockHelperThreadState& lock);
51 void resumeWaitingTasks(AutoLockHelperThreadState& lock);
52 void markDeferredWeakmaps(AutoLockHelperThreadState& lock);
53
54 void waitUntilResumed(AutoLockHelperThreadState& lock);
55 void resume();
56 void resumeOnFinish(const AutoLockHelperThreadState& lock);
57
58 bool hasWork() const;
59
60 // The following fields are only accessed by the marker thread:
61 ParallelMarker* const pm;
62 GCMarker* const marker;
63 AutoSetMarkColor color;
64 JS::SliceBudget budget;
65 ConditionVariable resumed;
66
67 const uint32_t id;
68
69 HelperThreadLockData<bool> isWaiting;
70
71 // Length of time this task spent blocked waiting for work.
72 MainThreadOrGCTaskData<mozilla::TimeDuration> markTime;
73 MainThreadOrGCTaskData<mozilla::TimeDuration> waitTime;
74};
75
76// Per-runtime parallel marking state.
77//
78// This class is used on the main thread and coordinates parallel marking using
79// several helper threads running ParallelMarkTasks.
80//
81// This uses a work-requesting approach. Threads mark until they run out of
82// work and then add themselves to a list of waiting tasks and block. Running
83// tasks with enough work may donate work to a waiting task and resume it.
84class MOZ_STACK_CLASS ParallelMarker {
Excessive padding in 'class js::gc::ParallelMarker' (105 padding bytes, where 41 is optimal). Optimal fields order: tasks, gc, waitingTasks, activeTasks, color, markingDeferredWeakmaps, consider reordering the fields or adding explicit padding members
85 public:
86 static bool mark(GCRuntime* gc, const JS::SliceBudget& sliceBudget);
87
88 bool hasWaitingTasks() const { return !waitingTasks.IsEmpty(); }
89
90 void donateWorkFrom(GCMarker* src);
91
92 private:
93 static bool markOneColor(GCRuntime* gc, MarkColor color,
94 const JS::SliceBudget& sliceBudget);
95
96 explicit ParallelMarker(GCRuntime* gc, MarkColor color);
97
98 bool mark(const JS::SliceBudget& sliceBudget);
99
100 bool anyMarkerHasEntries() const;
101
102 void addTask(ParallelMarkTask* task, const AutoLockHelperThreadState& lock);
103
104 void addTaskToWaitingList(ParallelMarkTask* task,
105 const AutoLockHelperThreadState& lock);
106#ifdef DEBUG1
107 bool isTaskInWaitingList(const ParallelMarkTask* task,
108 const AutoLockHelperThreadState& lock) const;
109#endif
110 ParallelMarkTask* takeWaitingTask();
111
112#ifdef DEBUG1
113 // True while a task is marking deferred weakmaps. During this the lock is
114 // released and no task is active, but the marking task will resume or finish
115 // any waiting tasks once it completes, so waiting tasks must not treat this
116 // as a lost wakeup.
117 bool isMarkingDeferredWeakmaps(const AutoLockHelperThreadState& lock) const {
118 return markingDeferredWeakmaps.ref();
119 }
120#endif
121
122 bool hasActiveTasks(const AutoLockHelperThreadState& lock) const {
123 return !activeTasks.ref().IsEmpty();
124 }
125 void setTaskActive(ParallelMarkTask* task,
126 const AutoLockHelperThreadState& lock);
127 void setTaskInactive(ParallelMarkTask* task,
128 const AutoLockHelperThreadState& lock);
129
130 size_t workerCount() const;
131
132 friend class ParallelMarkTask;
133
134 GCRuntime* const gc;
135
136 mozilla::Maybe<ParallelMarkTask> tasks[MaxParallelWorkers];
137
138 // waitingTasks is written to with the lock held but can be read without.
139 using WaitingTaskSet =
140 mozilla::BitSet<MaxParallelWorkers,
141 mozilla::Atomic<uint32_t, mozilla::Relaxed>>;
142 WaitingTaskSet waitingTasks;
143
144 HelperThreadLockData<ParallelTaskBitset> activeTasks;
145
146#ifdef DEBUG1
147 // Set while a task marks deferred weakmaps with the lock released.
148 HelperThreadLockData<bool> markingDeferredWeakmaps;
149#endif
150
151 const MarkColor color;
152};
153
154inline ParallelMarkTask::AtomicCount& ParallelMarkTask::waitingTaskCountRef() {
155 return pm->waitingTasks.Storage()[0];
156}
157
158} // namespace gc
159} // namespace js
160
161#endif /* gc_ParallelMarking_h */