| ... | ... | @@ -36,6 +36,20 @@ static int compare_type_abi_sizes_desc(const void *a, const void *b) { |
| 36 | 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 | 53 | static void tree_print_struct(FILE *f, ZigType *struct_type, size_t indent) { |
| 40 | 54 | ZigList<ZigType *> children = {}; |
| 41 | 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 | 59 | sum_from_fields += field->type_entry->abi_size; |
| 46 | 60 | } |
| 47 | 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 | 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 | 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 | 88 | static void tree_print(FILE *f, ZigType *ty, size_t indent) { |
| 56 | | for (size_t i = 0; i < indent; i += 1) { |
| 57 | | fprintf(f, " "); |
| 58 | | } |
| 59 | | fprintf(f, "%s: ", buf_ptr(&ty->name)); |
| 89 | start_child(f, indent); |
| 90 | fprintf(f, "\"type\": \"%s\"", buf_ptr(&ty->name)); |
| 91 | |
| 92 | start_peer(f, indent); |
| 93 | fprintf(f, "\"sizef\": \""); |
| 60 | 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 | 100 | switch (ty->id) { |
| 62 | 101 | case ZigTypeIdFnFrame: |
| 63 | 102 | return tree_print_struct(f, ty->data.frame.locals_struct, indent); |
| 64 | 103 | case ZigTypeIdStruct: |
| 65 | 104 | return tree_print_struct(f, ty, indent); |
| 66 | 105 | default: |
| 67 | | fprintf(f, "\n"); |
| 106 | start_child(f, indent); |
| 68 | 107 | return; |
| 69 | 108 | } |
| 70 | 109 | } |
| 71 | 110 | |
| 72 | 111 | void zig_print_stack_report(CodeGen *g, FILE *f) { |
| 73 | 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 | 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 | } |