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 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 IterateObjects(&excluding_class); | 248 IterateObjects(&excluding_class); |
249 intptr_t size_excluding_class = excluding_class.size(); | 249 intptr_t size_excluding_class = excluding_class.size(); |
250 return size_total - size_excluding_class; | 250 return size_total - size_excluding_class; |
251 } | 251 } |
252 | 252 |
253 | 253 |
254 class RetainingPathVisitor : public ObjectGraph::Visitor { | 254 class RetainingPathVisitor : public ObjectGraph::Visitor { |
255 public: | 255 public: |
256 // We cannot use a GrowableObjectArray, since we must not trigger GC. | 256 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
257 RetainingPathVisitor(RawObject* obj, const Array& path) | 257 RetainingPathVisitor(RawObject* obj, const Array& path) |
258 : obj_(obj), path_(path), length_(0) { | 258 : thread_(Thread::Current()), obj_(obj), path_(path), length_(0) { |
259 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); | 259 ASSERT(Thread::Current()->no_safepoint_scope_depth() != 0); |
260 } | 260 } |
261 | 261 |
262 intptr_t length() const { return length_; } | 262 intptr_t length() const { return length_; } |
263 | 263 |
264 bool ShouldSkip(RawObject* obj) { | 264 bool ShouldSkip(RawObject* obj) { |
265 // A retaining path through ICData is never the only retaining path, | 265 // A retaining path through ICData is never the only retaining path, |
266 // and it is less informative than its alternatives. | 266 // and it is less informative than its alternatives. |
267 intptr_t cid = obj->GetClassId(); | 267 intptr_t cid = obj->GetClassId(); |
268 switch (cid) { | 268 switch (cid) { |
269 case kICDataCid: | 269 case kICDataCid: |
270 return true; | 270 return true; |
271 default: | 271 default: |
272 return false; | 272 return false; |
273 } | 273 } |
274 } | 274 } |
275 | 275 |
276 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { | 276 virtual Direction VisitObject(ObjectGraph::StackIterator* it) { |
277 if (it->Get() != obj_) { | 277 if (it->Get() != obj_) { |
278 if (ShouldSkip(it->Get())) { | 278 if (ShouldSkip(it->Get())) { |
279 return kBacktrack; | 279 return kBacktrack; |
280 } else { | 280 } else { |
281 return kProceed; | 281 return kProceed; |
282 } | 282 } |
283 } else { | 283 } else { |
284 HANDLESCOPE(Isolate::Current()); | 284 HANDLESCOPE(thread_); |
285 Object& current = Object::Handle(); | 285 Object& current = Object::Handle(); |
286 Smi& offset_from_parent = Smi::Handle(); | 286 Smi& offset_from_parent = Smi::Handle(); |
287 do { | 287 do { |
288 intptr_t obj_index = length_ * 2; | 288 intptr_t obj_index = length_ * 2; |
289 intptr_t offset_index = obj_index + 1; | 289 intptr_t offset_index = obj_index + 1; |
290 if (!path_.IsNull() && offset_index < path_.Length()) { | 290 if (!path_.IsNull() && offset_index < path_.Length()) { |
291 current = it->Get(); | 291 current = it->Get(); |
292 path_.SetAt(obj_index, current); | 292 path_.SetAt(obj_index, current); |
293 offset_from_parent = Smi::New(it->OffsetFromParentInWords()); | 293 offset_from_parent = Smi::New(it->OffsetFromParentInWords()); |
294 path_.SetAt(offset_index, offset_from_parent); | 294 path_.SetAt(offset_index, offset_from_parent); |
295 } | 295 } |
296 ++length_; | 296 ++length_; |
297 } while (it->MoveToParent()); | 297 } while (it->MoveToParent()); |
298 return kAbort; | 298 return kAbort; |
299 } | 299 } |
300 } | 300 } |
301 | 301 |
302 private: | 302 private: |
| 303 Thread* thread_; |
303 RawObject* obj_; | 304 RawObject* obj_; |
304 const Array& path_; | 305 const Array& path_; |
305 intptr_t length_; | 306 intptr_t length_; |
306 }; | 307 }; |
307 | 308 |
308 | 309 |
309 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { | 310 intptr_t ObjectGraph::RetainingPath(Object* obj, const Array& path) { |
310 NoSafepointScope no_safepoint_scope_; | 311 NoSafepointScope no_safepoint_scope_; |
311 // To break the trivial path, the handle 'obj' is temporarily cleared during | 312 // To break the trivial path, the handle 'obj' is temporarily cleared during |
312 // the search, but restored before returning. | 313 // the search, but restored before returning. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 { | 474 { |
474 WritePointerVisitor ptr_writer(isolate(), stream); | 475 WritePointerVisitor ptr_writer(isolate(), stream); |
475 isolate()->IterateObjectPointers(&ptr_writer, false, false); | 476 isolate()->IterateObjectPointers(&ptr_writer, false, false); |
476 } | 477 } |
477 stream->WriteUnsigned(0); | 478 stream->WriteUnsigned(0); |
478 IterateObjects(&visitor); | 479 IterateObjects(&visitor); |
479 return visitor.count() + 1; // + root | 480 return visitor.count() + 1; // + root |
480 } | 481 } |
481 | 482 |
482 } // namespace dart | 483 } // namespace dart |
OLD | NEW |