OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1078 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1089 case kArray: return "/array/"; | 1089 case kArray: return "/array/"; |
1090 case kRegExp: return "/regexp/"; | 1090 case kRegExp: return "/regexp/"; |
1091 case kHeapNumber: return "/number/"; | 1091 case kHeapNumber: return "/number/"; |
1092 case kNative: return "/native/"; | 1092 case kNative: return "/native/"; |
1093 case kSynthetic: return "/synthetic/"; | 1093 case kSynthetic: return "/synthetic/"; |
1094 default: return "???"; | 1094 default: return "???"; |
1095 } | 1095 } |
1096 } | 1096 } |
1097 | 1097 |
1098 | 1098 |
1099 int HeapEntry::EntriesSize(int entries_count, | 1099 uint64_t HeapEntry::EntriesSize(int entries_count, |
1100 int children_count, | 1100 int children_count, |
1101 int retainers_count) { | 1101 int retainers_count) { |
1102 return sizeof(HeapEntry) * entries_count // NOLINT | 1102 return (uint64_t)sizeof(HeapEntry) * entries_count // NOLINT |
mnaganov (inactive)
2012/03/08 15:25:10
Please, use static_cast.
alexeif
2012/03/10 10:32:02
There's no need to use casts here. sizeof has the
| |
1103 + sizeof(HeapGraphEdge) * children_count // NOLINT | 1103 + (uint64_t)sizeof(HeapGraphEdge) * children_count // NOLINT |
1104 + sizeof(HeapGraphEdge*) * retainers_count; // NOLINT | 1104 + (uint64_t)sizeof(HeapGraphEdge*) * retainers_count; // NOLINT |
1105 } | 1105 } |
1106 | 1106 |
1107 | 1107 |
1108 // It is very important to keep objects that form a heap snapshot | 1108 // It is very important to keep objects that form a heap snapshot |
1109 // as small as possible. | 1109 // as small as possible. |
1110 namespace { // Avoid littering the global namespace. | 1110 namespace { // Avoid littering the global namespace. |
1111 | 1111 |
1112 template <size_t ptr_size> struct SnapshotSizeConstants; | 1112 template <size_t ptr_size> struct SnapshotSizeConstants; |
1113 | 1113 |
1114 template <> struct SnapshotSizeConstants<4> { | 1114 template <> struct SnapshotSizeConstants<4> { |
1115 static const int kExpectedHeapGraphEdgeSize = 12; | 1115 static const int kExpectedHeapGraphEdgeSize = 12; |
1116 static const int kExpectedHeapEntrySize = 36; | 1116 static const int kExpectedHeapEntrySize = 36; |
1117 static const int kMaxSerializableSnapshotRawSize = 256 * MB; | 1117 static const size_t kMaxSerializableSnapshotRawSize = 256 * MB; |
1118 }; | 1118 }; |
1119 | 1119 |
1120 template <> struct SnapshotSizeConstants<8> { | 1120 template <> struct SnapshotSizeConstants<8> { |
1121 static const int kExpectedHeapGraphEdgeSize = 24; | 1121 static const int kExpectedHeapGraphEdgeSize = 24; |
1122 static const int kExpectedHeapEntrySize = 48; | 1122 static const int kExpectedHeapEntrySize = 48; |
1123 static const int kMaxSerializableSnapshotRawSize = 768 * MB; | 1123 static const size_t kMaxSerializableSnapshotRawSize = 6000ul * MB; |
1124 }; | 1124 }; |
1125 | 1125 |
1126 } // namespace | 1126 } // namespace |
1127 | 1127 |
1128 class RawEntriesStorage { | |
1129 public: | |
1130 explicit RawEntriesStorage(size_t size) : size_(size) { } | |
1131 ~RawEntriesStorage() { | |
1132 for (int i = 0; i < raw_data_.length(); ++i) | |
1133 DeleteArray(raw_data_[i]); | |
1134 } | |
1135 char* FirstAddress(size_t minimum_size) { | |
mnaganov (inactive)
2012/03/08 15:25:10
I think, you should use Address type.
| |
1136 ASSERT(raw_data_.length() == 0); | |
1137 return AllocateNextChunk(minimum_size); | |
1138 } | |
1139 char* NextAddress(char* next_entry_candidate, size_t minimum_size) { | |
1140 ASSERT(raw_data_.length()); | |
mnaganov (inactive)
2012/03/08 15:25:10
!= 0
| |
1141 if (next_entry_candidate - last_chunk_ + minimum_size > last_chunk_size_) { | |
mnaganov (inactive)
2012/03/08 15:25:10
Note: Please verify that expressions like these co
| |
1142 return AllocateNextChunk(minimum_size); | |
1143 } | |
1144 return next_entry_candidate; | |
1145 } | |
1146 | |
1147 private: | |
1148 char* AllocateNextChunk(size_t minimum_size) { | |
1149 last_chunk_size_ = | |
1150 default_chunk_size_ > minimum_size ? default_chunk_size_ : minimum_size; | |
1151 last_chunk_ = NewArray<char>(last_chunk_size_); | |
alexeif
2012/03/10 10:32:02
Can't we just change the NewArray argument to size
| |
1152 raw_data_.Add(last_chunk_); | |
1153 return last_chunk_; | |
1154 } | |
1155 size_t size_; | |
1156 size_t last_chunk_size_; | |
1157 char* last_chunk_; | |
1158 List<char*> raw_data_; | |
1159 static const size_t default_chunk_size_ = 256 * MB; | |
1160 }; | |
1161 | |
1128 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, | 1162 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, |
1129 HeapSnapshot::Type type, | 1163 HeapSnapshot::Type type, |
1130 const char* title, | 1164 const char* title, |
1131 unsigned uid) | 1165 unsigned uid) |
1132 : collection_(collection), | 1166 : collection_(collection), |
1133 type_(type), | 1167 type_(type), |
1134 title_(title), | 1168 title_(title), |
1135 uid_(uid), | 1169 uid_(uid), |
1136 root_entry_(NULL), | 1170 root_entry_(NULL), |
1137 gc_roots_entry_(NULL), | 1171 gc_roots_entry_(NULL), |
1138 natives_root_entry_(NULL), | 1172 natives_root_entry_(NULL), |
1139 raw_entries_(NULL), | 1173 raw_entries_(NULL), |
1140 entries_sorted_(false) { | 1174 entries_sorted_(false) { |
1141 STATIC_ASSERT( | 1175 STATIC_ASSERT( |
1142 sizeof(HeapGraphEdge) == | 1176 sizeof(HeapGraphEdge) == |
1143 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); | 1177 SnapshotSizeConstants<kPointerSize>::kExpectedHeapGraphEdgeSize); |
1144 STATIC_ASSERT( | 1178 STATIC_ASSERT( |
1145 sizeof(HeapEntry) == | 1179 sizeof(HeapEntry) == |
1146 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); | 1180 SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize); |
1147 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { | 1181 for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) { |
1148 gc_subroot_entries_[i] = NULL; | 1182 gc_subroot_entries_[i] = NULL; |
1149 } | 1183 } |
1150 } | 1184 } |
1151 | 1185 |
1152 | 1186 |
1153 HeapSnapshot::~HeapSnapshot() { | 1187 HeapSnapshot::~HeapSnapshot() { |
1154 DeleteArray(raw_entries_); | 1188 delete raw_entries_; |
1155 } | 1189 } |
1156 | 1190 |
1157 | 1191 |
1158 void HeapSnapshot::Delete() { | 1192 void HeapSnapshot::Delete() { |
1159 collection_->RemoveSnapshot(this); | 1193 collection_->RemoveSnapshot(this); |
1160 delete this; | 1194 delete this; |
1161 } | 1195 } |
1162 | 1196 |
1163 | 1197 |
1164 void HeapSnapshot::AllocateEntries(int entries_count, | 1198 void HeapSnapshot::AllocateEntries(int entries_count, |
1165 int children_count, | 1199 int children_count, |
1166 int retainers_count) { | 1200 int retainers_count) { |
1167 ASSERT(raw_entries_ == NULL); | 1201 ASSERT(raw_entries_ == NULL); |
1168 raw_entries_size_ = | 1202 raw_entries_size_ = |
1169 HeapEntry::EntriesSize(entries_count, children_count, retainers_count); | 1203 HeapEntry::EntriesSize(entries_count, children_count, retainers_count); |
1170 raw_entries_ = NewArray<char>(raw_entries_size_); | 1204 raw_entries_ = new RawEntriesStorage(raw_entries_size_); |
1171 } | 1205 } |
1172 | 1206 |
1173 | 1207 |
1174 static void HeapEntryClearPaint(HeapEntry** entry_ptr) { | 1208 static void HeapEntryClearPaint(HeapEntry** entry_ptr) { |
1175 (*entry_ptr)->clear_paint(); | 1209 (*entry_ptr)->clear_paint(); |
1176 } | 1210 } |
1177 | 1211 |
1178 | 1212 |
1179 void HeapSnapshot::ClearPaint() { | 1213 void HeapSnapshot::ClearPaint() { |
1180 entries_.Iterate(HeapEntryClearPaint); | 1214 entries_.Iterate(HeapEntryClearPaint); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1218 retainers_count)); | 1252 retainers_count)); |
1219 } | 1253 } |
1220 | 1254 |
1221 | 1255 |
1222 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, | 1256 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, |
1223 const char* name, | 1257 const char* name, |
1224 uint64_t id, | 1258 uint64_t id, |
1225 int size, | 1259 int size, |
1226 int children_count, | 1260 int children_count, |
1227 int retainers_count) { | 1261 int retainers_count) { |
1228 HeapEntry* entry = GetNextEntryToInit(); | 1262 HeapEntry* entry = GetNextEntryToInit( |
1263 HeapEntry::EntriesSize(1, children_count, retainers_count)); | |
1229 entry->Init(this, type, name, id, size, children_count, retainers_count); | 1264 entry->Init(this, type, name, id, size, children_count, retainers_count); |
1230 return entry; | 1265 return entry; |
1231 } | 1266 } |
1232 | 1267 |
1233 | 1268 |
1234 void HeapSnapshot::SetDominatorsToSelf() { | 1269 void HeapSnapshot::SetDominatorsToSelf() { |
1235 for (int i = 0; i < entries_.length(); ++i) { | 1270 for (int i = 0; i < entries_.length(); ++i) { |
1236 HeapEntry* entry = entries_[i]; | 1271 HeapEntry* entry = entries_[i]; |
1237 if (entry->dominator() == NULL) entry->set_dominator(entry); | 1272 if (entry->dominator() == NULL) entry->set_dominator(entry); |
1238 } | 1273 } |
1239 } | 1274 } |
1240 | 1275 |
1241 | 1276 |
1242 HeapEntry* HeapSnapshot::GetNextEntryToInit() { | 1277 HeapEntry* HeapSnapshot::GetNextEntryToInit(size_t size) { |
1243 if (entries_.length() > 0) { | 1278 if (entries_.length() > 0) { |
1244 HeapEntry* last_entry = entries_.last(); | 1279 HeapEntry* last_entry = entries_.last(); |
1280 HeapEntry* next_entry = reinterpret_cast<HeapEntry*>( | |
1281 raw_entries_->NextAddress(reinterpret_cast<char*>(last_entry) | |
1282 + last_entry->EntrySize(), size)); | |
1283 entries_.Add(next_entry); | |
1284 } else { | |
1245 entries_.Add(reinterpret_cast<HeapEntry*>( | 1285 entries_.Add(reinterpret_cast<HeapEntry*>( |
1246 reinterpret_cast<char*>(last_entry) + last_entry->EntrySize())); | 1286 raw_entries_->FirstAddress(size))); |
1247 } else { | |
1248 entries_.Add(reinterpret_cast<HeapEntry*>(raw_entries_)); | |
1249 } | 1287 } |
1250 ASSERT(reinterpret_cast<char*>(entries_.last()) < | |
1251 (raw_entries_ + raw_entries_size_)); | |
1252 return entries_.last(); | 1288 return entries_.last(); |
1253 } | 1289 } |
1254 | 1290 |
1255 | 1291 |
1256 HeapEntry* HeapSnapshot::GetEntryById(uint64_t id) { | 1292 HeapEntry* HeapSnapshot::GetEntryById(uint64_t id) { |
1257 List<HeapEntry*>* entries_by_id = GetSortedEntriesList(); | 1293 List<HeapEntry*>* entries_by_id = GetSortedEntriesList(); |
1258 | 1294 |
1259 // Perform a binary search by id. | 1295 // Perform a binary search by id. |
1260 int low = 0; | 1296 int low = 0; |
1261 int high = entries_by_id->length() - 1; | 1297 int high = entries_by_id->length() - 1; |
(...skipping 2167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3429 | 3465 |
3430 HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() { | 3466 HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() { |
3431 HeapSnapshot* result = new HeapSnapshot(snapshot_->collection(), | 3467 HeapSnapshot* result = new HeapSnapshot(snapshot_->collection(), |
3432 HeapSnapshot::kFull, | 3468 HeapSnapshot::kFull, |
3433 snapshot_->title(), | 3469 snapshot_->title(), |
3434 snapshot_->uid()); | 3470 snapshot_->uid()); |
3435 result->AllocateEntries(2, 1, 0); | 3471 result->AllocateEntries(2, 1, 0); |
3436 HeapEntry* root = result->AddRootEntry(1); | 3472 HeapEntry* root = result->AddRootEntry(1); |
3437 const char* text = snapshot_->collection()->names()->GetFormatted( | 3473 const char* text = snapshot_->collection()->names()->GetFormatted( |
3438 "The snapshot is too big. " | 3474 "The snapshot is too big. " |
3439 "Maximum snapshot size is %d MB. " | 3475 "Maximum snapshot size is %d MB. " |
mnaganov (inactive)
2012/03/08 15:25:10
Is %d the correct type?
| |
3440 "Actual snapshot size is %d MB.", | 3476 "Actual snapshot size is %u MB.", |
alexeif
2012/03/10 10:32:02
if raw_entries_size() is uint64_t then it should b
| |
3441 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, | 3477 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, |
3442 (snapshot_->raw_entries_size() + MB - 1) / MB); | 3478 (snapshot_->raw_entries_size() + MB - 1) / MB); |
3443 HeapEntry* message = result->AddEntry( | 3479 HeapEntry* message = result->AddEntry( |
3444 HeapEntry::kString, text, 0, 4, 0, 0); | 3480 HeapEntry::kString, text, 0, 4, 0, 0); |
3445 root->SetUnidirElementReference(0, 1, message); | 3481 root->SetUnidirElementReference(0, 1, message); |
3446 result->SetDominatorsToSelf(); | 3482 result->SetDominatorsToSelf(); |
3447 return result; | 3483 return result; |
3448 } | 3484 } |
3449 | 3485 |
3450 | 3486 |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3734 | 3770 |
3735 | 3771 |
3736 void HeapSnapshotJSONSerializer::SortHashMap( | 3772 void HeapSnapshotJSONSerializer::SortHashMap( |
3737 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3773 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3738 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3774 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3739 sorted_entries->Add(p); | 3775 sorted_entries->Add(p); |
3740 sorted_entries->Sort(SortUsingEntryValue); | 3776 sorted_entries->Sort(SortUsingEntryValue); |
3741 } | 3777 } |
3742 | 3778 |
3743 } } // namespace v8::internal | 3779 } } // namespace v8::internal |
OLD | NEW |