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 |