| OLD | NEW |
| 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 Loading... |
| 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) { |
| 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 Loading... |
| 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 // We have to adjust size to keep information in entries_ fresh. |
| 430 entries_.at(from_entry_info_index).size = object_size; |
| 429 to_entry->value = from_value; | 431 to_entry->value = from_value; |
| 430 } | 432 } |
| 431 } | 433 } |
| 432 | 434 |
| 433 | 435 |
| 436 void HeapObjectsMap::NewObject(Address addr, int size) { |
| 437 ASSERT(addr != NULL); |
| 438 FindOrAddEntry(addr, size, false); |
| 439 } |
| 440 |
| 441 |
| 434 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { | 442 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
| 435 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 443 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
| 436 false); | 444 false); |
| 437 if (entry == NULL) return 0; | 445 if (entry == NULL) return 0; |
| 438 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 446 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 439 EntryInfo& entry_info = entries_.at(entry_index); | 447 EntryInfo& entry_info = entries_.at(entry_index); |
| 440 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 448 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| 441 return entry_info.id; | 449 return entry_info.id; |
| 442 } | 450 } |
| 443 | 451 |
| 444 | 452 |
| 445 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, | 453 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, |
| 446 unsigned int size) { | 454 unsigned int size, |
| 455 bool accessed) { |
| 447 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 456 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| 448 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 457 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
| 449 true); | 458 true); |
| 450 if (entry->value != NULL) { | 459 if (entry->value != NULL) { |
| 451 int entry_index = | 460 int entry_index = |
| 452 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 461 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 453 EntryInfo& entry_info = entries_.at(entry_index); | 462 EntryInfo& entry_info = entries_.at(entry_index); |
| 454 entry_info.accessed = true; | 463 entry_info.accessed = accessed; |
| 455 entry_info.size = size; | 464 entry_info.size = size; |
| 456 return entry_info.id; | 465 return entry_info.id; |
| 457 } | 466 } |
| 458 entry->value = reinterpret_cast<void*>(entries_.length()); | 467 entry->value = reinterpret_cast<void*>(entries_.length()); |
| 459 SnapshotObjectId id = next_id_; | 468 SnapshotObjectId id = next_id_; |
| 460 next_id_ += kObjectIdStep; | 469 next_id_ += kObjectIdStep; |
| 461 entries_.Add(EntryInfo(id, addr, size)); | 470 entries_.Add(EntryInfo(id, addr, size, accessed)); |
| 462 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 471 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| 463 return id; | 472 return id; |
| 464 } | 473 } |
| 465 | 474 |
| 466 | 475 |
| 467 void HeapObjectsMap::StopHeapObjectsTracking() { | 476 void HeapObjectsMap::StopHeapObjectsTracking() { |
| 468 time_intervals_.Clear(); | 477 time_intervals_.Clear(); |
| 469 } | 478 } |
| 470 | 479 |
| 471 | 480 |
| 472 void HeapObjectsMap::UpdateHeapObjectsMap() { | 481 void HeapObjectsMap::UpdateHeapObjectsMap() { |
| 473 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 482 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 474 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); | 483 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); |
| 475 HeapIterator iterator(heap_); | 484 HeapIterator iterator(heap_); |
| 476 for (HeapObject* obj = iterator.next(); | 485 for (HeapObject* obj = iterator.next(); |
| 477 obj != NULL; | 486 obj != NULL; |
| 478 obj = iterator.next()) { | 487 obj = iterator.next()) { |
| 479 FindOrAddEntry(obj->address(), obj->Size()); | 488 FindOrAddEntry(obj->address(), obj->Size()); |
| 480 } | 489 } |
| 481 RemoveDeadEntries(); | 490 RemoveDeadEntries(); |
| 482 } | 491 } |
| 483 | 492 |
| 484 | 493 |
| 494 int HeapObjectsMap::CheckAllocationsTracking() { |
| 495 HeapIterator iterator(heap_); |
| 496 int untracked = 0; |
| 497 for (HeapObject* obj = iterator.next(); |
| 498 obj != NULL; |
| 499 obj = iterator.next()) { |
| 500 HashMap::Entry* entry = entries_map_.Lookup( |
| 501 obj->address(), ComputePointerHash(obj->address()), false); |
| 502 if (entry == NULL) { |
| 503 untracked++; |
| 504 } else { |
| 505 #ifdef DEBUG |
| 506 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value
)); |
| 507 EntryInfo& entry_info = entries_.at(entry_index); |
| 508 ASSERT_EQ(obj->Size(), static_cast<int>(entry_info.size)); |
| 509 #endif |
| 510 } |
| 511 } |
| 512 return untracked; |
| 513 } |
| 514 |
| 515 |
| 485 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { | 516 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { |
| 486 UpdateHeapObjectsMap(); | 517 UpdateHeapObjectsMap(); |
| 487 time_intervals_.Add(TimeInterval(next_id_)); | 518 time_intervals_.Add(TimeInterval(next_id_)); |
| 488 int prefered_chunk_size = stream->GetChunkSize(); | 519 int prefered_chunk_size = stream->GetChunkSize(); |
| 489 List<v8::HeapStatsUpdate> stats_buffer; | 520 List<v8::HeapStatsUpdate> stats_buffer; |
| 490 ASSERT(!entries_.is_empty()); | 521 ASSERT(!entries_.is_empty()); |
| 491 EntryInfo* entry_info = &entries_.first(); | 522 EntryInfo* entry_info = &entries_.first(); |
| 492 EntryInfo* end_entry_info = &entries_.last() + 1; | 523 EntryInfo* end_entry_info = &entries_.last() + 1; |
| 493 for (int time_interval_index = 0; | 524 for (int time_interval_index = 0; |
| 494 time_interval_index < time_intervals_.length(); | 525 time_interval_index < time_intervals_.length(); |
| (...skipping 2208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2703 | 2734 |
| 2704 | 2735 |
| 2705 void HeapSnapshotJSONSerializer::SortHashMap( | 2736 void HeapSnapshotJSONSerializer::SortHashMap( |
| 2706 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 2737 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
| 2707 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 2738 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
| 2708 sorted_entries->Add(p); | 2739 sorted_entries->Add(p); |
| 2709 sorted_entries->Sort(SortUsingEntryValue); | 2740 sorted_entries->Sort(SortUsingEntryValue); |
| 2710 } | 2741 } |
| 2711 | 2742 |
| 2712 } } // namespace v8::internal | 2743 } } // namespace v8::internal |
| OLD | NEW |