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