OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/thread_registry.h" | 5 #include "vm/thread_registry.h" |
6 | 6 |
7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
8 #include "vm/json_stream.h" | 8 #include "vm/json_stream.h" |
9 #include "vm/lockers.h" | 9 #include "vm/lockers.h" |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 Thread* thread = free_list_; | 24 Thread* thread = free_list_; |
25 free_list_ = thread->next_; | 25 free_list_ = thread->next_; |
26 delete thread; | 26 delete thread; |
27 } | 27 } |
28 } | 28 } |
29 | 29 |
30 // Delete monitor. | 30 // Delete monitor. |
31 delete threads_lock_; | 31 delete threads_lock_; |
32 } | 32 } |
33 | 33 |
34 | |
35 // Gets a free Thread structure, we special case the mutator thread | 34 // Gets a free Thread structure, we special case the mutator thread |
36 // by reusing the cached structure, see comment in 'thread_registry.h'. | 35 // by reusing the cached structure, see comment in 'thread_registry.h'. |
37 Thread* ThreadRegistry::GetFreeThreadLocked(Isolate* isolate, bool is_mutator) { | 36 Thread* ThreadRegistry::GetFreeThreadLocked(Isolate* isolate, bool is_mutator) { |
38 ASSERT(threads_lock()->IsOwnedByCurrentThread()); | 37 ASSERT(threads_lock()->IsOwnedByCurrentThread()); |
39 Thread* thread; | 38 Thread* thread; |
40 if (is_mutator) { | 39 if (is_mutator) { |
41 if (mutator_thread_ == NULL) { | 40 if (mutator_thread_ == NULL) { |
42 mutator_thread_ = GetFromFreelistLocked(isolate); | 41 mutator_thread_ = GetFromFreelistLocked(isolate); |
43 } | 42 } |
44 thread = mutator_thread_; | 43 thread = mutator_thread_; |
45 } else { | 44 } else { |
46 thread = GetFromFreelistLocked(isolate); | 45 thread = GetFromFreelistLocked(isolate); |
47 ASSERT(thread->api_top_scope() == NULL); | 46 ASSERT(thread->api_top_scope() == NULL); |
48 } | 47 } |
49 // Now add this Thread to the active list for the isolate. | 48 // Now add this Thread to the active list for the isolate. |
50 AddToActiveListLocked(thread); | 49 AddToActiveListLocked(thread); |
51 return thread; | 50 return thread; |
52 } | 51 } |
53 | 52 |
54 | |
55 void ThreadRegistry::ReturnThreadLocked(bool is_mutator, Thread* thread) { | 53 void ThreadRegistry::ReturnThreadLocked(bool is_mutator, Thread* thread) { |
56 ASSERT(threads_lock()->IsOwnedByCurrentThread()); | 54 ASSERT(threads_lock()->IsOwnedByCurrentThread()); |
57 // Remove thread from the active list for the isolate. | 55 // Remove thread from the active list for the isolate. |
58 RemoveFromActiveListLocked(thread); | 56 RemoveFromActiveListLocked(thread); |
59 if (!is_mutator) { | 57 if (!is_mutator) { |
60 ReturnToFreelistLocked(thread); | 58 ReturnToFreelistLocked(thread); |
61 } | 59 } |
62 } | 60 } |
63 | 61 |
64 | |
65 void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor, | 62 void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor, |
66 bool validate_frames) { | 63 bool validate_frames) { |
67 MonitorLocker ml(threads_lock()); | 64 MonitorLocker ml(threads_lock()); |
68 bool mutator_thread_visited = false; | 65 bool mutator_thread_visited = false; |
69 Thread* thread = active_list_; | 66 Thread* thread = active_list_; |
70 while (thread != NULL) { | 67 while (thread != NULL) { |
71 thread->VisitObjectPointers(visitor, validate_frames); | 68 thread->VisitObjectPointers(visitor, validate_frames); |
72 if (mutator_thread_ == thread) { | 69 if (mutator_thread_ == thread) { |
73 mutator_thread_visited = true; | 70 mutator_thread_visited = true; |
74 } | 71 } |
75 thread = thread->next_; | 72 thread = thread->next_; |
76 } | 73 } |
77 // Visit mutator thread even if it is not in the active list because of | 74 // Visit mutator thread even if it is not in the active list because of |
78 // api handles. | 75 // api handles. |
79 if (!mutator_thread_visited && (mutator_thread_ != NULL)) { | 76 if (!mutator_thread_visited && (mutator_thread_ != NULL)) { |
80 mutator_thread_->VisitObjectPointers(visitor, validate_frames); | 77 mutator_thread_->VisitObjectPointers(visitor, validate_frames); |
81 } | 78 } |
82 } | 79 } |
83 | 80 |
84 | |
85 void ThreadRegistry::PrepareForGC() { | 81 void ThreadRegistry::PrepareForGC() { |
86 MonitorLocker ml(threads_lock()); | 82 MonitorLocker ml(threads_lock()); |
87 Thread* thread = active_list_; | 83 Thread* thread = active_list_; |
88 while (thread != NULL) { | 84 while (thread != NULL) { |
89 thread->PrepareForGC(); | 85 thread->PrepareForGC(); |
90 thread = thread->next_; | 86 thread = thread->next_; |
91 } | 87 } |
92 } | 88 } |
93 | 89 |
94 | |
95 #ifndef PRODUCT | 90 #ifndef PRODUCT |
96 void ThreadRegistry::PrintJSON(JSONStream* stream) const { | 91 void ThreadRegistry::PrintJSON(JSONStream* stream) const { |
97 MonitorLocker ml(threads_lock()); | 92 MonitorLocker ml(threads_lock()); |
98 JSONArray threads(stream); | 93 JSONArray threads(stream); |
99 Thread* current = active_list_; | 94 Thread* current = active_list_; |
100 while (current != NULL) { | 95 while (current != NULL) { |
101 threads.AddValue(current); | 96 threads.AddValue(current); |
102 current = current->next_; | 97 current = current->next_; |
103 } | 98 } |
104 } | 99 } |
105 #endif | 100 #endif |
106 | 101 |
107 | |
108 intptr_t ThreadRegistry::CountZoneHandles() const { | 102 intptr_t ThreadRegistry::CountZoneHandles() const { |
109 MonitorLocker ml(threads_lock()); | 103 MonitorLocker ml(threads_lock()); |
110 intptr_t count = 0; | 104 intptr_t count = 0; |
111 Thread* current = active_list_; | 105 Thread* current = active_list_; |
112 while (current != NULL) { | 106 while (current != NULL) { |
113 count += current->CountZoneHandles(); | 107 count += current->CountZoneHandles(); |
114 current = current->next_; | 108 current = current->next_; |
115 } | 109 } |
116 return count; | 110 return count; |
117 } | 111 } |
118 | 112 |
119 | |
120 intptr_t ThreadRegistry::CountScopedHandles() const { | 113 intptr_t ThreadRegistry::CountScopedHandles() const { |
121 MonitorLocker ml(threads_lock()); | 114 MonitorLocker ml(threads_lock()); |
122 intptr_t count = 0; | 115 intptr_t count = 0; |
123 Thread* current = active_list_; | 116 Thread* current = active_list_; |
124 while (current != NULL) { | 117 while (current != NULL) { |
125 count += current->CountScopedHandles(); | 118 count += current->CountScopedHandles(); |
126 current = current->next_; | 119 current = current->next_; |
127 } | 120 } |
128 return count; | 121 return count; |
129 } | 122 } |
130 | 123 |
131 | |
132 void ThreadRegistry::AddToActiveListLocked(Thread* thread) { | 124 void ThreadRegistry::AddToActiveListLocked(Thread* thread) { |
133 ASSERT(thread != NULL); | 125 ASSERT(thread != NULL); |
134 ASSERT(threads_lock()->IsOwnedByCurrentThread()); | 126 ASSERT(threads_lock()->IsOwnedByCurrentThread()); |
135 thread->next_ = active_list_; | 127 thread->next_ = active_list_; |
136 active_list_ = thread; | 128 active_list_ = thread; |
137 } | 129 } |
138 | 130 |
139 | |
140 void ThreadRegistry::RemoveFromActiveListLocked(Thread* thread) { | 131 void ThreadRegistry::RemoveFromActiveListLocked(Thread* thread) { |
141 ASSERT(thread != NULL); | 132 ASSERT(thread != NULL); |
142 ASSERT(threads_lock()->IsOwnedByCurrentThread()); | 133 ASSERT(threads_lock()->IsOwnedByCurrentThread()); |
143 Thread* prev = NULL; | 134 Thread* prev = NULL; |
144 Thread* current = active_list_; | 135 Thread* current = active_list_; |
145 while (current != NULL) { | 136 while (current != NULL) { |
146 if (current == thread) { | 137 if (current == thread) { |
147 if (prev == NULL) { | 138 if (prev == NULL) { |
148 active_list_ = current->next_; | 139 active_list_ = current->next_; |
149 } else { | 140 } else { |
150 prev->next_ = current->next_; | 141 prev->next_ = current->next_; |
151 } | 142 } |
152 break; | 143 break; |
153 } | 144 } |
154 prev = current; | 145 prev = current; |
155 current = current->next_; | 146 current = current->next_; |
156 } | 147 } |
157 } | 148 } |
158 | 149 |
159 | |
160 Thread* ThreadRegistry::GetFromFreelistLocked(Isolate* isolate) { | 150 Thread* ThreadRegistry::GetFromFreelistLocked(Isolate* isolate) { |
161 ASSERT(threads_lock()->IsOwnedByCurrentThread()); | 151 ASSERT(threads_lock()->IsOwnedByCurrentThread()); |
162 Thread* thread = NULL; | 152 Thread* thread = NULL; |
163 // Get thread structure from free list or create a new one. | 153 // Get thread structure from free list or create a new one. |
164 if (free_list_ == NULL) { | 154 if (free_list_ == NULL) { |
165 thread = new Thread(isolate); | 155 thread = new Thread(isolate); |
166 } else { | 156 } else { |
167 thread = free_list_; | 157 thread = free_list_; |
168 free_list_ = thread->next_; | 158 free_list_ = thread->next_; |
169 } | 159 } |
170 return thread; | 160 return thread; |
171 } | 161 } |
172 | 162 |
173 | |
174 void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) { | 163 void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) { |
175 ASSERT(thread != NULL); | 164 ASSERT(thread != NULL); |
176 ASSERT(thread->os_thread_ == NULL); | 165 ASSERT(thread->os_thread_ == NULL); |
177 ASSERT(thread->isolate_ == NULL); | 166 ASSERT(thread->isolate_ == NULL); |
178 ASSERT(thread->heap_ == NULL); | 167 ASSERT(thread->heap_ == NULL); |
179 ASSERT(threads_lock()->IsOwnedByCurrentThread()); | 168 ASSERT(threads_lock()->IsOwnedByCurrentThread()); |
180 // Add thread to the free list. | 169 // Add thread to the free list. |
181 thread->next_ = free_list_; | 170 thread->next_ = free_list_; |
182 free_list_ = thread; | 171 free_list_ = thread; |
183 } | 172 } |
184 | 173 |
185 } // namespace dart | 174 } // namespace dart |
OLD | NEW |