| Index: runtime/vm/thread.cc
|
| diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
|
| index 79919d4f9313ef0ea163a25b0b2071e588629fe4..fe81e56cc89d1510ef7e99356e55036fd2fa62a2 100644
|
| --- a/runtime/vm/thread.cc
|
| +++ b/runtime/vm/thread.cc
|
| @@ -72,6 +72,8 @@ void Thread::EnterIsolate(Isolate* isolate) {
|
| Profiler::BeginExecution(isolate);
|
| isolate->set_thread_state(thread_state);
|
| isolate->set_vm_tag(VMTag::kVMTagId);
|
| + ASSERT(thread->store_buffer_block_ == NULL);
|
| + thread->store_buffer_block_ = isolate->store_buffer()->PopBlock();
|
| }
|
|
|
|
|
| @@ -80,6 +82,9 @@ void Thread::ExitIsolate() {
|
| // TODO(koda): Audit callers; they should know whether they're in an isolate.
|
| if (thread == NULL || thread->isolate() == NULL) return;
|
| Isolate* isolate = thread->isolate();
|
| + StoreBufferBlock* block = thread->store_buffer_block_;
|
| + thread->store_buffer_block_ = NULL;
|
| + isolate->store_buffer()->PushBlock(block);
|
| if (isolate->is_runnable()) {
|
| isolate->set_vm_tag(VMTag::kIdleTagId);
|
| } else {
|
| @@ -106,6 +111,9 @@ void Thread::EnterIsolateAsHelper(Isolate* isolate) {
|
|
|
| void Thread::ExitIsolateAsHelper() {
|
| Thread* thread = Thread::Current();
|
| + // If the helper thread chose to use the store buffer, check that it has
|
| + // already been flushed manually.
|
| + ASSERT(thread->store_buffer_block_ == NULL);
|
| Isolate* isolate = thread->isolate();
|
| ASSERT(isolate != NULL);
|
| thread->isolate_ = NULL;
|
| @@ -113,6 +121,42 @@ void Thread::ExitIsolateAsHelper() {
|
| }
|
|
|
|
|
| +void Thread::PrepareForGC() {
|
| + Thread* thread = Thread::Current();
|
| + StoreBuffer* sb = thread->isolate()->store_buffer();
|
| + StoreBufferBlock* block = thread->store_buffer_block_;
|
| + thread->store_buffer_block_ = NULL;
|
| + const bool kCheckThreshold = false; // Prevent scheduling another GC.
|
| + sb->PushBlock(block, kCheckThreshold);
|
| + thread->store_buffer_block_ = sb->PopEmptyBlock();
|
| +}
|
| +
|
| +
|
| +void Thread::StoreBufferBlockProcess(bool check_threshold) {
|
| + StoreBuffer* sb = isolate()->store_buffer();
|
| + StoreBufferBlock* block = store_buffer_block_;
|
| + store_buffer_block_ = NULL;
|
| + sb->PushBlock(block, check_threshold);
|
| + store_buffer_block_ = sb->PopBlock();
|
| +}
|
| +
|
| +
|
| +void Thread::StoreBufferAddObject(RawObject* obj) {
|
| + store_buffer_block_->Add(obj);
|
| + if (store_buffer_block_->IsFull()) {
|
| + StoreBufferBlockProcess(true);
|
| + }
|
| +}
|
| +
|
| +
|
| +void Thread::StoreBufferAddObjectGC(RawObject* obj) {
|
| + store_buffer_block_->Add(obj);
|
| + if (store_buffer_block_->IsFull()) {
|
| + StoreBufferBlockProcess(false);
|
| + }
|
| +}
|
| +
|
| +
|
| CHA* Thread::cha() const {
|
| ASSERT(isolate_ != NULL);
|
| return isolate_->cha_;
|
|
|