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