| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 "platform/assert.h" | 5 #include "platform/assert.h" |
| 6 #include "vm/isolate.h" | 6 #include "vm/isolate.h" |
| 7 #include "vm/lockers.h" | 7 #include "vm/lockers.h" |
| 8 #include "vm/profiler.h" | 8 #include "vm/profiler.h" |
| 9 #include "vm/safepoint.h" | 9 #include "vm/safepoint.h" |
| 10 #include "vm/stack_frame.h" | 10 #include "vm/stack_frame.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 a1.Add(true); | 123 a1.Add(true); |
| 124 } | 124 } |
| 125 // Check that we can create handles and allocate in old space. | 125 // Check that we can create handles and allocate in old space. |
| 126 String& str = String::Handle(zone, String::New("old", Heap::kOld)); | 126 String& str = String::Handle(zone, String::New("old", Heap::kOld)); |
| 127 EXPECT(str.Equals("old")); | 127 EXPECT(str.Equals("old")); |
| 128 | 128 |
| 129 const intptr_t unique_smi = id_ + 928327281; | 129 const intptr_t unique_smi = id_ + 928327281; |
| 130 Smi& smi = Smi::Handle(zone, Smi::New(unique_smi)); | 130 Smi& smi = Smi::Handle(zone, Smi::New(unique_smi)); |
| 131 EXPECT(smi.Value() == unique_smi); | 131 EXPECT(smi.Value() == unique_smi); |
| 132 { | 132 { |
| 133 HeapIterationScope iteration(thread); |
| 133 ObjectCounter counter(isolate_, &smi); | 134 ObjectCounter counter(isolate_, &smi); |
| 134 // Ensure that our particular zone is visited. | 135 // Ensure that our particular zone is visited. |
| 135 isolate_->IterateObjectPointers(&counter, | 136 iteration.IterateStackPointers(&counter, |
| 136 StackFrameIterator::kValidateFrames); | 137 StackFrameIterator::kValidateFrames); |
| 137 EXPECT_EQ(1, counter.count()); | 138 EXPECT_EQ(1, counter.count()); |
| 138 } | 139 } |
| 139 char* unique_chars = zone->PrintToString("unique_str_%" Pd, id_); | 140 char* unique_chars = zone->PrintToString("unique_str_%" Pd, id_); |
| 140 String& unique_str = String::Handle(zone); | 141 String& unique_str = String::Handle(zone); |
| 141 { | 142 { |
| 142 // String::New may create additional handles in the topmost scope that | 143 // String::New may create additional handles in the topmost scope that |
| 143 // we don't want to count, so wrap this in its own scope. | 144 // we don't want to count, so wrap this in its own scope. |
| 144 HANDLESCOPE(thread); | 145 HANDLESCOPE(thread); |
| 145 unique_str = String::New(unique_chars, Heap::kOld); | 146 unique_str = String::New(unique_chars, Heap::kOld); |
| 146 } | 147 } |
| 147 EXPECT(unique_str.Equals(unique_chars)); | 148 EXPECT(unique_str.Equals(unique_chars)); |
| 148 { | 149 { |
| 150 HeapIterationScope iteration(thread); |
| 149 ObjectCounter str_counter(isolate_, &unique_str); | 151 ObjectCounter str_counter(isolate_, &unique_str); |
| 150 // Ensure that our particular zone is visited. | 152 // Ensure that our particular zone is visited. |
| 151 isolate_->IterateObjectPointers(&str_counter, | 153 iteration.IterateStackPointers(&str_counter, |
| 152 StackFrameIterator::kValidateFrames); | 154 StackFrameIterator::kValidateFrames); |
| 153 // We should visit the string object exactly once. | 155 // We should visit the string object exactly once. |
| 154 EXPECT_EQ(1, str_counter.count()); | 156 EXPECT_EQ(1, str_counter.count()); |
| 155 } | 157 } |
| 156 } | 158 } |
| 157 Thread::ExitIsolateAsHelper(); | 159 Thread::ExitIsolateAsHelper(); |
| 158 { | 160 { |
| 159 MonitorLocker ml(monitor_); | 161 MonitorLocker ml(monitor_); |
| 160 *done_ = true; | 162 *done_ = true; |
| 161 ml.Notify(); | 163 ml.Notify(); |
| 162 } | 164 } |
| 163 } | 165 } |
| 164 | 166 |
| 165 private: | 167 private: |
| 166 Isolate* isolate_; | 168 Isolate* isolate_; |
| 167 Monitor* monitor_; | 169 Monitor* monitor_; |
| 168 bool* done_; | 170 bool* done_; |
| 169 intptr_t id_; | 171 intptr_t id_; |
| 170 }; | 172 }; |
| 171 | 173 |
| 172 ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) { | 174 ISOLATE_UNIT_TEST_CASE(ManyTasksWithZones) { |
| 173 const int kTaskCount = 100; | 175 const int kTaskCount = 100; |
| 174 Monitor sync[kTaskCount]; | 176 Monitor sync[kTaskCount]; |
| 175 bool done[kTaskCount]; | 177 bool done[kTaskCount]; |
| 176 Isolate* isolate = Thread::Current()->isolate(); | 178 Isolate* isolate = thread->isolate(); |
| 177 EXPECT(isolate->heap()->GrowthControlState()); | 179 EXPECT(isolate->heap()->GrowthControlState()); |
| 178 isolate->heap()->DisableGrowthControl(); | 180 isolate->heap()->DisableGrowthControl(); |
| 179 for (int i = 0; i < kTaskCount; i++) { | 181 for (int i = 0; i < kTaskCount; i++) { |
| 180 done[i] = false; | 182 done[i] = false; |
| 181 Dart::thread_pool()->Run( | 183 Dart::thread_pool()->Run( |
| 182 new TaskWithZoneAllocation(isolate, &sync[i], &done[i], i)); | 184 new TaskWithZoneAllocation(isolate, &sync[i], &done[i], i)); |
| 183 } | 185 } |
| 186 bool in_isolate = true; |
| 184 for (int i = 0; i < kTaskCount; i++) { | 187 for (int i = 0; i < kTaskCount; i++) { |
| 185 // Check that main mutator thread can still freely use its own zone. | 188 // Check that main mutator thread can still freely use its own zone. |
| 186 String& bar = String::Handle(String::New("bar")); | 189 String& bar = String::Handle(String::New("bar")); |
| 187 if (i % 10 == 0) { | 190 if (i % 10 == 0) { |
| 188 // Mutator thread is free to independently move in/out/between isolates. | 191 // Mutator thread is free to independently move in/out/between isolates. |
| 189 Thread::ExitIsolate(); | 192 Thread::ExitIsolate(); |
| 193 in_isolate = false; |
| 190 } | 194 } |
| 191 MonitorLocker ml(&sync[i]); | 195 MonitorLocker ml(&sync[i]); |
| 192 while (!done[i]) { | 196 while (!done[i]) { |
| 193 ml.Wait(); | 197 if (in_isolate) { |
| 198 ml.WaitWithSafepointCheck(thread); |
| 199 } else { |
| 200 ml.Wait(); |
| 201 } |
| 194 } | 202 } |
| 195 EXPECT(done[i]); | 203 EXPECT(done[i]); |
| 196 if (i % 10 == 0) { | 204 if (i % 10 == 0) { |
| 197 Thread::EnterIsolate(isolate); | 205 Thread::EnterIsolate(isolate); |
| 206 in_isolate = true; |
| 198 } | 207 } |
| 199 EXPECT(bar.Equals("bar")); | 208 EXPECT(bar.Equals("bar")); |
| 200 } | 209 } |
| 201 } | 210 } |
| 202 | 211 |
| 203 #ifndef PRODUCT | 212 #ifndef PRODUCT |
| 204 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { | 213 class SimpleTaskWithZoneAllocation : public ThreadPool::Task { |
| 205 public: | 214 public: |
| 206 SimpleTaskWithZoneAllocation(intptr_t id, | 215 SimpleTaskWithZoneAllocation(intptr_t id, |
| 207 Isolate* isolate, | 216 Isolate* isolate, |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 StackZone stack_zone(thread); | 423 StackZone stack_zone(thread); |
| 415 Zone* zone = thread->zone(); | 424 Zone* zone = thread->zone(); |
| 416 HANDLESCOPE(thread); | 425 HANDLESCOPE(thread); |
| 417 const intptr_t kUniqueSmi = 928327281; | 426 const intptr_t kUniqueSmi = 928327281; |
| 418 Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi)); | 427 Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi)); |
| 419 if ((i % 100) != 0) { | 428 if ((i % 100) != 0) { |
| 420 // Usually, we just cooperate. | 429 // Usually, we just cooperate. |
| 421 TransitionVMToBlocked transition(thread); | 430 TransitionVMToBlocked transition(thread); |
| 422 } else { | 431 } else { |
| 423 // But occasionally, organize a rendezvous. | 432 // But occasionally, organize a rendezvous. |
| 424 SafepointOperationScope safepoint_scope(thread); | 433 HeapIterationScope iteration(thread); // Establishes a safepoint. |
| 434 ASSERT(thread->IsAtSafepoint()); |
| 425 ObjectCounter counter(isolate_, &smi); | 435 ObjectCounter counter(isolate_, &smi); |
| 426 isolate_->IterateObjectPointers(&counter, | 436 iteration.IterateStackPointers(&counter, |
| 427 StackFrameIterator::kValidateFrames); | 437 StackFrameIterator::kValidateFrames); |
| 428 { | 438 { |
| 429 MonitorLocker ml(monitor_); | 439 MonitorLocker ml(monitor_); |
| 430 EXPECT_EQ(*expected_count_, counter.count()); | 440 EXPECT_EQ(*expected_count_, counter.count()); |
| 431 } | 441 } |
| 432 UserTag& tag = UserTag::Handle(zone, isolate_->current_tag()); | 442 UserTag& tag = UserTag::Handle(zone, isolate_->current_tag()); |
| 433 if (tag.raw() != isolate_->default_tag()) { | 443 if (tag.raw() != isolate_->default_tag()) { |
| 434 String& label = String::Handle(zone, tag.label()); | 444 String& label = String::Handle(zone, tag.label()); |
| 435 EXPECT(label.Equals("foo")); | 445 EXPECT(label.Equals("foo")); |
| 436 MonitorLocker ml(monitor_); | 446 MonitorLocker ml(monitor_); |
| 437 if (*expected_count_ == kTaskCount && !local_done_) { | 447 if (*expected_count_ == kTaskCount && !local_done_) { |
| (...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 TransitionVMToBlocked transition(thread); | 769 TransitionVMToBlocked transition(thread); |
| 760 MonitorLocker ml(&done_monitor); | 770 MonitorLocker ml(&done_monitor); |
| 761 if (done) { | 771 if (done) { |
| 762 break; | 772 break; |
| 763 } | 773 } |
| 764 } | 774 } |
| 765 } | 775 } |
| 766 } | 776 } |
| 767 | 777 |
| 768 } // namespace dart | 778 } // namespace dart |
| OLD | NEW |