| 1168 | } |
| 1169 | |
| 1170 | struct mallinfo emmalloc_mallinfo() { |
| 1171 | MALLOC_ACQUIRE(); |
| 1172 | |
| 1173 | struct mallinfo info; |
| 1174 | // Non-mmapped space allocated (bytes): For emmalloc, |
| 1175 | // let's define this as the difference between heap size and dynamic top end. |
| 1176 | info.arena = emscripten_get_heap_size() - (size_t)_sbrk64(0); |
| 1177 | // Number of "ordinary" blocks. Let's define this as the number of highest |
| 1178 | // size blocks. (subtract one from each, since there is a sentinel node in each list) |
| 1179 | info.ordblks = count_linked_list_size(&freeRegionBuckets[NUM_FREE_BUCKETS-1])-1; |
| 1180 | // Number of free "fastbin" blocks. For emmalloc, define this as the number |
| 1181 | // of blocks that are not in the largest pristine block. |
| 1182 | info.smblks = 0; |
| 1183 | // The total number of bytes in free "fastbin" blocks. |
| 1184 | info.fsmblks = 0; |
| 1185 | for (int i = 0; i < NUM_FREE_BUCKETS-1; ++i) { |
| 1186 | info.smblks += count_linked_list_size(&freeRegionBuckets[i])-1; |
| 1187 | info.fsmblks += count_linked_list_space(&freeRegionBuckets[i]); |
| 1188 | } |
| 1189 | |
| 1190 | info.hblks = 0; // Number of mmapped regions: always 0. (no mmap support) |
| 1191 | info.hblkhd = 0; // Amount of bytes in mmapped regions: always 0. (no mmap support) |
| 1192 | |
| 1193 | // Walk through all the heap blocks to report the following data: |
| 1194 | // The "highwater mark" for allocated space—that is, the maximum amount of |
| 1195 | // space that was ever allocated. Emmalloc does not want to pay code to |
| 1196 | // track this, so this is only reported from current allocation data, and |
| 1197 | // may not be accurate. |
| 1198 | info.usmblks = 0; |
| 1199 | info.uordblks = 0; // The total number of bytes used by in-use allocations. |
| 1200 | info.fordblks = 0; // The total number of bytes in free blocks. |
| 1201 | // The total amount of releasable free space at the top of the heap. |
| 1202 | // This is the maximum number of bytes that could ideally be released by malloc_trim(3). |
| 1203 | Region *lastActualRegion = prev_region((Region*)(listOfAllRegions->endPtr - sizeof(Region))); |
| 1204 | info.keepcost = region_is_free(lastActualRegion) ? lastActualRegion->size : 0; |
| 1205 | |
| 1206 | RootRegion *root = listOfAllRegions; |
| 1207 | while (root) { |
| 1208 | Region *r = (Region*)root; |
| 1209 | assert(debug_region_is_consistent(r)); |
| 1210 | uint8_t *lastRegionEnd = root->endPtr; |
| 1211 | while ((uint8_t*)r < lastRegionEnd) { |
| 1212 | assert(debug_region_is_consistent(r)); |
| 1213 | |
| 1214 | if (region_is_free(r)) { |
| 1215 | // Count only the payload of the free block towards free memory. |
| 1216 | info.fordblks += region_payload_end_ptr(r) - region_payload_start_ptr(r); |
| 1217 | // But the header data of the free block goes towards used memory. |
| 1218 | info.uordblks += REGION_HEADER_SIZE; |
| 1219 | } else { |
| 1220 | info.uordblks += r->size; |
| 1221 | } |
| 1222 | // Update approximate watermark data |
| 1223 | info.usmblks = MAX(info.usmblks, (intptr_t)r + r->size); |
| 1224 | |
| 1225 | if (r->size == 0) { |
| 1226 | break; |
| 1227 | } |
nothing calls this directly
no test coverage detected