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

Unified Diff: src/heap.cc

Issue 6541044: Refactored PathTracer in heap.cc.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 10 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 side-by-side diff with in-line comments
Download patch
« src/heap.h ('K') | « src/heap.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap.cc
===================================================================
--- src/heap.cc (revision 6858)
+++ src/heap.cc (working copy)
@@ -5181,32 +5181,24 @@
}
-#ifdef DEBUG
+#if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
-static bool search_for_any_global;
-static Object* search_target;
-static bool found_target;
-static List<Object*> object_stack(20);
-
-
-// Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject.
-static const int kMarkTag = 2;
-
-static void MarkObjectRecursively(Object** p);
-class MarkObjectVisitor : public ObjectVisitor {
- public:
- void VisitPointers(Object** start, Object** end) {
- // Copy all HeapObject pointers in [start, end)
- for (Object** p = start; p < end; p++) {
- if ((*p)->IsHeapObject())
- MarkObjectRecursively(p);
- }
+void PathTracer::TracePathFrom(Object** root) {
+ if (search_for_any_global_) {
mnaganov (inactive) 2011/02/21 10:59:46 Using two version of the constructor instead of ru
marklam 2011/02/21 17:45:15 This is code that was originally there from the Ma
+ ASSERT(search_target_ == NULL);
+ } else {
+ ASSERT(search_target_->IsHeapObject());
}
-};
+ found_target_in_trace_ = false;
+ object_stack_.Clear();
-static MarkObjectVisitor mark_visitor;
+ MarkRecursively(root);
+ UnmarkRecursively(root);
+ ProcessResults();
+}
-static void MarkObjectRecursively(Object** p) {
+
+void PathTracer::MarkRecursively(Object** p) {
if (!(*p)->IsHeapObject()) return;
HeapObject* obj = HeapObject::cast(*p);
@@ -5215,14 +5207,17 @@
if (!map->IsHeapObject()) return; // visited before
- if (found_target) return; // stop if target found
- object_stack.Add(obj);
- if ((search_for_any_global && obj->IsJSGlobalObject()) ||
- (!search_for_any_global && (obj == search_target))) {
- found_target = true;
+ if (found_target_in_trace_) return; // stop if target found
+ object_stack_.Add(obj);
+ if ((search_for_any_global_ && obj->IsJSGlobalObject()) ||
+ (!search_for_any_global_ && (obj == search_target_))) {
+ found_target_in_trace_ = true;
+ found_target_ = true;
return;
}
+ bool is_global_context = obj->IsGlobalContext();
+
// not visited yet
Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
@@ -5230,31 +5225,29 @@
obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag));
- MarkObjectRecursively(&map);
+ // Scan the object body.
+ if (is_global_context && skip_weak_refs_) {
+ // This is specialized to scan Context's properly.
+ Object** start = reinterpret_cast<Object**>(obj->address() +
+ Context::kHeaderSize);
+ Object** end = reinterpret_cast<Object**>(obj->address() +
+ Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize);
+ mark_visitor.VisitPointers(start, end);
+ } else {
+ obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p),
+ &mark_visitor);
+ }
- obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p),
- &mark_visitor);
+ // Scan the map after the body because the body is a lot more interesting
+ // when doing leak detection.
+ MarkRecursively(&map);
- if (!found_target) // don't pop if found the target
- object_stack.RemoveLast();
+ if (!found_target_in_trace_) // don't pop if found the target
+ object_stack_.RemoveLast();
}
-static void UnmarkObjectRecursively(Object** p);
-class UnmarkObjectVisitor : public ObjectVisitor {
- public:
- void VisitPointers(Object** start, Object** end) {
- // Copy all HeapObject pointers in [start, end)
- for (Object** p = start; p < end; p++) {
- if ((*p)->IsHeapObject())
- UnmarkObjectRecursively(p);
- }
- }
-};
-
-static UnmarkObjectVisitor unmark_visitor;
-
-static void UnmarkObjectRecursively(Object** p) {
+void PathTracer::UnmarkRecursively(Object** p) {
if (!(*p)->IsHeapObject()) return;
HeapObject* obj = HeapObject::cast(*p);
@@ -5273,7 +5266,7 @@
obj->set_map(reinterpret_cast<Map*>(map_p));
- UnmarkObjectRecursively(reinterpret_cast<Object**>(&map_p));
+ UnmarkRecursively(reinterpret_cast<Object**>(&map_p));
obj->IterateBody(Map::cast(map_p)->instance_type(),
obj->SizeFromMap(Map::cast(map_p)),
@@ -5281,55 +5274,30 @@
}
-static void MarkRootObjectRecursively(Object** root) {
- if (search_for_any_global) {
- ASSERT(search_target == NULL);
- } else {
- ASSERT(search_target->IsHeapObject());
- }
- found_target = false;
- object_stack.Clear();
-
- MarkObjectRecursively(root);
- UnmarkObjectRecursively(root);
-
- if (found_target) {
+void PathTracer::ProcessResults() {
+ if (found_target_) {
PrintF("=====================================\n");
PrintF("==== Path to object ====\n");
PrintF("=====================================\n\n");
- ASSERT(!object_stack.is_empty());
- for (int i = 0; i < object_stack.length(); i++) {
+ ASSERT(!object_stack_.is_empty());
+ for (int i = 0; i < object_stack_.length(); i++) {
if (i > 0) PrintF("\n |\n |\n V\n\n");
- Object* obj = object_stack[i];
+ Object* obj = object_stack_[i];
obj->Print();
}
PrintF("=====================================\n");
}
}
+#endif // DEBUG || LIVE_OBJECT_LIST
-// Helper class for visiting HeapObjects recursively.
-class MarkRootVisitor: public ObjectVisitor {
- public:
- void VisitPointers(Object** start, Object** end) {
- // Visit all HeapObject pointers in [start, end)
- for (Object** p = start; p < end; p++) {
- if ((*p)->IsHeapObject())
- MarkRootObjectRecursively(p);
- }
- }
-};
-
-
+#ifdef DEBUG
// Triggers a depth-first traversal of reachable objects from roots
// and finds a path to a specific heap object and prints it.
void Heap::TracePathToObject(Object* target) {
- search_target = target;
- search_for_any_global = false;
-
- MarkRootVisitor root_visitor;
- IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
+ PathTracer tracer(target, false, PathTracer::kFindAll, false);
+ IterateRoots(&tracer, VISIT_ONLY_STRONG);
}
@@ -5337,11 +5305,8 @@
// and finds a path to any global object and prints it. Useful for
// determining the source for leaks of global objects.
void Heap::TracePathToGlobal() {
- search_target = NULL;
- search_for_any_global = true;
-
- MarkRootVisitor root_visitor;
- IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
+ PathTracer tracer(NULL, true, PathTracer::kFindAll, false);
+ IterateRoots(&tracer, VISIT_ONLY_STRONG);
}
#endif
« src/heap.h ('K') | « src/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698