| ... | @@ -36,6 +36,20 @@ static int compare_type_abi_sizes_desc(const void *a, const void *b) { | ... | @@ -36,6 +36,20 @@ static int compare_type_abi_sizes_desc(const void *a, const void *b) { |
| 36 | return 0; | 36 | return 0; |
| 37 | } | 37 | } |
| 38 | | 38 | |
| | 39 | static void start_child(FILE *f, size_t indent) { |
| | 40 | fprintf(f, "\n"); |
| | 41 | for (size_t i = 0; i < indent; i += 1) { |
| | 42 | fprintf(f, " "); |
| | 43 | } |
| | 44 | } |
| | 45 | |
| | 46 | static void start_peer(FILE *f, size_t indent) { |
| | 47 | fprintf(f, ",\n"); |
| | 48 | for (size_t i = 0; i < indent; i += 1) { |
| | 49 | fprintf(f, " "); |
| | 50 | } |
| | 51 | } |
| | 52 | |
| 39 | static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) { | 53 | static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) { |
| 40 | ZigList<ZigType *> children = {}; | 54 | ZigList<ZigType *> children = {}; |
| 41 | uint64_t sum_from_fields = 0; | 55 | uint64_t sum_from_fields = 0; |
| ... | @@ -45,34 +59,63 @@ static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) { | ... | @@ -45,34 +59,63 @@ static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) { |
| 45 | sum_from_fields += field->type_entry->abi_size; | 59 | sum_from_fields += field->type_entry->abi_size; |
| 46 | } | 60 | } |
| 47 | qsort(children.items, children.length, sizeof(ZigType *), compare_type_abi_sizes_desc); | 61 | qsort(children.items, children.length, sizeof(ZigType *), compare_type_abi_sizes_desc); |
| 48 | fprintf(f, " (padding = %" ZIG_PRI_u64 ")\n", struct_type->abi_size - sum_from_fields); | 62 | |
| | 63 | start_peer(f, indent); |
| | 64 | fprintf(f, "\"padding\": \"%" ZIG_PRI_u64 "\"", struct_type->abi_size - sum_from_fields); |
| | 65 | |
| | 66 | start_peer(f, indent); |
| | 67 | fprintf(f, "\"fields\": ["); |
| | 68 | |
| 49 | for (size_t i = 0; i < children.length; i += 1) { | 69 | for (size_t i = 0; i < children.length; i += 1) { |
| | 70 | if (i == 0) { |
| | 71 | start_child(f, indent + 1); |
| | 72 | } else { |
| | 73 | start_peer(f, indent + 1); |
| | 74 | } |
| | 75 | fprintf(f, "{"); |
| | 76 | |
| 50 | ZigType *child_type = children.at(i); | 77 | ZigType *child_type = children.at(i); |
| 51 | tree_print(f, child_type, indent + 1); | 78 | tree_print(f, child_type, indent + 2); |
| | 79 | |
| | 80 | start_child(f, indent + 1); |
| | 81 | fprintf(f, "}"); |
| 52 | } | 82 | } |
| | 83 | |
| | 84 | start_child(f, indent); |
| | 85 | fprintf(f, "]"); |
| 53 | } | 86 | } |
| 54 | | 87 | |
| 55 | static void tree_print(FILE *f, ZigType *ty, size_t indent) { | 88 | static void tree_print(FILE *f, ZigType *ty, size_t indent) { |
| 56 | for (size_t i = 0; i < indent; i += 1) { | 89 | start_child(f, indent); |
| 57 | fprintf(f, " "); | 90 | fprintf(f, "\"type\": \"%s\"", buf_ptr(&ty->name)); |
| 58 | } | 91 | |
| 59 | fprintf(f, "%s: ", buf_ptr(&ty->name)); | 92 | start_peer(f, indent); |
| | 93 | fprintf(f, "\"sizef\": \""); |
| 60 | pretty_print_bytes(f, ty->abi_size); | 94 | pretty_print_bytes(f, ty->abi_size); |
| | 95 | fprintf(f, "\""); |
| | 96 | |
| | 97 | start_peer(f, indent); |
| | 98 | fprintf(f, "\"size\": \"%" ZIG_PRI_u64 "\"", ty->abi_size); |
| | 99 | |
| 61 | switch (ty->id) { | 100 | switch (ty->id) { |
| 62 | case ZigTypeIdFnFrame: | 101 | case ZigTypeIdFnFrame: |
| 63 | return tree_print_struct(f, ty->data.frame.locals_struct, indent); | 102 | return tree_print_struct(f, ty->data.frame.locals_struct, indent); |
| 64 | case ZigTypeIdStruct: | 103 | case ZigTypeIdStruct: |
| 65 | return tree_print_struct(f, ty, indent); | 104 | return tree_print_struct(f, ty, indent); |
| 66 | default: | 105 | default: |
| 67 | fprintf(f, "\n"); | 106 | start_child(f, indent); |
| 68 | return; | 107 | return; |
| 69 | } | 108 | } |
| 70 | } | 109 | } |
| 71 | | 110 | |
| 72 | void zig_print_stack_report(CodeGen *g, FILE *f) { | 111 | void zig_print_stack_report(CodeGen *g, FILE *f) { |
| 73 | if (g->largest_frame_fn == nullptr) { | 112 | if (g->largest_frame_fn == nullptr) { |
| 74 | fprintf(f, "No async function frames in entire compilation.\n"); | 113 | fprintf(f, "{\"error\": \"No async function frames in entire compilation.\"}\n"); |
| 75 | return; | 114 | return; |
| 76 | } | 115 | } |
| 77 | tree_print(f, g->largest_frame_fn->frame_type, 0); | 116 | fprintf(f, "{"); |
| | 117 | tree_print(f, g->largest_frame_fn->frame_type, 1); |
| | 118 | |
| | 119 | start_child(f, 0); |
| | 120 | fprintf(f, "}\n"); |
| 78 | } | 121 | } |