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 3230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3241 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, | 3241 SnapshotSizeConstants<kPointerSize>::kMaxSerializableSnapshotRawSize / MB, |
3242 (snapshot_->RawSnapshotSize() + MB - 1) / MB); | 3242 (snapshot_->RawSnapshotSize() + MB - 1) / MB); |
3243 HeapEntry* message = result->AddEntry(HeapEntry::kString, text, 0, 4); | 3243 HeapEntry* message = result->AddEntry(HeapEntry::kString, text, 0, 4); |
3244 result->root()->SetIndexedReference(HeapGraphEdge::kElement, 1, message); | 3244 result->root()->SetIndexedReference(HeapGraphEdge::kElement, 1, message); |
3245 result->FillChildren(); | 3245 result->FillChildren(); |
3246 return result; | 3246 return result; |
3247 } | 3247 } |
3248 | 3248 |
3249 | 3249 |
3250 void HeapSnapshotJSONSerializer::SerializeImpl() { | 3250 void HeapSnapshotJSONSerializer::SerializeImpl() { |
3251 List<HeapEntry>& nodes = snapshot_->entries(); | |
3252 ASSERT(0 == snapshot_->root()->index()); | 3251 ASSERT(0 == snapshot_->root()->index()); |
3253 writer_->AddCharacter('{'); | 3252 writer_->AddCharacter('{'); |
3254 writer_->AddString("\"snapshot\":{"); | 3253 writer_->AddString("\"snapshot\":{"); |
3255 SerializeSnapshot(); | 3254 SerializeSnapshot(); |
3256 if (writer_->aborted()) return; | 3255 if (writer_->aborted()) return; |
3257 writer_->AddString("},\n"); | 3256 writer_->AddString("},\n"); |
3258 writer_->AddString("\"nodes\":["); | 3257 writer_->AddString("\"nodes\":["); |
3259 SerializeNodes(nodes); | 3258 SerializeNodes(); |
3260 if (writer_->aborted()) return; | 3259 if (writer_->aborted()) return; |
3261 writer_->AddString("],\n"); | 3260 writer_->AddString("],\n"); |
3262 writer_->AddString("\"edges\":["); | 3261 writer_->AddString("\"edges\":["); |
3263 SerializeEdges(nodes); | 3262 SerializeEdges(); |
3264 if (writer_->aborted()) return; | 3263 if (writer_->aborted()) return; |
3265 writer_->AddString("],\n"); | 3264 writer_->AddString("],\n"); |
3266 writer_->AddString("\"strings\":["); | 3265 writer_->AddString("\"strings\":["); |
3267 SerializeStrings(); | 3266 SerializeStrings(); |
3268 if (writer_->aborted()) return; | 3267 if (writer_->aborted()) return; |
3269 writer_->AddCharacter(']'); | 3268 writer_->AddCharacter(']'); |
3270 writer_->AddCharacter('}'); | 3269 writer_->AddCharacter('}'); |
3271 writer_->Finalize(); | 3270 writer_->Finalize(); |
3272 } | 3271 } |
3273 | 3272 |
(...skipping 21 matching lines...) Expand all Loading... |
3295 int last_digit = value % 10; | 3294 int last_digit = value % 10; |
3296 buffer[--buffer_pos] = '0' + last_digit; | 3295 buffer[--buffer_pos] = '0' + last_digit; |
3297 value /= 10; | 3296 value /= 10; |
3298 } while (value); | 3297 } while (value); |
3299 return result; | 3298 return result; |
3300 } | 3299 } |
3301 | 3300 |
3302 | 3301 |
3303 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, | 3302 void HeapSnapshotJSONSerializer::SerializeEdge(HeapGraphEdge* edge, |
3304 bool first_edge) { | 3303 bool first_edge) { |
3305 // The buffer needs space for 3 ints, 3 commas and \0 | 3304 // The buffer needs space for 3 unsigned ints, 3 commas and \0 |
3306 static const int kBufferSize = | 3305 static const int kBufferSize = |
3307 MaxDecimalDigitsIn<sizeof(int)>::kSigned * 3 + 3 + 1; // NOLINT | 3306 MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned * 3 + 3 + 1; // NOLINT |
3308 EmbeddedVector<char, kBufferSize> buffer; | 3307 EmbeddedVector<char, kBufferSize> buffer; |
3309 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement | 3308 int edge_name_or_index = edge->type() == HeapGraphEdge::kElement |
3310 || edge->type() == HeapGraphEdge::kHidden | 3309 || edge->type() == HeapGraphEdge::kHidden |
3311 || edge->type() == HeapGraphEdge::kWeak | 3310 || edge->type() == HeapGraphEdge::kWeak |
3312 ? edge->index() : GetStringId(edge->name()); | 3311 ? edge->index() : GetStringId(edge->name()); |
3313 int buffer_pos = 0; | 3312 int buffer_pos = 0; |
3314 if (!first_edge) { | 3313 if (!first_edge) { |
3315 buffer[buffer_pos++] = ','; | 3314 buffer[buffer_pos++] = ','; |
3316 } | 3315 } |
3317 buffer_pos = utoa(edge->type(), buffer, buffer_pos); | 3316 buffer_pos = utoa(edge->type(), buffer, buffer_pos); |
3318 buffer[buffer_pos++] = ','; | 3317 buffer[buffer_pos++] = ','; |
3319 buffer_pos = utoa(edge_name_or_index, buffer, buffer_pos); | 3318 buffer_pos = utoa(edge_name_or_index, buffer, buffer_pos); |
3320 buffer[buffer_pos++] = ','; | 3319 buffer[buffer_pos++] = ','; |
3321 buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos); | 3320 buffer_pos = utoa(entry_index(edge->to()), buffer, buffer_pos); |
3322 buffer[buffer_pos++] = '\0'; | 3321 buffer[buffer_pos++] = '\0'; |
3323 writer_->AddString(buffer.start()); | 3322 writer_->AddString(buffer.start()); |
3324 } | 3323 } |
3325 | 3324 |
3326 | 3325 |
3327 void HeapSnapshotJSONSerializer::SerializeEdges(const List<HeapEntry>& nodes) { | 3326 void HeapSnapshotJSONSerializer::SerializeEdges() { |
3328 bool first_edge = true; | 3327 List<HeapGraphEdge*>& edges = snapshot_->children(); |
3329 for (int i = 0; i < nodes.length(); ++i) { | 3328 for (int i = 0; i < edges.length(); ++i) { |
3330 HeapEntry* entry = &nodes[i]; | 3329 ASSERT(i == 0 || |
3331 Vector<HeapGraphEdge*> children = entry->children(); | 3330 edges[i - 1]->from()->index() <= edges[i]->from()->index()); |
3332 for (int j = 0; j < children.length(); ++j) { | 3331 SerializeEdge(edges[i], i == 0); |
3333 SerializeEdge(children[j], first_edge); | 3332 if (writer_->aborted()) return; |
3334 first_edge = false; | |
3335 if (writer_->aborted()) return; | |
3336 } | |
3337 } | 3333 } |
3338 } | 3334 } |
3339 | 3335 |
3340 | 3336 |
3341 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry, | 3337 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { |
3342 int edges_index) { | 3338 // The buffer needs space for 5 unsigned ints, 5 commas, \n and \0 |
3343 // The buffer needs space for 5 uint32_t, 5 commas, \n and \0 | |
3344 static const int kBufferSize = | 3339 static const int kBufferSize = |
3345 5 * MaxDecimalDigitsIn<sizeof(uint32_t)>::kUnsigned // NOLINT | 3340 5 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT |
3346 + 5 + 1 + 1; | 3341 + 5 + 1 + 1; |
3347 EmbeddedVector<char, kBufferSize> buffer; | 3342 EmbeddedVector<char, kBufferSize> buffer; |
3348 int buffer_pos = 0; | 3343 int buffer_pos = 0; |
3349 if (entry_index(entry) != 0) { | 3344 if (entry_index(entry) != 0) { |
3350 buffer[buffer_pos++] = ','; | 3345 buffer[buffer_pos++] = ','; |
3351 } | 3346 } |
3352 buffer_pos = utoa(entry->type(), buffer, buffer_pos); | 3347 buffer_pos = utoa(entry->type(), buffer, buffer_pos); |
3353 buffer[buffer_pos++] = ','; | 3348 buffer[buffer_pos++] = ','; |
3354 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos); | 3349 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos); |
3355 buffer[buffer_pos++] = ','; | 3350 buffer[buffer_pos++] = ','; |
3356 buffer_pos = utoa(entry->id(), buffer, buffer_pos); | 3351 buffer_pos = utoa(entry->id(), buffer, buffer_pos); |
3357 buffer[buffer_pos++] = ','; | 3352 buffer[buffer_pos++] = ','; |
3358 buffer_pos = utoa(entry->self_size(), buffer, buffer_pos); | 3353 buffer_pos = utoa(entry->self_size(), buffer, buffer_pos); |
3359 buffer[buffer_pos++] = ','; | 3354 buffer[buffer_pos++] = ','; |
3360 buffer_pos = utoa(edges_index, buffer, buffer_pos); | 3355 buffer_pos = utoa(entry->children_count(), buffer, buffer_pos); |
3361 buffer[buffer_pos++] = '\n'; | 3356 buffer[buffer_pos++] = '\n'; |
3362 buffer[buffer_pos++] = '\0'; | 3357 buffer[buffer_pos++] = '\0'; |
3363 writer_->AddString(buffer.start()); | 3358 writer_->AddString(buffer.start()); |
3364 } | 3359 } |
3365 | 3360 |
3366 | 3361 |
3367 void HeapSnapshotJSONSerializer::SerializeNodes(const List<HeapEntry>& nodes) { | 3362 void HeapSnapshotJSONSerializer::SerializeNodes() { |
3368 int edges_index = 0; | 3363 List<HeapEntry>& entries = snapshot_->entries(); |
3369 for (int i = 0; i < nodes.length(); ++i) { | 3364 for (int i = 0; i < entries.length(); ++i) { |
3370 HeapEntry* entry = &nodes[i]; | 3365 SerializeNode(&entries[i]); |
3371 SerializeNode(entry, edges_index); | |
3372 edges_index += entry->children().length() * kEdgeFieldsCount; | |
3373 if (writer_->aborted()) return; | 3366 if (writer_->aborted()) return; |
3374 } | 3367 } |
3375 } | 3368 } |
3376 | 3369 |
3377 | 3370 |
3378 void HeapSnapshotJSONSerializer::SerializeSnapshot() { | 3371 void HeapSnapshotJSONSerializer::SerializeSnapshot() { |
3379 writer_->AddString("\"title\":\""); | 3372 writer_->AddString("\"title\":\""); |
3380 writer_->AddString(snapshot_->title()); | 3373 writer_->AddString(snapshot_->title()); |
3381 writer_->AddString("\""); | 3374 writer_->AddString("\""); |
3382 writer_->AddString(",\"uid\":"); | 3375 writer_->AddString(",\"uid\":"); |
3383 writer_->AddNumber(snapshot_->uid()); | 3376 writer_->AddNumber(snapshot_->uid()); |
3384 writer_->AddString(",\"meta\":"); | 3377 writer_->AddString(",\"meta\":"); |
3385 // The object describing node serialization layout. | 3378 // The object describing node serialization layout. |
3386 // We use a set of macros to improve readability. | 3379 // We use a set of macros to improve readability. |
3387 #define JSON_A(s) "[" s "]" | 3380 #define JSON_A(s) "[" s "]" |
3388 #define JSON_O(s) "{" s "}" | 3381 #define JSON_O(s) "{" s "}" |
3389 #define JSON_S(s) "\"" s "\"" | 3382 #define JSON_S(s) "\"" s "\"" |
3390 writer_->AddString(JSON_O( | 3383 writer_->AddString(JSON_O( |
3391 JSON_S("node_fields") ":" JSON_A( | 3384 JSON_S("node_fields") ":" JSON_A( |
3392 JSON_S("type") "," | 3385 JSON_S("type") "," |
3393 JSON_S("name") "," | 3386 JSON_S("name") "," |
3394 JSON_S("id") "," | 3387 JSON_S("id") "," |
3395 JSON_S("self_size") "," | 3388 JSON_S("self_size") "," |
3396 JSON_S("edges_index")) "," | 3389 JSON_S("edge_count")) "," |
3397 JSON_S("node_types") ":" JSON_A( | 3390 JSON_S("node_types") ":" JSON_A( |
3398 JSON_A( | 3391 JSON_A( |
3399 JSON_S("hidden") "," | 3392 JSON_S("hidden") "," |
3400 JSON_S("array") "," | 3393 JSON_S("array") "," |
3401 JSON_S("string") "," | 3394 JSON_S("string") "," |
3402 JSON_S("object") "," | 3395 JSON_S("object") "," |
3403 JSON_S("code") "," | 3396 JSON_S("code") "," |
3404 JSON_S("closure") "," | 3397 JSON_S("closure") "," |
3405 JSON_S("regexp") "," | 3398 JSON_S("regexp") "," |
3406 JSON_S("number") "," | 3399 JSON_S("number") "," |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3524 | 3517 |
3525 | 3518 |
3526 void HeapSnapshotJSONSerializer::SortHashMap( | 3519 void HeapSnapshotJSONSerializer::SortHashMap( |
3527 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 3520 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
3528 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 3521 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
3529 sorted_entries->Add(p); | 3522 sorted_entries->Add(p); |
3530 sorted_entries->Sort(SortUsingEntryValue); | 3523 sorted_entries->Sort(SortUsingEntryValue); |
3531 } | 3524 } |
3532 | 3525 |
3533 } } // namespace v8::internal | 3526 } } // namespace v8::internal |
OLD | NEW |