OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 | 1201 |
1202 // It is very important to keep objects that form a heap snapshot | 1202 // It is very important to keep objects that form a heap snapshot |
1203 // as small as possible. | 1203 // as small as possible. |
1204 namespace { // Avoid littering the global namespace. | 1204 namespace { // Avoid littering the global namespace. |
1205 | 1205 |
1206 template <size_t ptr_size> struct SnapshotSizeConstants; | 1206 template <size_t ptr_size> struct SnapshotSizeConstants; |
1207 | 1207 |
1208 template <> struct SnapshotSizeConstants<4> { | 1208 template <> struct SnapshotSizeConstants<4> { |
1209 static const int kExpectedHeapGraphEdgeSize = 12; | 1209 static const int kExpectedHeapGraphEdgeSize = 12; |
1210 static const int kExpectedHeapEntrySize = 36; | 1210 static const int kExpectedHeapEntrySize = 36; |
| 1211 static const int kMaxSerializableSnapshotRawSize = 256 * MB; |
1211 }; | 1212 }; |
1212 | 1213 |
1213 template <> struct SnapshotSizeConstants<8> { | 1214 template <> struct SnapshotSizeConstants<8> { |
1214 static const int kExpectedHeapGraphEdgeSize = 24; | 1215 static const int kExpectedHeapGraphEdgeSize = 24; |
1215 static const int kExpectedHeapEntrySize = 48; | 1216 static const int kExpectedHeapEntrySize = 48; |
| 1217 static const int kMaxSerializableSnapshotRawSize = 768 * MB; |
1216 }; | 1218 }; |
1217 | 1219 |
1218 } // namespace | 1220 } // namespace |
1219 | 1221 |
1220 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, | 1222 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, |
1221 HeapSnapshot::Type type, | 1223 HeapSnapshot::Type type, |
1222 const char* title, | 1224 const char* title, |
1223 unsigned uid) | 1225 unsigned uid) |
1224 : collection_(collection), | 1226 : collection_(collection), |
1225 type_(type), | 1227 type_(type), |
(...skipping 2178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3404 v8::OutputStream::kAbort) aborted_ = true; | 3406 v8::OutputStream::kAbort) aborted_ = true; |
3405 } | 3407 } |
3406 | 3408 |
3407 v8::OutputStream* stream_; | 3409 v8::OutputStream* stream_; |
3408 int chunk_size_; | 3410 int chunk_size_; |
3409 ScopedVector<char> chunk_; | 3411 ScopedVector<char> chunk_; |
3410 int chunk_pos_; | 3412 int chunk_pos_; |
3411 bool aborted_; | 3413 bool aborted_; |
3412 }; | 3414 }; |
3413 | 3415 |
3414 const int HeapSnapshotJSONSerializer::kMaxSerializableSnapshotRawSize = | |
3415 256 * MB; | |
3416 | |
3417 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { | 3416 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { |
3418 ASSERT(writer_ == NULL); | 3417 ASSERT(writer_ == NULL); |
3419 writer_ = new OutputStreamWriter(stream); | 3418 writer_ = new OutputStreamWriter(stream); |
3420 | 3419 |
3421 HeapSnapshot* original_snapshot = NULL; | 3420 HeapSnapshot* original_snapshot = NULL; |
3422 if (snapshot_->raw_entries_size() >= kMaxSerializableSnapshotRawSize) { | 3421 if (snapshot_->raw_entries_size() >= |
| 3422 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize) { |
3423 // The snapshot is too big. Serialize a fake snapshot. | 3423 // The snapshot is too big. Serialize a fake snapshot. |
3424 original_snapshot = snapshot_; | 3424 original_snapshot = snapshot_; |
3425 snapshot_ = CreateFakeSnapshot(); | 3425 snapshot_ = CreateFakeSnapshot(); |
3426 } | 3426 } |
3427 // Since nodes graph is cyclic, we need the first pass to enumerate | 3427 // Since nodes graph is cyclic, we need the first pass to enumerate |
3428 // them. Strings can be serialized in one pass. | 3428 // them. Strings can be serialized in one pass. |
3429 EnumerateNodes(); | 3429 EnumerateNodes(); |
3430 SerializeImpl(); | 3430 SerializeImpl(); |
3431 | 3431 |
3432 delete writer_; | 3432 delete writer_; |
3433 writer_ = NULL; | 3433 writer_ = NULL; |
3434 | 3434 |
3435 if (original_snapshot != NULL) { | 3435 if (original_snapshot != NULL) { |
3436 delete snapshot_; | 3436 delete snapshot_; |
3437 snapshot_ = original_snapshot; | 3437 snapshot_ = original_snapshot; |
3438 } | 3438 } |
3439 } | 3439 } |
3440 | 3440 |
3441 | 3441 |
3442 HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() { | 3442 HeapSnapshot* HeapSnapshotJSONSerializer::CreateFakeSnapshot() { |
3443 HeapSnapshot* result = new HeapSnapshot(snapshot_->collection(), | 3443 HeapSnapshot* result = new HeapSnapshot(snapshot_->collection(), |
3444 HeapSnapshot::kFull, | 3444 HeapSnapshot::kFull, |
3445 snapshot_->title(), | 3445 snapshot_->title(), |
3446 snapshot_->uid()); | 3446 snapshot_->uid()); |
3447 result->AllocateEntries(2, 1, 0); | 3447 result->AllocateEntries(2, 1, 0); |
3448 HeapEntry* root = result->AddRootEntry(1); | 3448 HeapEntry* root = result->AddRootEntry(1); |
| 3449 const char* text = snapshot_->collection()->names()->GetFormatted( |
| 3450 "The snapshot is too big. " |
| 3451 "Maximum snapshot size is %d MB. " |
| 3452 "Actual snapshot size is %d MB.", |
| 3453 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, |
| 3454 (snapshot_->raw_entries_size() + MB - 1) / MB); |
3449 HeapEntry* message = result->AddEntry( | 3455 HeapEntry* message = result->AddEntry( |
3450 HeapEntry::kString, "The snapshot is too big", 0, 4, 0, 0); | 3456 HeapEntry::kString, text, 0, 4, 0, 0); |
3451 root->SetUnidirElementReference(0, 1, message); | 3457 root->SetUnidirElementReference(0, 1, message); |
3452 result->SetDominatorsToSelf(); | 3458 result->SetDominatorsToSelf(); |
3453 return result; | 3459 return result; |
3454 } | 3460 } |
3455 | 3461 |
3456 | 3462 |
3457 void HeapSnapshotJSONSerializer::SerializeImpl() { | 3463 void HeapSnapshotJSONSerializer::SerializeImpl() { |
3458 writer_->AddCharacter('{'); | 3464 writer_->AddCharacter('{'); |
3459 writer_->AddString("\"snapshot\":{"); | 3465 writer_->AddString("\"snapshot\":{"); |
3460 SerializeSnapshot(); | 3466 SerializeSnapshot(); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3727 | 3733 |
3728 | 3734 |
3729 void HeapSnapshotJSONSerializer::SortHashMap( | 3735 void HeapSnapshotJSONSerializer::SortHashMap( |
3730 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3736 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3731 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3737 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3732 sorted_entries->Add(p); | 3738 sorted_entries->Add(p); |
3733 sorted_entries->Sort(SortUsingEntryValue); | 3739 sorted_entries->Sort(SortUsingEntryValue); |
3734 } | 3740 } |
3735 | 3741 |
3736 } } // namespace v8::internal | 3742 } } // namespace v8::internal |
OLD | NEW |