From 47a1e6ad6a7a20c142210ea129c83cee292a8545 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Thu, 26 Sep 2024 11:46:36 -0400 Subject: [PATCH] fix order of fields in heapsnapshot & improve formatting The order of the fields in the json object is critical for dev tools. It seems their JSON parser doesn't just load the whole json object in then process it, but does some processing on the fly. With this the snapshot loads in vscode and dev tools --- src/gc-heap-snapshot.cpp | 42 ++++++++----------- stdlib/Profile/src/heapsnapshot_reassemble.jl | 10 ++++- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/gc-heap-snapshot.cpp b/src/gc-heap-snapshot.cpp index fcda11dad4f8a..72eb17115f4c7 100644 --- a/src/gc-heap-snapshot.cpp +++ b/src/gc-heap-snapshot.cpp @@ -618,38 +618,32 @@ void final_serialize_heap_snapshot(ios_t *json, ios_t *strings, HeapSnapshot &sn { // mimicking https://github.com/nodejs/node/blob/5fd7a72e1c4fbaf37d3723c4c81dce35c149dc84/deps/v8/src/profiler/heap-snapshot-generator.cc#L2567-L2567 // also https://github.com/microsoft/vscode-v8-heap-tools/blob/c5b34396392397925ecbb4ecb904a27a2754f2c1/v8-heap-parser/src/decoder.rs#L43-L51 - ios_printf(json, "{\"snapshot\":{"); + ios_printf(json, "{\"snapshot\":{\n"); - ios_printf(json, "\"meta\":{"); - ios_printf(json, "\"node_fields\":[\"type\",\"name\",\"id\",\"self_size\",\"edge_count\",\"trace_node_id\",\"detachedness\"],"); - ios_printf(json, "\"node_types\":["); + ios_printf(json, " \"meta\":{\n"); + ios_printf(json, " \"node_fields\":[\"type\",\"name\",\"id\",\"self_size\",\"edge_count\",\"trace_node_id\",\"detachedness\"],\n"); + ios_printf(json, " \"node_types\":["); snapshot.node_types.print_json_array(json, false); ios_printf(json, ","); - ios_printf(json, "\"string\", \"number\", \"number\", \"number\", \"number\", \"number\"],"); - ios_printf(json, "\"edge_fields\":[\"type\",\"name_or_index\",\"to_node\"],"); - ios_printf(json, "\"edge_types\":["); + ios_printf(json, "\"string\", \"number\", \"number\", \"number\", \"number\", \"number\"],\n"); + ios_printf(json, " \"edge_fields\":[\"type\",\"name_or_index\",\"to_node\"],\n"); + ios_printf(json, " \"edge_types\":["); snapshot.edge_types.print_json_array(json, false); ios_printf(json, ","); - ios_printf(json, "\"string_or_number\",\"from_node\"],"); + ios_printf(json, "\"string_or_number\",\"from_node\"],\n"); // not used. Required by microsoft/vscode-v8-heap-tools - ios_printf(json, "\"trace_function_info_fields\":[\"function_id\",\"name\",\"script_name\",\"script_id\",\"line\",\"column\"],"); - ios_printf(json, "\"trace_node_fields\":[\"id\",\"function_info_index\",\"count\",\"size\",\"children\"],"); - ios_printf(json, "\"sample_fields\":[\"timestamp_us\",\"last_assigned_id\"],"); - ios_printf(json, "\"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]"); + ios_printf(json, " \"trace_function_info_fields\":[\"function_id\",\"name\",\"script_name\",\"script_id\",\"line\",\"column\"],\n"); + ios_printf(json, " \"trace_node_fields\":[\"id\",\"function_info_index\",\"count\",\"size\",\"children\"],\n"); + ios_printf(json, " \"sample_fields\":[\"timestamp_us\",\"last_assigned_id\"],\n"); + ios_printf(json, " \"location_fields\":[\"object_index\",\"script_id\",\"line\",\"column\"]\n"); // end not used - ios_printf(json, "},\n"); // end "meta" + ios_printf(json, " },\n"); // end "meta" - ios_printf(json, "\"node_count\":%zu,", snapshot.num_nodes); - ios_printf(json, "\"edge_count\":%zu,", snapshot.num_edges); - ios_printf(json, "\"trace_function_count\":0"); // not used. Required by microsoft/vscode-v8-heap-tools - ios_printf(json, "},\n"); // end "snapshot" - - // not used. Required by microsoft/vscode-v8-heap-tools - ios_printf(json, "\"trace_function_infos\":[],"); - ios_printf(json, "\"trace_tree\":[],"); - ios_printf(json, "\"samples\":[],"); - ios_printf(json, "\"locations\":[]"); - // end not used + ios_printf(json, " \"node_count\":%zu,\n", snapshot.num_nodes); + ios_printf(json, " \"edge_count\":%zu,\n", snapshot.num_edges); + ios_printf(json, " \"trace_function_count\":0\n"); // not used. Required by microsoft/vscode-v8-heap-tools + ios_printf(json, "}\n"); // end "snapshot" + // this } is removed by the julia reassembler in Profile ios_printf(json, "}"); } diff --git a/stdlib/Profile/src/heapsnapshot_reassemble.jl b/stdlib/Profile/src/heapsnapshot_reassemble.jl index 2413ae538b8ac..b2d86ee1f27b6 100644 --- a/stdlib/Profile/src/heapsnapshot_reassemble.jl +++ b/stdlib/Profile/src/heapsnapshot_reassemble.jl @@ -155,7 +155,8 @@ function assemble_snapshot(in_prefix, io::IO) _write_decimal_number(io, nodes.edge_count[i], _digits_buf) print(io, ",0,0") end - print(io, "],\"edges\":[") + print(io, "],\n") + print(io, "\"edges\":[") e = 1 for n in 1:length(nodes) count = nodes.edge_count[n] @@ -177,6 +178,13 @@ function assemble_snapshot(in_prefix, io::IO) end println(io, "],") + # not used. Required by microsoft/vscode-v8-heap-tools + # This order of these fields is required by chrome dev tools otherwise loading fails + println(io, "\"trace_function_infos\":[],") + println(io, "\"trace_tree\":[],") + println(io, "\"samples\":[],") + println(io, "\"locations\":[],") + println(io, "\"strings\":[") open(string(in_prefix, ".strings"), "r") do strings_io first = true