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.h" | 5 #include "vm/thread.h" |
6 | 6 |
7 #include "vm/isolate.h" | 7 #include "vm/isolate.h" |
8 #include "vm/os_thread.h" | 8 #include "vm/os_thread.h" |
9 #include "vm/profiler.h" | 9 #include "vm/profiler.h" |
10 #include "vm/thread_interrupter.h" | 10 #include "vm/thread_interrupter.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 ASSERT(isolate->thread_state() == NULL); | 65 ASSERT(isolate->thread_state() == NULL); |
66 InterruptableThreadState* thread_state = | 66 InterruptableThreadState* thread_state = |
67 ThreadInterrupter::GetCurrentThreadState(); | 67 ThreadInterrupter::GetCurrentThreadState(); |
68 #if defined(DEBUG) | 68 #if defined(DEBUG) |
69 Isolate::CheckForDuplicateThreadState(thread_state); | 69 Isolate::CheckForDuplicateThreadState(thread_state); |
70 #endif | 70 #endif |
71 ASSERT(thread_state != NULL); | 71 ASSERT(thread_state != NULL); |
72 Profiler::BeginExecution(isolate); | 72 Profiler::BeginExecution(isolate); |
73 isolate->set_thread_state(thread_state); | 73 isolate->set_thread_state(thread_state); |
74 isolate->set_vm_tag(VMTag::kVMTagId); | 74 isolate->set_vm_tag(VMTag::kVMTagId); |
| 75 ASSERT(thread->store_buffer_block_ == NULL); |
| 76 thread->store_buffer_block_ = isolate->store_buffer()->PopBlock(); |
75 } | 77 } |
76 | 78 |
77 | 79 |
78 void Thread::ExitIsolate() { | 80 void Thread::ExitIsolate() { |
79 Thread* thread = Thread::Current(); | 81 Thread* thread = Thread::Current(); |
80 // TODO(koda): Audit callers; they should know whether they're in an isolate. | 82 // TODO(koda): Audit callers; they should know whether they're in an isolate. |
81 if (thread == NULL || thread->isolate() == NULL) return; | 83 if (thread == NULL || thread->isolate() == NULL) return; |
82 Isolate* isolate = thread->isolate(); | 84 Isolate* isolate = thread->isolate(); |
| 85 StoreBufferBlock* block = thread->store_buffer_block_; |
| 86 thread->store_buffer_block_ = NULL; |
| 87 isolate->store_buffer()->PushBlock(block); |
83 if (isolate->is_runnable()) { | 88 if (isolate->is_runnable()) { |
84 isolate->set_vm_tag(VMTag::kIdleTagId); | 89 isolate->set_vm_tag(VMTag::kIdleTagId); |
85 } else { | 90 } else { |
86 isolate->set_vm_tag(VMTag::kLoadWaitTagId); | 91 isolate->set_vm_tag(VMTag::kLoadWaitTagId); |
87 } | 92 } |
88 isolate->set_thread_state(NULL); | 93 isolate->set_thread_state(NULL); |
89 Profiler::EndExecution(isolate); | 94 Profiler::EndExecution(isolate); |
90 isolate->set_mutator_thread(NULL); | 95 isolate->set_mutator_thread(NULL); |
91 thread->isolate_ = NULL; | 96 thread->isolate_ = NULL; |
92 ASSERT(Isolate::Current() == NULL); | 97 ASSERT(Isolate::Current() == NULL); |
93 } | 98 } |
94 | 99 |
95 | 100 |
96 void Thread::EnterIsolateAsHelper(Isolate* isolate) { | 101 void Thread::EnterIsolateAsHelper(Isolate* isolate) { |
97 Thread* thread = Thread::Current(); | 102 Thread* thread = Thread::Current(); |
98 ASSERT(thread != NULL); | 103 ASSERT(thread != NULL); |
99 ASSERT(thread->isolate() == NULL); | 104 ASSERT(thread->isolate() == NULL); |
100 thread->isolate_ = isolate; | 105 thread->isolate_ = isolate; |
101 // Do not update isolate->mutator_thread, but perform sanity check: | 106 // Do not update isolate->mutator_thread, but perform sanity check: |
102 // this thread should not be both the main mutator and helper. | 107 // this thread should not be both the main mutator and helper. |
103 ASSERT(isolate->mutator_thread() != thread); | 108 ASSERT(isolate->mutator_thread() != thread); |
104 } | 109 } |
105 | 110 |
106 | 111 |
107 void Thread::ExitIsolateAsHelper() { | 112 void Thread::ExitIsolateAsHelper() { |
108 Thread* thread = Thread::Current(); | 113 Thread* thread = Thread::Current(); |
| 114 // If the helper thread chose to use the store buffer, check that it has |
| 115 // already been flushed manually. |
| 116 ASSERT(thread->store_buffer_block_ == NULL); |
109 Isolate* isolate = thread->isolate(); | 117 Isolate* isolate = thread->isolate(); |
110 ASSERT(isolate != NULL); | 118 ASSERT(isolate != NULL); |
111 thread->isolate_ = NULL; | 119 thread->isolate_ = NULL; |
112 ASSERT(isolate->mutator_thread() != thread); | 120 ASSERT(isolate->mutator_thread() != thread); |
113 } | 121 } |
114 | 122 |
115 | 123 |
| 124 void Thread::PrepareForGC() { |
| 125 Thread* thread = Thread::Current(); |
| 126 StoreBuffer* sb = thread->isolate()->store_buffer(); |
| 127 StoreBufferBlock* block = thread->store_buffer_block_; |
| 128 thread->store_buffer_block_ = NULL; |
| 129 const bool kCheckThreshold = false; // Prevent scheduling another GC. |
| 130 sb->PushBlock(block, kCheckThreshold); |
| 131 thread->store_buffer_block_ = sb->PopEmptyBlock(); |
| 132 } |
| 133 |
| 134 |
| 135 void Thread::StoreBufferBlockProcess(bool check_threshold) { |
| 136 StoreBuffer* sb = isolate()->store_buffer(); |
| 137 StoreBufferBlock* block = store_buffer_block_; |
| 138 store_buffer_block_ = NULL; |
| 139 sb->PushBlock(block, check_threshold); |
| 140 store_buffer_block_ = sb->PopBlock(); |
| 141 } |
| 142 |
| 143 |
| 144 void Thread::StoreBufferAddObject(RawObject* obj) { |
| 145 store_buffer_block_->Add(obj); |
| 146 if (store_buffer_block_->IsFull()) { |
| 147 StoreBufferBlockProcess(true); |
| 148 } |
| 149 } |
| 150 |
| 151 |
| 152 void Thread::StoreBufferAddObjectGC(RawObject* obj) { |
| 153 store_buffer_block_->Add(obj); |
| 154 if (store_buffer_block_->IsFull()) { |
| 155 StoreBufferBlockProcess(false); |
| 156 } |
| 157 } |
| 158 |
| 159 |
116 CHA* Thread::cha() const { | 160 CHA* Thread::cha() const { |
117 ASSERT(isolate_ != NULL); | 161 ASSERT(isolate_ != NULL); |
118 return isolate_->cha_; | 162 return isolate_->cha_; |
119 } | 163 } |
120 | 164 |
121 | 165 |
122 void Thread::set_cha(CHA* value) { | 166 void Thread::set_cha(CHA* value) { |
123 ASSERT(isolate_ != NULL); | 167 ASSERT(isolate_ != NULL); |
124 isolate_->cha_ = value; | 168 isolate_->cha_ = value; |
125 } | 169 } |
126 | 170 |
127 } // namespace dart | 171 } // namespace dart |
OLD | NEW |