| 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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 // HeapObjectsMap::GenerateId) and odds for native objects. | 362 // HeapObjectsMap::GenerateId) and odds for native objects. |
| 363 const SnapshotObjectId HeapObjectsMap::kInternalRootObjectId = 1; | 363 const SnapshotObjectId HeapObjectsMap::kInternalRootObjectId = 1; |
| 364 const SnapshotObjectId HeapObjectsMap::kGcRootsObjectId = | 364 const SnapshotObjectId HeapObjectsMap::kGcRootsObjectId = |
| 365 HeapObjectsMap::kInternalRootObjectId + HeapObjectsMap::kObjectIdStep; | 365 HeapObjectsMap::kInternalRootObjectId + HeapObjectsMap::kObjectIdStep; |
| 366 const SnapshotObjectId HeapObjectsMap::kGcRootsFirstSubrootId = | 366 const SnapshotObjectId HeapObjectsMap::kGcRootsFirstSubrootId = |
| 367 HeapObjectsMap::kGcRootsObjectId + HeapObjectsMap::kObjectIdStep; | 367 HeapObjectsMap::kGcRootsObjectId + HeapObjectsMap::kObjectIdStep; |
| 368 const SnapshotObjectId HeapObjectsMap::kFirstAvailableObjectId = | 368 const SnapshotObjectId HeapObjectsMap::kFirstAvailableObjectId = |
| 369 HeapObjectsMap::kGcRootsFirstSubrootId + | 369 HeapObjectsMap::kGcRootsFirstSubrootId + |
| 370 VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep; | 370 VisitorSynchronization::kNumberOfSyncTags * HeapObjectsMap::kObjectIdStep; |
| 371 | 371 |
| 372 | |
| 373 static bool AddressesMatch(void* key1, void* key2) { | |
| 374 return key1 == key2; | |
| 375 } | |
| 376 | |
| 377 | |
| 378 HeapObjectsMap::HeapObjectsMap(Heap* heap) | 372 HeapObjectsMap::HeapObjectsMap(Heap* heap) |
| 379 : next_id_(kFirstAvailableObjectId), | 373 : next_id_(kFirstAvailableObjectId), |
| 380 entries_map_(AddressesMatch), | 374 entries_map_(AddressesMatch), |
| 381 heap_(heap) { | 375 heap_(heap) { |
| 382 // This dummy element solves a problem with entries_map_. | 376 // This dummy element solves a problem with entries_map_. |
| 383 // When we do lookup in HashMap we see no difference between two cases: | 377 // When we do lookup in HashMap we see no difference between two cases: |
| 384 // it has an entry with NULL as the value or it has created | 378 // it has an entry with NULL as the value or it has created |
| 385 // a new entry on the fly with NULL as the default value. | 379 // a new entry on the fly with NULL as the default value. |
| 386 // With such dummy element we have a guaranty that all entries_map_ entries | 380 // With such dummy element we have a guaranty that all entries_map_ entries |
| 387 // will have the value field grater than 0. | 381 // will have the value field grater than 0. |
| 388 // This fact is using in MoveObject method. | 382 // This fact is using in MoveObject method. |
| 389 entries_.Add(EntryInfo(0, NULL, 0)); | 383 entries_.Add(EntryInfo(0, NULL, 0)); |
| 390 } | 384 } |
| 391 | 385 |
| 392 | 386 |
| 393 void HeapObjectsMap::SnapshotGenerationFinished() { | 387 void HeapObjectsMap::SnapshotGenerationFinished() { |
| 394 RemoveDeadEntries(); | 388 RemoveDeadEntries(); |
| 395 } | 389 } |
| 396 | 390 |
| 397 | 391 |
| 398 void HeapObjectsMap::MoveObject(Address from, Address to) { | 392 void HeapObjectsMap::MoveObject(Address from, Address to) { |
| 399 ASSERT(to != NULL); | 393 ASSERT(to != NULL); |
| 400 ASSERT(from != NULL); | 394 ASSERT(from != NULL); |
| 401 if (from == to) return; | 395 if (from == to) return; |
| 402 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); | 396 void* from_value = entries_map_.Remove(from, AddressHash(from)); |
| 403 if (from_value == NULL) { | 397 if (from_value == NULL) { |
| 404 // It may occur that some untracked object moves to an address X and there | 398 // 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 | 399 // is a tracked object at that address. In this case we should remove the |
| 406 // entry as we know that the object has died. | 400 // entry as we know that the object has died. |
| 407 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); | 401 void* to_value = entries_map_.Remove(to, AddressHash(to)); |
| 408 if (to_value != NULL) { | 402 if (to_value != NULL) { |
| 409 int to_entry_info_index = | 403 int to_entry_info_index = |
| 410 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); | 404 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); |
| 411 entries_.at(to_entry_info_index).addr = NULL; | 405 entries_.at(to_entry_info_index).addr = NULL; |
| 412 } | 406 } |
| 413 } else { | 407 } else { |
| 414 HashMap::Entry* to_entry = entries_map_.Lookup(to, ComputePointerHash(to), | 408 HashMap::Entry* to_entry = entries_map_.Lookup(to, AddressHash(to), true); |
| 415 true); | |
| 416 if (to_entry->value != NULL) { | 409 if (to_entry->value != NULL) { |
| 417 // We found the existing entry with to address for an old object. | 410 // We found the existing entry with to address for an old object. |
| 418 // Without this operation we will have two EntryInfo's with the same | 411 // Without this operation we will have two EntryInfo's with the same |
| 419 // value in addr field. It is bad because later at RemoveDeadEntries | 412 // value in addr field. It is bad because later at RemoveDeadEntries |
| 420 // one of this entry will be removed with the corresponding entries_map_ | 413 // one of this entry will be removed with the corresponding entries_map_ |
| 421 // entry. | 414 // entry. |
| 422 int to_entry_info_index = | 415 int to_entry_info_index = |
| 423 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); | 416 static_cast<int>(reinterpret_cast<intptr_t>(to_entry->value)); |
| 424 entries_.at(to_entry_info_index).addr = NULL; | 417 entries_.at(to_entry_info_index).addr = NULL; |
| 425 } | 418 } |
| 426 int from_entry_info_index = | 419 int from_entry_info_index = |
| 427 static_cast<int>(reinterpret_cast<intptr_t>(from_value)); | 420 static_cast<int>(reinterpret_cast<intptr_t>(from_value)); |
| 428 entries_.at(from_entry_info_index).addr = to; | 421 entries_.at(from_entry_info_index).addr = to; |
| 429 to_entry->value = from_value; | 422 to_entry->value = from_value; |
| 430 } | 423 } |
| 431 } | 424 } |
| 432 | 425 |
| 433 | 426 |
| 434 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { | 427 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
| 435 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 428 HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), false); |
| 436 false); | |
| 437 if (entry == NULL) return 0; | 429 if (entry == NULL) return 0; |
| 438 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 430 int entry_index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 439 EntryInfo& entry_info = entries_.at(entry_index); | 431 EntryInfo& entry_info = entries_.at(entry_index); |
| 440 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 432 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| 441 return entry_info.id; | 433 return entry_info.id; |
| 442 } | 434 } |
| 443 | 435 |
| 444 | 436 |
| 445 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, | 437 SnapshotObjectId HeapObjectsMap::FindOrAddEntry(Address addr, |
| 446 unsigned int size) { | 438 unsigned int size) { |
| 447 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); | 439 ASSERT(static_cast<uint32_t>(entries_.length()) > entries_map_.occupancy()); |
| 448 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 440 HashMap::Entry* entry = entries_map_.Lookup(addr, AddressHash(addr), true); |
| 449 true); | |
| 450 if (entry->value != NULL) { | 441 if (entry->value != NULL) { |
| 451 int entry_index = | 442 int entry_index = |
| 452 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 443 static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 453 EntryInfo& entry_info = entries_.at(entry_index); | 444 EntryInfo& entry_info = entries_.at(entry_index); |
| 454 entry_info.accessed = true; | 445 entry_info.accessed = true; |
| 455 entry_info.size = size; | 446 entry_info.size = size; |
| 456 return entry_info.id; | 447 return entry_info.id; |
| 457 } | 448 } |
| 458 entry->value = reinterpret_cast<void*>(entries_.length()); | 449 entry->value = reinterpret_cast<void*>(entries_.length()); |
| 459 SnapshotObjectId id = next_id_; | 450 SnapshotObjectId id = next_id_; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 entries_.at(0).addr == NULL); | 525 entries_.at(0).addr == NULL); |
| 535 int first_free_entry = 1; | 526 int first_free_entry = 1; |
| 536 for (int i = 1; i < entries_.length(); ++i) { | 527 for (int i = 1; i < entries_.length(); ++i) { |
| 537 EntryInfo& entry_info = entries_.at(i); | 528 EntryInfo& entry_info = entries_.at(i); |
| 538 if (entry_info.accessed) { | 529 if (entry_info.accessed) { |
| 539 if (first_free_entry != i) { | 530 if (first_free_entry != i) { |
| 540 entries_.at(first_free_entry) = entry_info; | 531 entries_.at(first_free_entry) = entry_info; |
| 541 } | 532 } |
| 542 entries_.at(first_free_entry).accessed = false; | 533 entries_.at(first_free_entry).accessed = false; |
| 543 HashMap::Entry* entry = entries_map_.Lookup( | 534 HashMap::Entry* entry = entries_map_.Lookup( |
| 544 entry_info.addr, ComputePointerHash(entry_info.addr), false); | 535 entry_info.addr, AddressHash(entry_info.addr), false); |
| 545 ASSERT(entry); | 536 ASSERT(entry); |
| 546 entry->value = reinterpret_cast<void*>(first_free_entry); | 537 entry->value = reinterpret_cast<void*>(first_free_entry); |
| 547 ++first_free_entry; | 538 ++first_free_entry; |
| 548 } else { | 539 } else { |
| 549 if (entry_info.addr) { | 540 if (entry_info.addr) { |
| 550 entries_map_.Remove(entry_info.addr, | 541 entries_map_.Remove(entry_info.addr, AddressHash(entry_info.addr)); |
| 551 ComputePointerHash(entry_info.addr)); | |
| 552 } | 542 } |
| 553 } | 543 } |
| 554 } | 544 } |
| 555 entries_.Rewind(first_free_entry); | 545 entries_.Rewind(first_free_entry); |
| 556 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 == | 546 ASSERT(static_cast<uint32_t>(entries_.length()) - 1 == |
| 557 entries_map_.occupancy()); | 547 entries_map_.occupancy()); |
| 558 } | 548 } |
| 559 | 549 |
| 560 | 550 |
| 561 SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) { | 551 SnapshotObjectId HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) { |
| (...skipping 2141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2703 | 2693 |
| 2704 | 2694 |
| 2705 void HeapSnapshotJSONSerializer::SortHashMap( | 2695 void HeapSnapshotJSONSerializer::SortHashMap( |
| 2706 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 2696 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
| 2707 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 2697 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
| 2708 sorted_entries->Add(p); | 2698 sorted_entries->Add(p); |
| 2709 sorted_entries->Sort(SortUsingEntryValue); | 2699 sorted_entries->Sort(SortUsingEntryValue); |
| 2710 } | 2700 } |
| 2711 | 2701 |
| 2712 } } // namespace v8::internal | 2702 } } // namespace v8::internal |
| OLD | NEW |