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 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 // This fact is using in MoveObject method. | 390 // This fact is using in MoveObject method. |
391 entries_.Add(EntryInfo(0, NULL, 0)); | 391 entries_.Add(EntryInfo(0, NULL, 0)); |
392 } | 392 } |
393 | 393 |
394 | 394 |
395 void HeapObjectsMap::SnapshotGenerationFinished() { | 395 void HeapObjectsMap::SnapshotGenerationFinished() { |
396 RemoveDeadEntries(); | 396 RemoveDeadEntries(); |
397 } | 397 } |
398 | 398 |
399 | 399 |
400 void HeapObjectsMap::MoveObject(Address from, Address to) { | 400 void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { |
401 ASSERT(to != NULL); | 401 ASSERT(to != NULL); |
402 ASSERT(from != NULL); | 402 ASSERT(from != NULL); |
403 if (from == to) return; | 403 if (from == to) return; |
404 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); | 404 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); |
405 if (from_value == NULL) { | 405 if (from_value == NULL) { |
406 // It may occur that some untracked object moves to an address X and there | 406 // It may occur that some untracked object moves to an address X and there |
407 // is a tracked object at that address. In this case we should remove the | 407 // is a tracked object at that address. In this case we should remove the |
408 // entry as we know that the object has died. | 408 // entry as we know that the object has died. |
409 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); | 409 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); |
410 if (to_value != NULL) { | 410 if (to_value != NULL) { |
(...skipping 10 matching lines...) Expand all Loading... | |
421 // value in addr field. It is bad because later at RemoveDeadEntries | 421 // value in addr field. It is bad because later at RemoveDeadEntries |
422 // one of this entry will be removed with the corresponding entries_map_ | 422 // one of this entry will be removed with the corresponding entries_map_ |
423 // entry. | 423 // entry. |
424 int to_entry_info_index = | 424 int to_entry_info_index = |
425 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); | 425 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); |
426 entries_.at(to_entry_info_index).addr = NULL; | 426 entries_.at(to_entry_info_index).addr = NULL; |
427 } | 427 } |
428 int from_entry_info_index = | 428 int from_entry_info_index = |
429 static_cast<int>(reinterpret_cast<intptr_t>(from_value)); | 429 static_cast<int>(reinterpret_cast<intptr_t>(from_value)); |
430 entries_.at(from_entry_info_index).addr = to; | 430 entries_.at(from_entry_info_index).addr = to; |
431 // Size of an object can change during its life, so to keep information | |
432 // about the object in entries_ consistent, we have to adjust size when the | |
433 // object is migrated. | |
434 entries_.at(from_entry_info_index).size = object_size; | |
431 to_entry->value = from_value; | 435 to_entry->value = from_value; |
432 } | 436 } |
433 } | 437 } |
434 | 438 |
435 | 439 |
440 void HeapObjectsMap::NewObject(Address addr, int size) { | |
441 ASSERT(addr != NULL); | |
442 FindOrAddEntry(addr, size, false); | |
443 } | |
444 | |
445 | |
446 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) { | |
447 FindOrAddEntry(addr, size, false); | |
Hannes Payer (out of office)
2013/10/02 18:00:29
Why do we have two implementations of the same fun
Alexandra Mikhaylova
2013/10/03 16:27:55
Sometimes we want just to update the information (
Hannes Payer (out of office)
2013/10/10 18:54:40
Since both functions implement the same functional
| |
448 } | |
449 | |
450 | |
436 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { | 451 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
437 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 452 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
438 false); | 453 false); |
439 if (entry == NULL) return 0; | 454 if (entry == NULL) return 0; |
440 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 455 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
441 EntryInfo& entry_info = entries_.at(entry_index); | 456 EntryInfo& entry_info = entries_.at(entry_index); |
442 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 457 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
443 return entry_info.id; | 458 return entry_info.id; |
444 } | 459 } |
445 | 460 |
446 | 461 |
447 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, | 462 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, |
448 unsigned int size) { | 463 unsigned int size, |
464 bool accessed) { | |
449 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 465 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
450 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 466 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
451 true); | 467 true); |
452 if (entry->value != NULL) { | 468 if (entry->value != NULL) { |
453 int entry_index = | 469 int entry_index = |
454 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 470 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
455 EntryInfo& entry_info = entries_.at(entry_index); | 471 EntryInfo& entry_info = entries_.at(entry_index); |
456 entry_info.accessed = true; | 472 entry_info.accessed = accessed; |
457 entry_info.size = size; | 473 entry_info.size = size; |
458 return entry_info.id; | 474 return entry_info.id; |
459 } | 475 } |
460 entry->value = reinterpret_cast<void*>(entries_.length()); | 476 entry->value = reinterpret_cast<void*>(entries_.length()); |
461 SnapshotObjectId id = next_id_; | 477 SnapshotObjectId id = next_id_; |
462 next_id_ += kObjectIdStep; | 478 next_id_ += kObjectIdStep; |
463 entries_.Add(EntryInfo(id, addr, size)); | 479 entries_.Add(EntryInfo(id, addr, size, accessed)); |
464 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 480 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
465 return id; | 481 return id; |
466 } | 482 } |
467 | 483 |
468 | 484 |
469 void HeapObjectsMap::StopHeapObjectsTracking() { | 485 void HeapObjectsMap::StopHeapObjectsTracking() { |
470 time_intervals_.Clear(); | 486 time_intervals_.Clear(); |
471 } | 487 } |
472 | 488 |
473 | 489 |
474 void HeapObjectsMap::UpdateHeapObjectsMap() { | 490 void HeapObjectsMap::UpdateHeapObjectsMap() { |
475 heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 491 heap_->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
476 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); | 492 "HeapSnapshotsCollection::UpdateHeapObjectsMap"); |
477 HeapIterator iterator(heap_); | 493 HeapIterator iterator(heap_); |
478 for (HeapObject* obj = iterator.next(); | 494 for (HeapObject* obj = iterator.next(); |
479 obj != NULL; | 495 obj != NULL; |
480 obj = iterator.next()) { | 496 obj = iterator.next()) { |
481 FindOrAddEntry(obj->address(), obj->Size()); | 497 FindOrAddEntry(obj->address(), obj->Size()); |
482 } | 498 } |
483 RemoveDeadEntries(); | 499 RemoveDeadEntries(); |
484 } | 500 } |
485 | 501 |
486 | 502 |
503 int HeapObjectsMap::FindUntrackedObjects() { | |
504 HeapIterator iterator(heap_); | |
505 int untracked = 0; | |
506 for (HeapObject* obj = iterator.next(); | |
507 obj != NULL; | |
508 obj = iterator.next()) { | |
509 HashMap::Entry* entry = entries_map_.Lookup( | |
510 obj->address(), ComputePointerHash(obj->address()), false); | |
511 if (entry == NULL) { | |
512 untracked++; | |
513 } else { | |
514 int entry_index = static_cast<int>( | |
515 reinterpret_cast<intptr_t>(entry->value)); | |
516 EntryInfo& entry_info = entries_.at(entry_index); | |
517 CHECK_EQ(obj->Size(), static_cast<int>(entry_info.size)); | |
518 } | |
519 } | |
520 return untracked; | |
521 } | |
522 | |
523 | |
487 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { | 524 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { |
488 UpdateHeapObjectsMap(); | 525 UpdateHeapObjectsMap(); |
489 time_intervals_.Add(TimeInterval(next_id_)); | 526 time_intervals_.Add(TimeInterval(next_id_)); |
490 int prefered_chunk_size = stream->GetChunkSize(); | 527 int prefered_chunk_size = stream->GetChunkSize(); |
491 List<v8::HeapStatsUpdate> stats_buffer; | 528 List<v8::HeapStatsUpdate> stats_buffer; |
492 ASSERT(!entries_.is_empty()); | 529 ASSERT(!entries_.is_empty()); |
493 EntryInfo* entry_info = &entries_.first(); | 530 EntryInfo* entry_info = &entries_.first(); |
494 EntryInfo* end_entry_info = &entries_.last() + 1; | 531 EntryInfo* end_entry_info = &entries_.last() + 1; |
495 for (int time_interval_index = 0; | 532 for (int time_interval_index = 0; |
496 time_interval_index < time_intervals_.length(); | 533 time_interval_index < time_intervals_.length(); |
(...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2706 writer_->AddString("\"<dummy>\""); | 2743 writer_->AddString("\"<dummy>\""); |
2707 for (int i = 1; i < sorted_strings.length(); ++i) { | 2744 for (int i = 1; i < sorted_strings.length(); ++i) { |
2708 writer_->AddCharacter(','); | 2745 writer_->AddCharacter(','); |
2709 SerializeString(sorted_strings[i]); | 2746 SerializeString(sorted_strings[i]); |
2710 if (writer_->aborted()) return; | 2747 if (writer_->aborted()) return; |
2711 } | 2748 } |
2712 } | 2749 } |
2713 | 2750 |
2714 | 2751 |
2715 } } // namespace v8::internal | 2752 } } // namespace v8::internal |
OLD | NEW |