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

Side by Side Diff: src/profile-generator.cc

Issue 6759025: Version 3.2.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 8 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
« no previous file with comments | « src/profile-generator.h ('k') | src/regexp-macro-assembler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 977
978 978
979 int HeapEntry::RetainedSize(bool exact) { 979 int HeapEntry::RetainedSize(bool exact) {
980 if (exact && (retained_size_ & kExactRetainedSizeTag) == 0) { 980 if (exact && (retained_size_ & kExactRetainedSizeTag) == 0) {
981 CalculateExactRetainedSize(); 981 CalculateExactRetainedSize();
982 } 982 }
983 return retained_size_ & (~kExactRetainedSizeTag); 983 return retained_size_ & (~kExactRetainedSizeTag);
984 } 984 }
985 985
986 986
987 List<HeapGraphPath*>* HeapEntry::GetRetainingPaths() {
988 return snapshot_->GetRetainingPaths(this);
989 }
990
991
992 template<class Visitor> 987 template<class Visitor>
993 void HeapEntry::ApplyAndPaintAllReachable(Visitor* visitor) { 988 void HeapEntry::ApplyAndPaintAllReachable(Visitor* visitor) {
994 List<HeapEntry*> list(10); 989 List<HeapEntry*> list(10);
995 list.Add(this); 990 list.Add(this);
996 this->paint_reachable(); 991 this->paint_reachable();
997 visitor->Apply(this); 992 visitor->Apply(this);
998 while (!list.is_empty()) { 993 while (!list.is_empty()) {
999 HeapEntry* entry = list.RemoveLast(); 994 HeapEntry* entry = list.RemoveLast();
1000 Vector<HeapGraphEdge> children = entry->children(); 995 Vector<HeapGraphEdge> children = entry->children();
1001 for (int i = 0; i < children.length(); ++i) { 996 for (int i = 0; i < children.length(); ++i) {
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
1140 } 1135 }
1141 1136
1142 RetainedSizeCalculator ret_size_calc; 1137 RetainedSizeCalculator ret_size_calc;
1143 snapshot()->IterateEntries(&ret_size_calc); 1138 snapshot()->IterateEntries(&ret_size_calc);
1144 retained_size_ = ret_size_calc.reained_size(); 1139 retained_size_ = ret_size_calc.reained_size();
1145 ASSERT((retained_size_ & kExactRetainedSizeTag) == 0); 1140 ASSERT((retained_size_ & kExactRetainedSizeTag) == 0);
1146 retained_size_ |= kExactRetainedSizeTag; 1141 retained_size_ |= kExactRetainedSizeTag;
1147 } 1142 }
1148 1143
1149 1144
1150 class CachedHeapGraphPath {
1151 public:
1152 CachedHeapGraphPath()
1153 : nodes_(NodesMatch) { }
1154 CachedHeapGraphPath(const CachedHeapGraphPath& src)
1155 : nodes_(NodesMatch, &HashMap::DefaultAllocator, src.nodes_.capacity()),
1156 path_(src.path_.length() + 1) {
1157 for (HashMap::Entry* p = src.nodes_.Start();
1158 p != NULL;
1159 p = src.nodes_.Next(p)) {
1160 nodes_.Lookup(p->key, p->hash, true);
1161 }
1162 path_.AddAll(src.path_);
1163 }
1164 void Add(HeapGraphEdge* edge) {
1165 nodes_.Lookup(edge->to(), Hash(edge->to()), true);
1166 path_.Add(edge);
1167 }
1168 bool ContainsNode(HeapEntry* node) {
1169 return nodes_.Lookup(node, Hash(node), false) != NULL;
1170 }
1171 const List<HeapGraphEdge*>* path() const { return &path_; }
1172
1173 private:
1174 static uint32_t Hash(HeapEntry* entry) {
1175 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry));
1176 }
1177 static bool NodesMatch(void* key1, void* key2) { return key1 == key2; }
1178
1179 HashMap nodes_;
1180 List<HeapGraphEdge*> path_;
1181 };
1182
1183
1184 List<HeapGraphPath*>* HeapEntry::CalculateRetainingPaths() {
1185 List<HeapGraphPath*>* retaining_paths = new List<HeapGraphPath*>(4);
1186 CachedHeapGraphPath path;
1187 FindRetainingPaths(&path, retaining_paths);
1188 return retaining_paths;
1189 }
1190
1191
1192 void HeapEntry::FindRetainingPaths(CachedHeapGraphPath* prev_path,
1193 List<HeapGraphPath*>* retaining_paths) {
1194 Vector<HeapGraphEdge*> rets = retainers();
1195 for (int i = 0; i < rets.length(); ++i) {
1196 HeapGraphEdge* ret_edge = rets[i];
1197 if (prev_path->ContainsNode(ret_edge->From())) continue;
1198 if (ret_edge->From() != snapshot()->root()) {
1199 CachedHeapGraphPath path(*prev_path);
1200 path.Add(ret_edge);
1201 ret_edge->From()->FindRetainingPaths(&path, retaining_paths);
1202 } else {
1203 HeapGraphPath* ret_path = new HeapGraphPath(*prev_path->path());
1204 ret_path->Set(0, ret_edge);
1205 retaining_paths->Add(ret_path);
1206 }
1207 }
1208 }
1209
1210
1211 HeapGraphPath::HeapGraphPath(const List<HeapGraphEdge*>& path)
1212 : path_(path.length() + 1) {
1213 Add(NULL);
1214 for (int i = path.length() - 1; i >= 0; --i) {
1215 Add(path[i]);
1216 }
1217 }
1218
1219
1220 void HeapGraphPath::Print() {
1221 path_[0]->From()->Print(1, 0);
1222 for (int i = 0; i < path_.length(); ++i) {
1223 OS::Print(" -> ");
1224 HeapGraphEdge* edge = path_[i];
1225 switch (edge->type()) {
1226 case HeapGraphEdge::kContextVariable:
1227 OS::Print("[#%s] ", edge->name());
1228 break;
1229 case HeapGraphEdge::kElement:
1230 case HeapGraphEdge::kHidden:
1231 OS::Print("[%d] ", edge->index());
1232 break;
1233 case HeapGraphEdge::kInternal:
1234 OS::Print("[$%s] ", edge->name());
1235 break;
1236 case HeapGraphEdge::kProperty:
1237 OS::Print("[%s] ", edge->name());
1238 break;
1239 case HeapGraphEdge::kShortcut:
1240 OS::Print("[^%s] ", edge->name());
1241 break;
1242 default:
1243 OS::Print("!!! unknown edge type: %d ", edge->type());
1244 }
1245 edge->to()->Print(1, 0);
1246 }
1247 OS::Print("\n");
1248 }
1249
1250
1251 // It is very important to keep objects that form a heap snapshot 1145 // It is very important to keep objects that form a heap snapshot
1252 // as small as possible. 1146 // as small as possible.
1253 namespace { // Avoid littering the global namespace. 1147 namespace { // Avoid littering the global namespace.
1254 1148
1255 template <size_t ptr_size> struct SnapshotSizeConstants; 1149 template <size_t ptr_size> struct SnapshotSizeConstants;
1256 1150
1257 template <> struct SnapshotSizeConstants<4> { 1151 template <> struct SnapshotSizeConstants<4> {
1258 static const int kExpectedHeapGraphEdgeSize = 12; 1152 static const int kExpectedHeapGraphEdgeSize = 12;
1259 static const int kExpectedHeapEntrySize = 36; 1153 static const int kExpectedHeapEntrySize = 36;
1260 }; 1154 };
(...skipping 10 matching lines...) Expand all
1271 const char* title, 1165 const char* title,
1272 unsigned uid) 1166 unsigned uid)
1273 : collection_(collection), 1167 : collection_(collection),
1274 type_(type), 1168 type_(type),
1275 title_(title), 1169 title_(title),
1276 uid_(uid), 1170 uid_(uid),
1277 root_entry_(NULL), 1171 root_entry_(NULL),
1278 gc_roots_entry_(NULL), 1172 gc_roots_entry_(NULL),
1279 natives_root_entry_(NULL), 1173 natives_root_entry_(NULL),
1280 raw_entries_(NULL), 1174 raw_entries_(NULL),
1281 entries_sorted_(false), 1175 entries_sorted_(false) {
1282 retaining_paths_(HeapEntry::Match) {
1283 STATIC_ASSERT( 1176 STATIC_ASSERT(
1284 sizeof(HeapGraphEdge) == 1177 sizeof(HeapGraphEdge) ==
1285 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOL INT 1178 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOL INT
1286 STATIC_ASSERT( 1179 STATIC_ASSERT(
1287 sizeof(HeapEntry) == 1180 sizeof(HeapEntry) ==
1288 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT 1181 SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT
1289 } 1182 }
1290 1183
1291
1292 static void DeleteHeapGraphPath(HeapGraphPath** path_ptr) {
1293 delete *path_ptr;
1294 }
1295
1296 HeapSnapshot::~HeapSnapshot() { 1184 HeapSnapshot::~HeapSnapshot() {
1297 DeleteArray(raw_entries_); 1185 DeleteArray(raw_entries_);
1298 for (HashMap::Entry* p = retaining_paths_.Start();
1299 p != NULL;
1300 p = retaining_paths_.Next(p)) {
1301 List<HeapGraphPath*>* list =
1302 reinterpret_cast<List<HeapGraphPath*>*>(p->value);
1303 list->Iterate(DeleteHeapGraphPath);
1304 delete list;
1305 }
1306 } 1186 }
1307 1187
1308 1188
1309 void HeapSnapshot::Delete() { 1189 void HeapSnapshot::Delete() {
1310 collection_->RemoveSnapshot(this); 1190 collection_->RemoveSnapshot(this);
1311 delete this; 1191 delete this;
1312 } 1192 }
1313 1193
1314 1194
1315 void HeapSnapshot::AllocateEntries(int entries_count, 1195 void HeapSnapshot::AllocateEntries(int entries_count,
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1397 reinterpret_cast<char*>(last_entry) + last_entry->EntrySize())); 1277 reinterpret_cast<char*>(last_entry) + last_entry->EntrySize()));
1398 } else { 1278 } else {
1399 entries_.Add(reinterpret_cast<HeapEntry*>(raw_entries_)); 1279 entries_.Add(reinterpret_cast<HeapEntry*>(raw_entries_));
1400 } 1280 }
1401 ASSERT(reinterpret_cast<char*>(entries_.last()) < 1281 ASSERT(reinterpret_cast<char*>(entries_.last()) <
1402 (raw_entries_ + raw_entries_size_)); 1282 (raw_entries_ + raw_entries_size_));
1403 return entries_.last(); 1283 return entries_.last();
1404 } 1284 }
1405 1285
1406 1286
1407 HeapSnapshotsDiff* HeapSnapshot::CompareWith(HeapSnapshot* snapshot) {
1408 return collection_->CompareSnapshots(this, snapshot);
1409 }
1410
1411
1412 HeapEntry* HeapSnapshot::GetEntryById(uint64_t id) { 1287 HeapEntry* HeapSnapshot::GetEntryById(uint64_t id) {
1413 // GetSortedEntriesList is used in diff algorithm and sorts
1414 // entries by their id.
1415 List<HeapEntry*>* entries_by_id = GetSortedEntriesList(); 1288 List<HeapEntry*>* entries_by_id = GetSortedEntriesList();
1416 1289
1417 // Perform a binary search by id. 1290 // Perform a binary search by id.
1418 int low = 0; 1291 int low = 0;
1419 int high = entries_by_id->length() - 1; 1292 int high = entries_by_id->length() - 1;
1420 while (low <= high) { 1293 while (low <= high) {
1421 int mid = 1294 int mid =
1422 (static_cast<unsigned int>(low) + static_cast<unsigned int>(high)) >> 1; 1295 (static_cast<unsigned int>(low) + static_cast<unsigned int>(high)) >> 1;
1423 uint64_t mid_id = entries_by_id->at(mid)->id(); 1296 uint64_t mid_id = entries_by_id->at(mid)->id();
1424 if (mid_id > id) 1297 if (mid_id > id)
1425 high = mid - 1; 1298 high = mid - 1;
1426 else if (mid_id < id) 1299 else if (mid_id < id)
1427 low = mid + 1; 1300 low = mid + 1;
1428 else 1301 else
1429 return entries_by_id->at(mid); 1302 return entries_by_id->at(mid);
1430 } 1303 }
1431 return NULL; 1304 return NULL;
1432 } 1305 }
1433 1306
1434 1307
1435 List<HeapGraphPath*>* HeapSnapshot::GetRetainingPaths(HeapEntry* entry) {
1436 HashMap::Entry* p =
1437 retaining_paths_.Lookup(entry, HeapEntry::Hash(entry), true);
1438 if (p->value == NULL) {
1439 p->value = entry->CalculateRetainingPaths();
1440 }
1441 return reinterpret_cast<List<HeapGraphPath*>*>(p->value);
1442 }
1443
1444
1445 template<class T> 1308 template<class T>
1446 static int SortByIds(const T* entry1_ptr, 1309 static int SortByIds(const T* entry1_ptr,
1447 const T* entry2_ptr) { 1310 const T* entry2_ptr) {
1448 if ((*entry1_ptr)->id() == (*entry2_ptr)->id()) return 0; 1311 if ((*entry1_ptr)->id() == (*entry2_ptr)->id()) return 0;
1449 return (*entry1_ptr)->id() < (*entry2_ptr)->id() ? -1 : 1; 1312 return (*entry1_ptr)->id() < (*entry2_ptr)->id() ? -1 : 1;
1450 } 1313 }
1451 1314
1452 List<HeapEntry*>* HeapSnapshot::GetSortedEntriesList() { 1315 List<HeapEntry*>* HeapSnapshot::GetSortedEntriesList() {
1453 if (!entries_sorted_) { 1316 if (!entries_sorted_) {
1454 entries_.Sort(SortByIds); 1317 entries_.Sort(SortByIds);
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 1487
1625 1488
1626 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) { 1489 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) {
1627 snapshots_.RemoveElement(snapshot); 1490 snapshots_.RemoveElement(snapshot);
1628 unsigned uid = snapshot->uid(); 1491 unsigned uid = snapshot->uid();
1629 snapshots_uids_.Remove(reinterpret_cast<void*>(uid), 1492 snapshots_uids_.Remove(reinterpret_cast<void*>(uid),
1630 static_cast<uint32_t>(uid)); 1493 static_cast<uint32_t>(uid));
1631 } 1494 }
1632 1495
1633 1496
1634 HeapSnapshotsDiff* HeapSnapshotsCollection::CompareSnapshots(
1635 HeapSnapshot* snapshot1,
1636 HeapSnapshot* snapshot2) {
1637 return comparator_.Compare(snapshot1, snapshot2);
1638 }
1639
1640
1641 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder = 1497 HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder =
1642 reinterpret_cast<HeapEntry*>(1); 1498 reinterpret_cast<HeapEntry*>(1);
1643 1499
1644 HeapEntriesMap::HeapEntriesMap() 1500 HeapEntriesMap::HeapEntriesMap()
1645 : entries_(HeapThingsMatch), 1501 : entries_(HeapThingsMatch),
1646 entries_count_(0), 1502 entries_count_(0),
1647 total_children_count_(0), 1503 total_children_count_(0),
1648 total_retainers_count_(0) { 1504 total_retainers_count_(0) {
1649 } 1505 }
1650 1506
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 dominator != entry; 2653 dominator != entry;
2798 entry = dominator, dominator = entry->dominator()) { 2654 entry = dominator, dominator = entry->dominator()) {
2799 dominator->add_retained_size(entry_size); 2655 dominator->add_retained_size(entry_size);
2800 } 2656 }
2801 if (!ProgressReport()) return false; 2657 if (!ProgressReport()) return false;
2802 } 2658 }
2803 return true; 2659 return true;
2804 } 2660 }
2805 2661
2806 2662
2807 void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) {
2808 raw_additions_root_ =
2809 NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0));
2810 additions_root()->Init(
2811 snapshot2_, HeapEntry::kHidden, "", 0, 0, additions_count, 0);
2812 raw_deletions_root_ =
2813 NewArray<char>(HeapEntry::EntriesSize(1, deletions_count, 0));
2814 deletions_root()->Init(
2815 snapshot1_, HeapEntry::kHidden, "", 0, 0, deletions_count, 0);
2816 }
2817
2818
2819 static void DeleteHeapSnapshotsDiff(HeapSnapshotsDiff** diff_ptr) {
2820 delete *diff_ptr;
2821 }
2822
2823 HeapSnapshotsComparator::~HeapSnapshotsComparator() {
2824 diffs_.Iterate(DeleteHeapSnapshotsDiff);
2825 }
2826
2827
2828 HeapSnapshotsDiff* HeapSnapshotsComparator::Compare(HeapSnapshot* snapshot1,
2829 HeapSnapshot* snapshot2) {
2830 snapshot1->ClearPaint();
2831 snapshot1->root()->PaintAllReachable();
2832 snapshot2->ClearPaint();
2833 snapshot2->root()->PaintAllReachable();
2834
2835 List<HeapEntry*>* entries1 = snapshot1->GetSortedEntriesList();
2836 List<HeapEntry*>* entries2 = snapshot2->GetSortedEntriesList();
2837 int i = 0, j = 0;
2838 List<HeapEntry*> added_entries, deleted_entries;
2839 while (i < entries1->length() && j < entries2->length()) {
2840 uint64_t id1 = entries1->at(i)->id();
2841 uint64_t id2 = entries2->at(j)->id();
2842 if (id1 == id2) {
2843 HeapEntry* entry1 = entries1->at(i++);
2844 HeapEntry* entry2 = entries2->at(j++);
2845 if (entry1->painted_reachable() != entry2->painted_reachable()) {
2846 if (entry1->painted_reachable())
2847 deleted_entries.Add(entry1);
2848 else
2849 added_entries.Add(entry2);
2850 }
2851 } else if (id1 < id2) {
2852 HeapEntry* entry = entries1->at(i++);
2853 deleted_entries.Add(entry);
2854 } else {
2855 HeapEntry* entry = entries2->at(j++);
2856 added_entries.Add(entry);
2857 }
2858 }
2859 while (i < entries1->length()) {
2860 HeapEntry* entry = entries1->at(i++);
2861 deleted_entries.Add(entry);
2862 }
2863 while (j < entries2->length()) {
2864 HeapEntry* entry = entries2->at(j++);
2865 added_entries.Add(entry);
2866 }
2867
2868 HeapSnapshotsDiff* diff = new HeapSnapshotsDiff(snapshot1, snapshot2);
2869 diffs_.Add(diff);
2870 diff->CreateRoots(added_entries.length(), deleted_entries.length());
2871
2872 for (int i = 0; i < deleted_entries.length(); ++i) {
2873 HeapEntry* entry = deleted_entries[i];
2874 diff->AddDeletedEntry(i, i + 1, entry);
2875 }
2876 for (int i = 0; i < added_entries.length(); ++i) {
2877 HeapEntry* entry = added_entries[i];
2878 diff->AddAddedEntry(i, i + 1, entry);
2879 }
2880 return diff;
2881 }
2882
2883
2884 class OutputStreamWriter { 2663 class OutputStreamWriter {
2885 public: 2664 public:
2886 explicit OutputStreamWriter(v8::OutputStream* stream) 2665 explicit OutputStreamWriter(v8::OutputStream* stream)
2887 : stream_(stream), 2666 : stream_(stream),
2888 chunk_size_(stream->GetChunkSize()), 2667 chunk_size_(stream->GetChunkSize()),
2889 chunk_(chunk_size_), 2668 chunk_(chunk_size_),
2890 chunk_pos_(0), 2669 chunk_pos_(0),
2891 aborted_(false) { 2670 aborted_(false) {
2892 ASSERT(chunk_size_ > 0); 2671 ASSERT(chunk_size_ > 0);
2893 } 2672 }
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
3248 3027
3249 3028
3250 String* GetConstructorNameForHeapProfile(JSObject* object) { 3029 String* GetConstructorNameForHeapProfile(JSObject* object) {
3251 if (object->IsJSFunction()) return HEAP->closure_symbol(); 3030 if (object->IsJSFunction()) return HEAP->closure_symbol();
3252 return object->constructor_name(); 3031 return object->constructor_name();
3253 } 3032 }
3254 3033
3255 } } // namespace v8::internal 3034 } } // namespace v8::internal
3256 3035
3257 #endif // ENABLE_LOGGING_AND_PROFILING 3036 #endif // ENABLE_LOGGING_AND_PROFILING
OLDNEW
« no previous file with comments | « src/profile-generator.h ('k') | src/regexp-macro-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698