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 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 // To break the trivial path, the handle 'obj' is temporarily cleared during | 294 // To break the trivial path, the handle 'obj' is temporarily cleared during |
295 // the search, but restored before returning. | 295 // the search, but restored before returning. |
296 RawObject* raw = obj->raw(); | 296 RawObject* raw = obj->raw(); |
297 *obj = Object::null(); | 297 *obj = Object::null(); |
298 RetainingPathVisitor visitor(raw, path); | 298 RetainingPathVisitor visitor(raw, path); |
299 IterateObjects(&visitor); | 299 IterateObjects(&visitor); |
300 *obj = raw; | 300 *obj = raw; |
301 return visitor.length(); | 301 return visitor.length(); |
302 } | 302 } |
303 | 303 |
| 304 |
| 305 class InboundReferencesVisitor : public ObjectVisitor, |
| 306 public ObjectPointerVisitor { |
| 307 public: |
| 308 // We cannot use a GrowableObjectArray, since we must not trigger GC. |
| 309 InboundReferencesVisitor(Isolate* isolate, |
| 310 RawObject* target, |
| 311 const Array& references, |
| 312 Object* scratch) |
| 313 : ObjectVisitor(isolate), ObjectPointerVisitor(isolate), source_(NULL), |
| 314 target_(target), references_(references), scratch_(scratch), length_(0) { |
| 315 ASSERT(Isolate::Current()->no_gc_scope_depth() != 0); |
| 316 } |
| 317 |
| 318 intptr_t length() const { return length_; } |
| 319 |
| 320 virtual void VisitObject(RawObject* raw_obj) { |
| 321 source_ = raw_obj; |
| 322 raw_obj->VisitPointers(this); |
| 323 } |
| 324 |
| 325 virtual void VisitPointers(RawObject** first, RawObject** last) { |
| 326 for (RawObject** current_ptr = first; current_ptr <= last; current_ptr++) { |
| 327 RawObject* current_obj = *current_ptr; |
| 328 if (current_obj == target_) { |
| 329 intptr_t obj_index = length_ * 2; |
| 330 intptr_t offset_index = obj_index + 1; |
| 331 if (!references_.IsNull() && offset_index < references_.Length()) { |
| 332 *scratch_ = source_; |
| 333 references_.SetAt(obj_index, *scratch_); |
| 334 |
| 335 *scratch_ = Smi::New(0); |
| 336 uword source_start = RawObject::ToAddr(source_); |
| 337 uword current_ptr_addr = reinterpret_cast<uword>(current_ptr); |
| 338 intptr_t offset = current_ptr_addr - source_start; |
| 339 if (offset > 0 && offset < source_->Size()) { |
| 340 ASSERT(Utils::IsAligned(offset, kWordSize)); |
| 341 *scratch_ = Smi::New(offset >> kWordSizeLog2); |
| 342 } else { |
| 343 // Some internal VM objects visit pointers not contained within the |
| 344 // parent. For instance, RawCode::VisitCodePointers visits pointers |
| 345 // in instructions. |
| 346 ASSERT(!source_->IsDartInstance()); |
| 347 *scratch_ = Smi::New(-1); |
| 348 } |
| 349 references_.SetAt(offset_index, *scratch_); |
| 350 } |
| 351 ++length_; |
| 352 } |
| 353 } |
| 354 } |
| 355 |
| 356 private: |
| 357 RawObject* source_; |
| 358 RawObject* target_; |
| 359 const Array& references_; |
| 360 Object* scratch_; |
| 361 intptr_t length_; |
| 362 }; |
| 363 |
| 364 |
| 365 intptr_t ObjectGraph::InboundReferences(Object* obj, const Array& references) { |
| 366 Object& scratch = Object::Handle(); |
| 367 NoGCScope no_gc_scope_; |
| 368 InboundReferencesVisitor visitor(isolate(), obj->raw(), references, &scratch); |
| 369 isolate()->heap()->IterateObjects(&visitor); |
| 370 return visitor.length(); |
| 371 } |
| 372 |
304 } // namespace dart | 373 } // namespace dart |
OLD | NEW |