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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« src/heap.h ('K') | « src/heap.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5163 matching lines...) Expand 10 before | Expand all | Expand 10 after
5174 } 5174 }
5175 5175
5176 5176
5177 void HeapIterator::reset() { 5177 void HeapIterator::reset() {
5178 // Restart the iterator. 5178 // Restart the iterator.
5179 Shutdown(); 5179 Shutdown();
5180 Init(); 5180 Init();
5181 } 5181 }
5182 5182
5183 5183
5184 #ifdef DEBUG 5184 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST)
5185 5185
5186 static bool search_for_any_global; 5186 void PathTracer::TracePathFrom(Object** root) {
marklam 2011/02/20 00:41:15 TracePathFrom() used to be MarkRootObjectRecursive
5187 static Object* search_target; 5187 if (search_for_any_global_) {
5188 static bool found_target; 5188 ASSERT(search_target_ == NULL);
5189 static List<Object*> object_stack(20); 5189 } else {
5190 ASSERT(search_target_->IsHeapObject());
5191 }
5192 found_target_ = false;
5193 object_stack_.Clear();
5194
5195 MarkRecursively(root);
5196 UnmarkRecursively(root);
5197 ProcessResults();
marklam 2011/02/20 00:41:15 ProcessResults() is introduced as a virtual method
5198 }
5190 5199
5191 5200
5192 // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject. 5201 void PathTracer::MarkRecursively(Object** p) {
marklam 2011/02/20 00:41:15 MarkRecursively() used to be MarkObjectRecursively
5193 static const int kMarkTag = 2;
5194
5195 static void MarkObjectRecursively(Object** p);
5196 class MarkObjectVisitor : public ObjectVisitor {
5197 public:
5198 void VisitPointers(Object** start, Object** end) {
5199 // Copy all HeapObject pointers in [start, end)
5200 for (Object** p = start; p < end; p++) {
5201 if ((*p)->IsHeapObject())
5202 MarkObjectRecursively(p);
5203 }
5204 }
5205 };
5206
5207 static MarkObjectVisitor mark_visitor;
5208
5209 static void MarkObjectRecursively(Object** p) {
5210 if (!(*p)->IsHeapObject()) return; 5202 if (!(*p)->IsHeapObject()) return;
5211 5203
5212 HeapObject* obj = HeapObject::cast(*p); 5204 HeapObject* obj = HeapObject::cast(*p);
5213 5205
5214 Object* map = obj->map(); 5206 Object* map = obj->map();
5215 5207
5216 if (!map->IsHeapObject()) return; // visited before 5208 if (!map->IsHeapObject()) return; // visited before
5217 5209
5218 if (found_target) return; // stop if target found 5210 if (found_target_) return; // stop if target found
5219 object_stack.Add(obj); 5211 object_stack_.Add(obj);
5220 if ((search_for_any_global && obj->IsJSGlobalObject()) || 5212 if ((search_for_any_global_ && obj->IsJSGlobalObject()) ||
5221 (!search_for_any_global && (obj == search_target))) { 5213 (!search_for_any_global_ && (obj == search_target_))) {
5222 found_target = true; 5214 found_target_ = true;
5223 return; 5215 return;
5224 } 5216 }
5225 5217
5218 bool is_global_context = obj->IsGlobalContext();
5219
5226 // not visited yet 5220 // not visited yet
5227 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); 5221 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
5228 5222
5229 Address map_addr = map_p->address(); 5223 Address map_addr = map_p->address();
5230 5224
5231 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag)); 5225 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag));
5232 5226
5233 MarkObjectRecursively(&map); 5227 // Scan the object body.
5228 if (is_global_context && skip_weak_refs_) {
5229 // This is specialized to scan Context's properly.
5230 Object** start = reinterpret_cast<Object**>(obj->address() +
5231 Context::kHeaderSize);
5232 Object** end = reinterpret_cast<Object**>(obj->address() +
5233 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize);
5234 mark_visitor.VisitPointers(start, end);
5235 } else {
5236 obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p),
5237 &mark_visitor);
5238 }
marklam 2011/02/20 00:41:15 The pre-existing code would scan all entries in th
5234 5239
5235 obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p), 5240 // Scan the map after the body because the body is a lot more interesting
5236 &mark_visitor); 5241 // when doing leak detection.
5242 MarkRecursively(&map);
marklam 2011/02/20 00:41:15 I moved the tracing of the map after the tracing o
5237 5243
5238 if (!found_target) // don't pop if found the target 5244 if (!found_target_) // don't pop if found the target
5239 object_stack.RemoveLast(); 5245 object_stack_.RemoveLast();
5240 } 5246 }
5241 5247
5242 5248
5243 static void UnmarkObjectRecursively(Object** p); 5249 void PathTracer::UnmarkRecursively(Object** p) {
marklam 2011/02/20 00:41:15 UnmarkRecursively() used to be called UnmarkObject
5244 class UnmarkObjectVisitor : public ObjectVisitor {
5245 public:
5246 void VisitPointers(Object** start, Object** end) {
5247 // Copy all HeapObject pointers in [start, end)
5248 for (Object** p = start; p < end; p++) {
5249 if ((*p)->IsHeapObject())
5250 UnmarkObjectRecursively(p);
5251 }
5252 }
5253 };
5254
5255 static UnmarkObjectVisitor unmark_visitor;
5256
5257 static void UnmarkObjectRecursively(Object** p) {
5258 if (!(*p)->IsHeapObject()) return; 5250 if (!(*p)->IsHeapObject()) return;
5259 5251
5260 HeapObject* obj = HeapObject::cast(*p); 5252 HeapObject* obj = HeapObject::cast(*p);
5261 5253
5262 Object* map = obj->map(); 5254 Object* map = obj->map();
5263 5255
5264 if (map->IsHeapObject()) return; // unmarked already 5256 if (map->IsHeapObject()) return; // unmarked already
5265 5257
5266 Address map_addr = reinterpret_cast<Address>(map); 5258 Address map_addr = reinterpret_cast<Address>(map);
5267 5259
5268 map_addr -= kMarkTag; 5260 map_addr -= kMarkTag;
5269 5261
5270 ASSERT_TAG_ALIGNED(map_addr); 5262 ASSERT_TAG_ALIGNED(map_addr);
5271 5263
5272 HeapObject* map_p = HeapObject::FromAddress(map_addr); 5264 HeapObject* map_p = HeapObject::FromAddress(map_addr);
5273 5265
5274 obj->set_map(reinterpret_cast<Map*>(map_p)); 5266 obj->set_map(reinterpret_cast<Map*>(map_p));
5275 5267
5276 UnmarkObjectRecursively(reinterpret_cast<Object**>(&map_p)); 5268 UnmarkRecursively(reinterpret_cast<Object**>(&map_p));
5277 5269
5278 obj->IterateBody(Map::cast(map_p)->instance_type(), 5270 obj->IterateBody(Map::cast(map_p)->instance_type(),
5279 obj->SizeFromMap(Map::cast(map_p)), 5271 obj->SizeFromMap(Map::cast(map_p)),
5280 &unmark_visitor); 5272 &unmark_visitor);
5281 } 5273 }
5282 5274
5283 5275
5284 static void MarkRootObjectRecursively(Object** root) { 5276 void PathTracer::ProcessResults() {
5285 if (search_for_any_global) { 5277 if (found_target_) {
5286 ASSERT(search_target == NULL);
5287 } else {
5288 ASSERT(search_target->IsHeapObject());
5289 }
5290 found_target = false;
5291 object_stack.Clear();
5292
5293 MarkObjectRecursively(root);
5294 UnmarkObjectRecursively(root);
5295
5296 if (found_target) {
5297 PrintF("=====================================\n"); 5278 PrintF("=====================================\n");
5298 PrintF("==== Path to object ====\n"); 5279 PrintF("==== Path to object ====\n");
5299 PrintF("=====================================\n\n"); 5280 PrintF("=====================================\n\n");
5300 5281
5301 ASSERT(!object_stack.is_empty()); 5282 ASSERT(!object_stack_.is_empty());
5302 for (int i = 0; i < object_stack.length(); i++) { 5283 for (int i = 0; i < object_stack_.length(); i++) {
5303 if (i > 0) PrintF("\n |\n |\n V\n\n"); 5284 if (i > 0) PrintF("\n |\n |\n V\n\n");
5304 Object* obj = object_stack[i]; 5285 Object* obj = object_stack_[i];
5305 obj->Print(); 5286 obj->Print();
5306 } 5287 }
5307 PrintF("=====================================\n"); 5288 PrintF("=====================================\n");
5308 } 5289 }
5309 } 5290 }
5291 #endif // DEBUG || LIVE_OBJECT_LIST
5310 5292
5311 5293
5312 // Helper class for visiting HeapObjects recursively. 5294 #ifdef DEBUG
5313 class MarkRootVisitor: public ObjectVisitor {
5314 public:
5315 void VisitPointers(Object** start, Object** end) {
5316 // Visit all HeapObject pointers in [start, end)
5317 for (Object** p = start; p < end; p++) {
5318 if ((*p)->IsHeapObject())
5319 MarkRootObjectRecursively(p);
5320 }
5321 }
5322 };
5323
5324
5325 // Triggers a depth-first traversal of reachable objects from roots 5295 // Triggers a depth-first traversal of reachable objects from roots
5326 // and finds a path to a specific heap object and prints it. 5296 // and finds a path to a specific heap object and prints it.
5327 void Heap::TracePathToObject(Object* target) { 5297 void Heap::TracePathToObject(Object* target) {
5328 search_target = target; 5298 PathTracer tracer(target, false, PathTracer::kFindAll, false);
5329 search_for_any_global = false; 5299 IterateRoots(&tracer, VISIT_ONLY_STRONG);
5330
5331 MarkRootVisitor root_visitor;
5332 IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
5333 } 5300 }
5334 5301
5335 5302
5336 // Triggers a depth-first traversal of reachable objects from roots 5303 // Triggers a depth-first traversal of reachable objects from roots
5337 // and finds a path to any global object and prints it. Useful for 5304 // and finds a path to any global object and prints it. Useful for
5338 // determining the source for leaks of global objects. 5305 // determining the source for leaks of global objects.
5339 void Heap::TracePathToGlobal() { 5306 void Heap::TracePathToGlobal() {
5340 search_target = NULL; 5307 PathTracer tracer(NULL, true, PathTracer::kFindAll, false);
5341 search_for_any_global = true; 5308 IterateRoots(&tracer, VISIT_ONLY_STRONG);
5342
5343 MarkRootVisitor root_visitor;
5344 IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
5345 } 5309 }
5346 #endif 5310 #endif
5347 5311
5348 5312
5349 static intptr_t CountTotalHolesSize() { 5313 static intptr_t CountTotalHolesSize() {
5350 intptr_t holes_size = 0; 5314 intptr_t holes_size = 0;
5351 OldSpaces spaces; 5315 OldSpaces spaces;
5352 for (OldSpace* space = spaces.next(); 5316 for (OldSpace* space = spaces.next();
5353 space != NULL; 5317 space != NULL;
5354 space = spaces.next()) { 5318 space = spaces.next()) {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5587 void ExternalStringTable::TearDown() { 5551 void ExternalStringTable::TearDown() {
5588 new_space_strings_.Free(); 5552 new_space_strings_.Free();
5589 old_space_strings_.Free(); 5553 old_space_strings_.Free();
5590 } 5554 }
5591 5555
5592 5556
5593 List<Object*> ExternalStringTable::new_space_strings_; 5557 List<Object*> ExternalStringTable::new_space_strings_;
5594 List<Object*> ExternalStringTable::old_space_strings_; 5558 List<Object*> ExternalStringTable::old_space_strings_;
5595 5559
5596 } } // namespace v8::internal 5560 } } // namespace v8::internal
OLDNEW
« 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