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 "threading/ProtectedData.h"
8 :
9 : #include "jscntxt.h"
10 :
11 : #include "gc/Heap.h"
12 : #include "vm/HelperThreads.h"
13 :
14 : namespace js {
15 :
16 : #ifdef JS_HAS_PROTECTED_DATA_CHECKS
17 :
18 : /* static */ mozilla::Atomic<size_t> AutoNoteSingleThreadedRegion::count(0);
19 :
20 : template <AllowedHelperThread Helper>
21 : static inline bool
22 9849814 : OnHelperThread()
23 : {
24 : if (Helper == AllowedHelperThread::IonCompile || Helper == AllowedHelperThread::GCTaskOrIonCompile) {
25 1429003 : if (CurrentThreadIsIonCompiling())
26 8 : return true;
27 : }
28 :
29 : if (Helper == AllowedHelperThread::GCTask || Helper == AllowedHelperThread::GCTaskOrIonCompile) {
30 5614360 : if (TlsContext.get()->performingGC || TlsContext.get()->runtime()->gc.onBackgroundThread())
31 152342 : return true;
32 : }
33 :
34 9699736 : return false;
35 : }
36 :
37 : void
38 35900676 : CheckThreadLocal::check() const
39 : {
40 35900676 : JSContext* cx = TlsContext.get();
41 35897808 : MOZ_ASSERT(cx);
42 :
43 : // As for CheckZoneGroup, in a cooperatively scheduled runtime the active
44 : // thread is permitted access to thread local state for other suspended
45 : // threads in the same runtime.
46 35897808 : if (cx->isCooperativelyScheduled())
47 34092772 : MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
48 : else
49 1947472 : MOZ_ASSERT(id == ThisThread::GetId());
50 36040757 : }
51 :
52 : template <AllowedHelperThread Helper>
53 : void
54 2621841 : CheckActiveThread<Helper>::check() const
55 : {
56 : // When interrupting a thread on Windows, changes are made to the runtime
57 : // and active thread's state from another thread while the active thread is
58 : // suspended. We need a way to mark these accesses as being tantamount to
59 : // accesses by the active thread. See bug 1323066.
60 : #ifndef XP_WIN
61 2621841 : if (OnHelperThread<Helper>())
62 114123 : return;
63 :
64 2507732 : JSContext* cx = TlsContext.get();
65 2507732 : MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
66 : #endif // XP_WIN
67 : }
68 :
69 : template class CheckActiveThread<AllowedHelperThread::None>;
70 : template class CheckActiveThread<AllowedHelperThread::GCTask>;
71 : template class CheckActiveThread<AllowedHelperThread::IonCompile>;
72 :
73 : template <AllowedHelperThread Helper>
74 : void
75 5971398 : CheckZoneGroup<Helper>::check() const
76 : {
77 5971398 : if (OnHelperThread<Helper>())
78 35647 : return;
79 :
80 5937008 : JSContext* cx = TlsContext.get();
81 5937074 : if (group) {
82 5881146 : if (group->usedByHelperThread) {
83 483703 : MOZ_ASSERT(group->ownedByCurrentThread());
84 : } else {
85 : // This check is disabled on windows for the same reason as in
86 : // CheckActiveThread.
87 : #ifndef XP_WIN
88 : // In a cooperatively scheduled runtime the active thread is
89 : // permitted access to all zone groups --- even those it has not
90 : // entered --- for GC and similar purposes. Since all other
91 : // cooperative threads are suspended, these accesses are threadsafe
92 : // if the zone group is not in use by a helper thread.
93 : //
94 : // A corollary to this is that suspended cooperative threads may
95 : // not access anything in a zone group, even zone groups they own,
96 : // because they're not allowed to interact with the JS API.
97 5398374 : MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
98 : #endif
99 : }
100 : } else {
101 : // |group| will be null for data in the atoms zone. This is protected
102 : // by the exclusive access lock.
103 55928 : MOZ_ASSERT(cx->runtime()->currentThreadHasExclusiveAccess());
104 : }
105 : }
106 :
107 : template class CheckZoneGroup<AllowedHelperThread::None>;
108 : template class CheckZoneGroup<AllowedHelperThread::GCTask>;
109 : template class CheckZoneGroup<AllowedHelperThread::IonCompile>;
110 : template class CheckZoneGroup<AllowedHelperThread::GCTaskOrIonCompile>;
111 :
112 : template <GlobalLock Lock, AllowedHelperThread Helper>
113 : void
114 1259320 : CheckGlobalLock<Lock, Helper>::check() const
115 : {
116 1259320 : if (OnHelperThread<Helper>())
117 2594 : return;
118 :
119 : switch (Lock) {
120 : case GlobalLock::GCLock:
121 678 : MOZ_ASSERT(TlsContext.get()->runtime()->gc.currentThreadHasLockedGC());
122 678 : break;
123 : case GlobalLock::ExclusiveAccessLock:
124 1255507 : MOZ_ASSERT(TlsContext.get()->runtime()->currentThreadHasExclusiveAccess());
125 1255511 : break;
126 : case GlobalLock::HelperThreadLock:
127 552 : MOZ_ASSERT(HelperThreadState().isLockedByCurrentThread());
128 552 : break;
129 : }
130 : }
131 :
132 : template class CheckGlobalLock<GlobalLock::GCLock, AllowedHelperThread::None>;
133 : template class CheckGlobalLock<GlobalLock::ExclusiveAccessLock, AllowedHelperThread::None>;
134 : template class CheckGlobalLock<GlobalLock::ExclusiveAccessLock, AllowedHelperThread::GCTask>;
135 : template class CheckGlobalLock<GlobalLock::HelperThreadLock, AllowedHelperThread::None>;
136 :
137 : #endif // JS_HAS_PROTECTED_DATA_CHECKS
138 :
139 : } // namespace js
|