Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(39)

Side by Side Diff: runtime/vm/thread_test.cc

Issue 2995543004: [vm, gc] Require a safepoint for heap iteration. (Closed)
Patch Set: explicit-thread Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/symbols.cc ('k') | runtime/vm/verifier.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/symbols.cc ('k') | runtime/vm/verifier.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698