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

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) {
5187 static Object* search_target; 5187 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
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_in_trace_ = false;
5193 object_stack_.Clear();
5194
5195 MarkRecursively(root);
5196 UnmarkRecursively(root);
5197 ProcessResults();
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) {
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_in_trace_) 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_in_trace_ = true;
5215 found_target_ = true;
5223 return; 5216 return;
5224 } 5217 }
5225 5218
5219 bool is_global_context = obj->IsGlobalContext();
5220
5226 // not visited yet 5221 // not visited yet
5227 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); 5222 Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
5228 5223
5229 Address map_addr = map_p->address(); 5224 Address map_addr = map_p->address();
5230 5225
5231 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag)); 5226 obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag));
5232 5227
5233 MarkObjectRecursively(&map); 5228 // Scan the object body.
5229 if (is_global_context && skip_weak_refs_) {
5230 // This is specialized to scan Context's properly.
5231 Object** start = reinterpret_cast<Object**>(obj->address() +
5232 Context::kHeaderSize);
5233 Object** end = reinterpret_cast<Object**>(obj->address() +
5234 Context::kHeaderSize + Context::FIRST_WEAK_SLOT * kPointerSize);
5235 mark_visitor.VisitPointers(start, end);
5236 } else {
5237 obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p),
5238 &mark_visitor);
5239 }
5234 5240
5235 obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p), 5241 // Scan the map after the body because the body is a lot more interesting
5236 &mark_visitor); 5242 // when doing leak detection.
5243 MarkRecursively(&map);
5237 5244
5238 if (!found_target) // don't pop if found the target 5245 if (!found_target_in_trace_) // don't pop if found the target
5239 object_stack.RemoveLast(); 5246 object_stack_.RemoveLast();
5240 } 5247 }
5241 5248
5242 5249
5243 static void UnmarkObjectRecursively(Object** p); 5250 void PathTracer::UnmarkRecursively(Object** p) {
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; 5251 if (!(*p)->IsHeapObject()) return;
5259 5252
5260 HeapObject* obj = HeapObject::cast(*p); 5253 HeapObject* obj = HeapObject::cast(*p);
5261 5254
5262 Object* map = obj->map(); 5255 Object* map = obj->map();
5263 5256
5264 if (map->IsHeapObject()) return; // unmarked already 5257 if (map->IsHeapObject()) return; // unmarked already
5265 5258
5266 Address map_addr = reinterpret_cast<Address>(map); 5259 Address map_addr = reinterpret_cast<Address>(map);
5267 5260
5268 map_addr -= kMarkTag; 5261 map_addr -= kMarkTag;
5269 5262
5270 ASSERT_TAG_ALIGNED(map_addr); 5263 ASSERT_TAG_ALIGNED(map_addr);
5271 5264
5272 HeapObject* map_p = HeapObject::FromAddress(map_addr); 5265 HeapObject* map_p = HeapObject::FromAddress(map_addr);
5273 5266
5274 obj->set_map(reinterpret_cast<Map*>(map_p)); 5267 obj->set_map(reinterpret_cast<Map*>(map_p));
5275 5268
5276 UnmarkObjectRecursively(reinterpret_cast<Object**>(&map_p)); 5269 UnmarkRecursively(reinterpret_cast<Object**>(&map_p));
5277 5270
5278 obj->IterateBody(Map::cast(map_p)->instance_type(), 5271 obj->IterateBody(Map::cast(map_p)->instance_type(),
5279 obj->SizeFromMap(Map::cast(map_p)), 5272 obj->SizeFromMap(Map::cast(map_p)),
5280 &unmark_visitor); 5273 &unmark_visitor);
5281 } 5274 }
5282 5275
5283 5276
5284 static void MarkRootObjectRecursively(Object** root) { 5277 void PathTracer::ProcessResults() {
5285 if (search_for_any_global) { 5278 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"); 5279 PrintF("=====================================\n");
5298 PrintF("==== Path to object ====\n"); 5280 PrintF("==== Path to object ====\n");
5299 PrintF("=====================================\n\n"); 5281 PrintF("=====================================\n\n");
5300 5282
5301 ASSERT(!object_stack.is_empty()); 5283 ASSERT(!object_stack_.is_empty());
5302 for (int i = 0; i < object_stack.length(); i++) { 5284 for (int i = 0; i < object_stack_.length(); i++) {
5303 if (i > 0) PrintF("\n |\n |\n V\n\n"); 5285 if (i > 0) PrintF("\n |\n |\n V\n\n");
5304 Object* obj = object_stack[i]; 5286 Object* obj = object_stack_[i];
5305 obj->Print(); 5287 obj->Print();
5306 } 5288 }
5307 PrintF("=====================================\n"); 5289 PrintF("=====================================\n");
5308 } 5290 }
5309 } 5291 }
5292 #endif // DEBUG || LIVE_OBJECT_LIST
5310 5293
5311 5294
5312 // Helper class for visiting HeapObjects recursively. 5295 #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 5296 // Triggers a depth-first traversal of reachable objects from roots
5326 // and finds a path to a specific heap object and prints it. 5297 // and finds a path to a specific heap object and prints it.
5327 void Heap::TracePathToObject(Object* target) { 5298 void Heap::TracePathToObject(Object* target) {
5328 search_target = target; 5299 PathTracer tracer(target, false, PathTracer::kFindAll, false);
5329 search_for_any_global = false; 5300 IterateRoots(&tracer, VISIT_ONLY_STRONG);
5330
5331 MarkRootVisitor root_visitor;
5332 IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
5333 } 5301 }
5334 5302
5335 5303
5336 // Triggers a depth-first traversal of reachable objects from roots 5304 // Triggers a depth-first traversal of reachable objects from roots
5337 // and finds a path to any global object and prints it. Useful for 5305 // and finds a path to any global object and prints it. Useful for
5338 // determining the source for leaks of global objects. 5306 // determining the source for leaks of global objects.
5339 void Heap::TracePathToGlobal() { 5307 void Heap::TracePathToGlobal() {
5340 search_target = NULL; 5308 PathTracer tracer(NULL, true, PathTracer::kFindAll, false);
5341 search_for_any_global = true; 5309 IterateRoots(&tracer, VISIT_ONLY_STRONG);
5342
5343 MarkRootVisitor root_visitor;
5344 IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
5345 } 5310 }
5346 #endif 5311 #endif
5347 5312
5348 5313
5349 static intptr_t CountTotalHolesSize() { 5314 static intptr_t CountTotalHolesSize() {
5350 intptr_t holes_size = 0; 5315 intptr_t holes_size = 0;
5351 OldSpaces spaces; 5316 OldSpaces spaces;
5352 for (OldSpace* space = spaces.next(); 5317 for (OldSpace* space = spaces.next();
5353 space != NULL; 5318 space != NULL;
5354 space = spaces.next()) { 5319 space = spaces.next()) {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
5587 void ExternalStringTable::TearDown() { 5552 void ExternalStringTable::TearDown() {
5588 new_space_strings_.Free(); 5553 new_space_strings_.Free();
5589 old_space_strings_.Free(); 5554 old_space_strings_.Free();
5590 } 5555 }
5591 5556
5592 5557
5593 List<Object*> ExternalStringTable::new_space_strings_; 5558 List<Object*> ExternalStringTable::new_space_strings_;
5594 List<Object*> ExternalStringTable::old_space_strings_; 5559 List<Object*> ExternalStringTable::old_space_strings_;
5595 5560
5596 } } // namespace v8::internal 5561 } } // 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