OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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/object_graph.h" | 5 #include "vm/object_graph.h" |
6 | 6 |
7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
8 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 explicit Unmarker(Isolate* isolate) : ObjectVisitor(isolate) { } | 141 explicit Unmarker(Isolate* isolate) : ObjectVisitor(isolate) { } |
142 | 142 |
143 void VisitObject(RawObject* obj) { | 143 void VisitObject(RawObject* obj) { |
144 if (obj->IsMarked()) { | 144 if (obj->IsMarked()) { |
145 obj->ClearMarkBit(); | 145 obj->ClearMarkBit(); |
146 } | 146 } |
147 } | 147 } |
148 | 148 |
149 static void UnmarkAll(Isolate* isolate) { | 149 static void UnmarkAll(Isolate* isolate) { |
150 Unmarker unmarker(isolate); | 150 Unmarker unmarker(isolate); |
151 isolate->heap()->VisitObjects(&unmarker); | 151 isolate->heap()->IterateObjects(&unmarker); |
152 } | 152 } |
153 | 153 |
154 private: | 154 private: |
155 DISALLOW_COPY_AND_ASSIGN(Unmarker); | 155 DISALLOW_COPY_AND_ASSIGN(Unmarker); |
156 }; | 156 }; |
157 | 157 |
158 | 158 |
159 ObjectGraph::ObjectGraph(Isolate* isolate) | 159 ObjectGraph::ObjectGraph(Isolate* isolate) |
160 : StackResource(isolate) { | 160 : StackResource(isolate) { |
161 // The VM isolate has all its objects pre-marked, so iterating over it | 161 // The VM isolate has all its objects pre-marked, so iterating over it |
162 // would be a no-op. | 162 // would be a no-op. |
163 ASSERT(isolate != Dart::vm_isolate()); | 163 ASSERT(isolate != Dart::vm_isolate()); |
164 isolate->heap()->WriteProtectCode(false); | 164 isolate->heap()->WriteProtectCode(false); |
165 } | 165 } |
166 | 166 |
167 | 167 |
168 ObjectGraph::~ObjectGraph() { | 168 ObjectGraph::~ObjectGraph() { |
169 isolate()->heap()->WriteProtectCode(true); | 169 isolate()->heap()->WriteProtectCode(true); |
170 } | 170 } |
171 | 171 |
172 | 172 |
173 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) { | 173 void ObjectGraph::IterateObjects(ObjectGraph::Visitor* visitor) { |
174 NoSafepointScope no_safepoint_scope_; | 174 NoSafepointScope no_safepoint_scope_; |
175 PageSpace* old_space = isolate()->heap()->old_space(); | |
176 MonitorLocker ml(old_space->tasks_lock()); | |
177 while (old_space->tasks() > 0) { | |
178 ml.Wait(); | |
179 } | |
180 Stack stack(isolate()); | 175 Stack stack(isolate()); |
181 isolate()->VisitObjectPointers(&stack, false, false); | 176 isolate()->IterateObjectPointers(&stack, false, false); |
182 stack.TraverseGraph(visitor); | 177 stack.TraverseGraph(visitor); |
183 Unmarker::UnmarkAll(isolate()); | 178 Unmarker::UnmarkAll(isolate()); |
184 } | 179 } |
185 | 180 |
186 | 181 |
187 void ObjectGraph::IterateObjectsFrom(const Object& root, | 182 void ObjectGraph::IterateObjectsFrom(const Object& root, |
188 ObjectGraph::Visitor* visitor) { | 183 ObjectGraph::Visitor* visitor) { |
189 NoSafepointScope no_safepoint_scope_; | 184 NoSafepointScope no_safepoint_scope_; |
190 PageSpace* old_space = isolate()->heap()->old_space(); | |
191 MonitorLocker ml(old_space->tasks_lock()); | |
192 while (old_space->tasks() > 0) { | |
193 ml.Wait(); | |
194 } | |
195 Stack stack(isolate()); | 185 Stack stack(isolate()); |
196 RawObject* root_raw = root.raw(); | 186 RawObject* root_raw = root.raw(); |
197 stack.VisitPointer(&root_raw); | 187 stack.VisitPointer(&root_raw); |
198 stack.TraverseGraph(visitor); | 188 stack.TraverseGraph(visitor); |
199 // TODO(koda): Optimize if we only visited a small subgraph. | 189 // TODO(koda): Optimize if we only visited a small subgraph. |
200 Unmarker::UnmarkAll(isolate()); | 190 Unmarker::UnmarkAll(isolate()); |
201 } | 191 } |
202 | 192 |
203 | 193 |
204 class SizeVisitor : public ObjectGraph::Visitor { | 194 class SizeVisitor : public ObjectGraph::Visitor { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 const Array& references_; | 360 const Array& references_; |
371 Object* scratch_; | 361 Object* scratch_; |
372 intptr_t length_; | 362 intptr_t length_; |
373 }; | 363 }; |
374 | 364 |
375 | 365 |
376 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { | 366 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { |
377 Object& scratch = Object::Handle(); | 367 Object& scratch = Object::Handle(); |
378 NoSafepointScope no_safepoint_scope_; | 368 NoSafepointScope no_safepoint_scope_; |
379 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); | 369 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); |
380 isolate()->heap()->VisitObjects(&visitor); | 370 isolate()->heap()->IterateObjects(&visitor); |
381 return visitor.length(); | 371 return visitor.length(); |
382 } | 372 } |
383 | 373 |
384 | 374 |
385 static void WritePtr(RawObject* raw, WriteStream* stream) { | 375 static void WritePtr(RawObject* raw, WriteStream* stream) { |
386 ASSERT(raw->IsHeapObject()); | 376 ASSERT(raw->IsHeapObject()); |
387 ASSERT(raw->IsOldObject()); | 377 ASSERT(raw->IsOldObject()); |
388 uword addr = RawObject::ToAddr(raw); | 378 uword addr = RawObject::ToAddr(raw); |
389 ASSERT(Utils::IsAligned(addr, kObjectAlignment)); | 379 ASSERT(Utils::IsAligned(addr, kObjectAlignment)); |
390 // Using units of kObjectAlignment makes the ids fit into Smis when parsed | 380 // Using units of kObjectAlignment makes the ids fit into Smis when parsed |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 intptr_t ObjectGraph::Serialize(WriteStream* stream) { | 449 intptr_t ObjectGraph::Serialize(WriteStream* stream) { |
460 // Current encoding assumes objects do not move, so promote everything to old. | 450 // Current encoding assumes objects do not move, so promote everything to old. |
461 isolate()->heap()->new_space()->Evacuate(); | 451 isolate()->heap()->new_space()->Evacuate(); |
462 WriteGraphVisitor visitor(isolate(), stream); | 452 WriteGraphVisitor visitor(isolate(), stream); |
463 stream->WriteUnsigned(kObjectAlignment); | 453 stream->WriteUnsigned(kObjectAlignment); |
464 stream->WriteUnsigned(0); | 454 stream->WriteUnsigned(0); |
465 stream->WriteUnsigned(0); | 455 stream->WriteUnsigned(0); |
466 stream->WriteUnsigned(0); | 456 stream->WriteUnsigned(0); |
467 { | 457 { |
468 WritePointerVisitor ptr_writer(isolate(), stream); | 458 WritePointerVisitor ptr_writer(isolate(), stream); |
469 isolate()->VisitObjectPointers(&ptr_writer, false, false); | 459 isolate()->IterateObjectPointers(&ptr_writer, false, false); |
470 } | 460 } |
471 stream->WriteUnsigned(0); | 461 stream->WriteUnsigned(0); |
472 IterateObjects(&visitor); | 462 IterateObjects(&visitor); |
473 return visitor.count() + 1; // + root | 463 return visitor.count() + 1; // + root |
474 } | 464 } |
475 | 465 |
476 } // namespace dart | 466 } // namespace dart |
OLD | NEW |