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_(0), | |
koda
2014/08/21 18:21:20
I think we usually use NULL rather than 0.
| |
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& path) { | |
366 Object& scratch = Object::Handle(); | |
367 NoGCScope no_gc_scope_; | |
368 // To break the trivial path, the handle 'obj' is temporarily cleared during | |
koda
2014/08/21 18:21:20
Is this needed here? You don't seem to look at han
rmacnak
2014/08/21 22:06:44
True; removed.
| |
369 // the search, but restored before returning. | |
370 RawObject* raw = obj->raw(); | |
371 *obj = Object::null(); | |
372 InboundReferencesVisitor visitor(isolate(), raw, path, &scratch); | |
373 isolate()->heap()->IterateObjects(&visitor); | |
374 *obj = raw; | |
375 return visitor.length(); | |
376 } | |
377 | |
304 } // namespace dart | 378 } // namespace dart |
OLD | NEW |