| 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); | 
 |   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 void HeapObjectsMap::UpdateMap() { | 
 |   504   HeapIterator iterator(heap_); | 
 |   505   for (HeapObject* obj = iterator.next(); | 
 |   506        obj != NULL; | 
 |   507        obj = iterator.next()) { | 
 |   508     FindOrAddEntry(obj->address(), obj->Size()); | 
 |   509   } | 
 |   510 } | 
 |   511  | 
 |   512  | 
 |   513 int HeapObjectsMap::FindUntrackedObjects() { | 
 |   514   HeapIterator iterator(heap_); | 
 |   515   int untracked = 0; | 
 |   516   for (HeapObject* obj = iterator.next(); | 
 |   517        obj != NULL; | 
 |   518        obj = iterator.next()) { | 
 |   519     HashMap::Entry* entry = entries_map_.Lookup( | 
 |   520       obj->address(), ComputePointerHash(obj->address()), false); | 
 |   521     if (entry == NULL) { | 
 |   522       untracked++; | 
 |   523     } else { | 
 |   524       int entry_index = static_cast<int>( | 
 |   525           reinterpret_cast<intptr_t>(entry->value)); | 
 |   526       EntryInfo& entry_info = entries_.at(entry_index); | 
 |   527       CHECK_EQ(obj->Size(), static_cast<int>(entry_info.size)); | 
 |   528     } | 
 |   529   } | 
 |   530   return untracked; | 
 |   531 } | 
 |   532  | 
 |   533  | 
|   487 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { |   534 SnapshotObjectId HeapObjectsMap::PushHeapObjectsStats(OutputStream* stream) { | 
|   488   UpdateHeapObjectsMap(); |   535   UpdateHeapObjectsMap(); | 
|   489   time_intervals_.Add(TimeInterval(next_id_)); |   536   time_intervals_.Add(TimeInterval(next_id_)); | 
|   490   int prefered_chunk_size = stream->GetChunkSize(); |   537   int prefered_chunk_size = stream->GetChunkSize(); | 
|   491   List<v8::HeapStatsUpdate> stats_buffer; |   538   List<v8::HeapStatsUpdate> stats_buffer; | 
|   492   ASSERT(!entries_.is_empty()); |   539   ASSERT(!entries_.is_empty()); | 
|   493   EntryInfo* entry_info = &entries_.first(); |   540   EntryInfo* entry_info = &entries_.first(); | 
|   494   EntryInfo* end_entry_info = &entries_.last() + 1; |   541   EntryInfo* end_entry_info = &entries_.last() + 1; | 
|   495   for (int time_interval_index = 0; |   542   for (int time_interval_index = 0; | 
|   496        time_interval_index < time_intervals_.length(); |   543        time_interval_index < time_intervals_.length(); | 
| (...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2706   writer_->AddString("\"<dummy>\""); |  2753   writer_->AddString("\"<dummy>\""); | 
|  2707   for (int i = 1; i < sorted_strings.length(); ++i) { |  2754   for (int i = 1; i < sorted_strings.length(); ++i) { | 
|  2708     writer_->AddCharacter(','); |  2755     writer_->AddCharacter(','); | 
|  2709     SerializeString(sorted_strings[i]); |  2756     SerializeString(sorted_strings[i]); | 
|  2710     if (writer_->aborted()) return; |  2757     if (writer_->aborted()) return; | 
|  2711   } |  2758   } | 
|  2712 } |  2759 } | 
|  2713  |  2760  | 
|  2714  |  2761  | 
|  2715 } }  // namespace v8::internal |  2762 } }  // namespace v8::internal | 
| OLD | NEW |