| 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 |