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

Side by Side Diff: src/heap-snapshot-generator.cc

Issue 22852024: Track JS allocations as they arrive with no affection on performance when tracking is switched off (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Make separate API for JS allocations recording, add example of checking JS allocations recording in… Created 7 years, 3 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // This fact is using in MoveObject method. 388 // This fact is using in MoveObject method.
389 entries_.Add(EntryInfo(0, NULL, 0)); 389 entries_.Add(EntryInfo(0, NULL, 0));
390 } 390 }
391 391
392 392
393 void HeapObjectsMap::SnapshotGenerationFinished() { 393 void HeapObjectsMap::SnapshotGenerationFinished() {
394 RemoveDeadEntries(); 394 RemoveDeadEntries();
395 } 395 }
396 396
397 397
398 void HeapObjectsMap::MoveObject(Address from, Address to) { 398 void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) {
loislo 2013/08/27 09:04:57 I think that we need new method UpdateObjectSize a
Alexandra Mikhaylova 2013/09/19 16:03:38 Done.
399 ASSERT(to != NULL); 399 ASSERT(to != NULL);
400 ASSERT(from != NULL); 400 ASSERT(from != NULL);
401 if (from == to) return; 401 if (from == to) return;
402 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); 402 void* from_value = entries_map_.Remove(from, ComputePointerHash(from));
403 if (from_value == NULL) { 403 if (from_value == NULL) {
404 // It may occur that some untracked object moves to an address X and there 404 // It may occur that some untracked object moves to an address X and there
405 // is a tracked object at that address. In this case we should remove the 405 // is a tracked object at that address. In this case we should remove the
406 // entry as we know that the object has died. 406 // entry as we know that the object has died.
407 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); 407 void* to_value = entries_map_.Remove(to, ComputePointerHash(to));
408 if (to_value != NULL) { 408 if (to_value != NULL) {
(...skipping 10 matching lines...) Expand all
419 // value in addr field. It is bad because later at RemoveDeadEntries 419 // value in addr field. It is bad because later at RemoveDeadEntries
420 // one of this entry will be removed with the corresponding entries_map_ 420 // one of this entry will be removed with the corresponding entries_map_
421 // entry. 421 // entry.
422 int to_entry_info_index = 422 int to_entry_info_index =
423 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); 423 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value));
424 entries_.at(to_entry_info_index).addr = NULL; 424 entries_.at(to_entry_info_index).addr = NULL;
425 } 425 }
426 int from_entry_info_index = 426 int from_entry_info_index =
427 static_cast<int>(reinterpret_cast<intptr_t>(from_value)); 427 static_cast<int>(reinterpret_cast<intptr_t>(from_value));
428 entries_.at(from_entry_info_index).addr = to; 428 entries_.at(from_entry_info_index).addr = to;
429 // Size of an object can change during its life, so to keep information
430 // about the object in entries_ consistent, we have to adjust size when the
431 // object is migrated.
432 entries_.at(from_entry_info_index).size = object_size;
429 to_entry->value = from_value; 433 to_entry->value = from_value;
430 } 434 }
431 } 435 }
432 436
433 437
438 void HeapObjectsMap::NewObject(Address addr, int size) {
439 ASSERT(addr != NULL);
440 FindOrAddEntry(addr, size, false);
441 }
442
443
434 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { 444 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) {
435 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), 445 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr),
436 false); 446 false);
437 if (entry == NULL) return 0; 447 if (entry == NULL) return 0;
438 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); 448 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
439 EntryInfo& entry_info = entries_.at(entry_index); 449 EntryInfo& entry_info = entries_.at(entry_index);
440 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); 450 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy());
441 return entry_info.id; 451 return entry_info.id;
442 } 452 }
443 453
444 454
445 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, 455 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr,
446 unsigned int size) { 456 unsigned int size,
457 bool accessed) {
447 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); 458 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy());
448 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), 459 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr),
449 true); 460 true);
450 if (entry->value != NULL) { 461 if (entry->value != NULL) {
451 int entry_index = 462 int entry_index =
452 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); 463 static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
453 EntryInfo& entry_info = entries_.at(entry_index); 464 EntryInfo& entry_info = entries_.at(entry_index);
454 entry_info.accessed = true; 465 entry_info.accessed = accessed;
455 entry_info.size = size; 466 entry_info.size = size;
456 return entry_info.id; 467 return entry_info.id;
457 } 468 }
458 entry->value = reinterpret_cast<void*>(entries_.length()); 469 entry->value = reinterpret_cast<void*>(entries_.length());
459 SnapshotObjectId id = next_id_; 470 SnapshotObjectId id = next_id_;
460 next_id_ += kObjectIdStep; 471 next_id_ += kObjectIdStep;
461 entries_.Add(EntryInfo(id, addr, size)); 472 entries_.Add(EntryInfo(id, addr, size, accessed));
462 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); 473 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy());
463 return id; 474 return id;
464 } 475 }
465 476
466 477
467 void HeapObjectsMap::StopHeapObjectsTracking() { 478 void HeapObjectsMap::StopHeapObjectsTracking() {
468 time_intervals_.Clear(); 479 time_intervals_.Clear();
469 } 480 }
470 481
471 482
472 void HeapObjectsMap::UpdateHeapObjectsMap() { 483 void HeapObjectsMap::UpdateHeapObjectsMap() {
473 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, 484 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask,
474 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); 485 "HeapSnapshotsCollection::UpdateHeapObjectsMap");
475 HeapIterator iterator(heap_); 486 HeapIterator iterator(heap_);
476 for (HeapObject* obj = iterator.next(); 487 for (HeapObject* obj = iterator.next();
477 obj != NULL; 488 obj != NULL;
478 obj = iterator.next()) { 489 obj = iterator.next()) {
479 FindOrAddEntry(obj->address(), obj->Size()); 490 FindOrAddEntry(obj->address(), obj->Size());
480 } 491 }
481 RemoveDeadEntries(); 492 RemoveDeadEntries();
482 } 493 }
483 494
484 495
496 int HeapObjectsMap::FindUntrackedObjects() {
497 HeapIterator iterator(heap_);
498 int untracked = 0;
499 for (HeapObject* obj = iterator.next();
500 obj != NULL;
501 obj = iterator.next()) {
502 HashMap::Entry* entry = entries_map_.Lookup(
503 obj->address(), ComputePointerHash(obj->address()), false);
504 if (entry == NULL) {
505 untracked++;
506 } else {
507 int entry_index = static_cast<int>(
508 reinterpret_cast<intptr_t>(entry->value));
509 EntryInfo& entry_info = entries_.at(entry_index);
510 ASSERT_EQ(obj->Size(), static_cast<int>(entry_info.size));
511 }
512 }
513 return untracked;
514 }
515
516
485 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { 517 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) {
486 UpdateHeapObjectsMap(); 518 UpdateHeapObjectsMap();
487 time_intervals_.Add(TimeInterval(next_id_)); 519 time_intervals_.Add(TimeInterval(next_id_));
488 int prefered_chunk_size = stream->GetChunkSize(); 520 int prefered_chunk_size = stream->GetChunkSize();
489 List<v8::HeapStatsUpdate> stats_buffer; 521 List<v8::HeapStatsUpdate> stats_buffer;
490 ASSERT(!entries_.is_empty()); 522 ASSERT(!entries_.is_empty());
491 EntryInfo* entry_info = &entries_.first(); 523 EntryInfo* entry_info = &entries_.first();
492 EntryInfo* end_entry_info = &entries_.last() + 1; 524 EntryInfo* end_entry_info = &entries_.last() + 1;
493 for (int time_interval_index = 0; 525 for (int time_interval_index = 0;
494 time_interval_index < time_intervals_.length(); 526 time_interval_index < time_intervals_.length();
(...skipping 2208 matching lines...) Expand 10 before | Expand all | Expand 10 after
2703 2735
2704 2736
2705 void HeapSnapshotJSONSerializer::SortHashMap( 2737 void HeapSnapshotJSONSerializer::SortHashMap(
2706 HashMap* map, List<HashMap::Entry*>* sorted_entries) { 2738 HashMap* map, List<HashMap::Entry*>* sorted_entries) {
2707 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) 2739 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p))
2708 sorted_entries->Add(p); 2740 sorted_entries->Add(p);
2709 sorted_entries->Sort(SortUsingEntryValue); 2741 sorted_entries->Sort(SortUsingEntryValue);
2710 } 2742 }
2711 2743
2712 } } // namespace v8::internal 2744 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698