From f600c4f1c51ad1de4fe4b14ac3667bd69e9def3f Mon Sep 17 00:00:00 2001 From: Brad Nelson Date: Thu, 3 Feb 2022 10:07:51 -0800 Subject: [PATCH] Added memory report. --- ueforth/Makefile | 2 +- ueforth/common/utils.fs | 3 +- ueforth/tools/memuse.py | 85 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100755 ueforth/tools/memuse.py diff --git a/ueforth/Makefile b/ueforth/Makefile index 896ac97..44c6cd2 100644 --- a/ueforth/Makefile +++ b/ueforth/Makefile @@ -365,7 +365,7 @@ $(ESP32_SIM)/Esp32forth-sim: \ strip $(STRIP_ARGS) $@ sizes: $(ESP32_SIM)/Esp32forth-sim - echo internals size-all bye | $< | sort -n + echo internals size-all bye | $< | tools/memuse.py # ---- ESP32 ---- diff --git a/ueforth/common/utils.fs b/ueforth/common/utils.fs index 13cae65..b6083f6 100644 --- a/ueforth/common/utils.fs +++ b/ueforth/common/utils.fs @@ -79,10 +79,11 @@ internals definitions ( Words to measure size of things ) : size-vocabulary ( voc ) @ begin dup nonvoc? while - dup >size . dup see. cr >link + dup >params . dup >size . dup . dup see. cr >link repeat drop ; : size-all last-vocabulary @ begin dup while + 0 . 0 . 0 . dup see. cr dup >body size-vocabulary >vocnext repeat drop cr ; diff --git a/ueforth/tools/memuse.py b/ueforth/tools/memuse.py new file mode 100755 index 0000000..66478cf --- /dev/null +++ b/ueforth/tools/memuse.py @@ -0,0 +1,85 @@ +#! /usr/bin/env python + +import sys + +vocab = None +data = [] +for line in sys.stdin.read().splitlines(): + parts = line.strip().split(' ') + if len(parts) != 4 or parts[0] == '-->': + continue + params = int(parts[0]) + size = int(parts[1]) + addr = int(parts[2]) + name = parts[3] + if params == 0 and size == 0 and addr == 0: + vocab = name + else: + data.append((addr, params, size, vocab, name)) + +data.sort() + +base = None +layout = [] +last_end = None +for addr, params, size, vocab, name in data: + end = addr + (params - 1) * 4 + start = end - size + if base is None: + base = start + if last_end is not None and last_end != start: + layout.append((last_end - base, start - last_end, 0, 'none', '--GAP--')) + layout.append((start - base, end - start, params, vocab, name)) + last_end = end + +string_size = 0 +params_size = 0 +struct_size = 0 +builtin_count = 0 +builtin_size = 0 +vocab_size = {} +vocab_count = {} +for start, size, params, vocab, name in layout: + string_size += size - params * 4 - 3 * 4 + params_size += (params * 4) + struct_size += 3 * 4 + if vocab not in vocab_size: + vocab_size[vocab] = 0 + vocab_count[vocab] = 0 + vocab_size[vocab] += size + vocab_count[vocab] += 1 + if params == 0: + builtin_count += 1 + builtin_size += size + +vocab_table = [] +for vocab in vocab_size: + vocab_table.append((vocab_size[vocab], vocab_count[vocab], vocab)) +vocab_table.sort() + +def Columns(data, widths, underline=False): + result = [] + for i in range(len(data)): + result.append((str(data[i]) + ' ' * widths[i])[:widths[i]]) + if underline: + return ''.join(result) + '\n' + ''.join(['-' * len(i) for i in result]) + return ''.join(result) + +items = len(layout) + +columns = [7, 7, 7, 15, 30] +print(Columns(['START', 'SIZE', 'PARAMS', 'VOCABULARY', 'WORD'], columns, underline=True)) +for item in layout: + print(Columns(item, columns)) +print() +columns = [7, 7, 15] +print(Columns(['SIZE', 'COUNT', 'VOCABULARY'], columns, underline=True)) +for item in vocab_table: + print(Columns(item, columns)) +print() +columns = [7, 7, 15] +print(Columns(['SIZE', 'COUNT', 'CATEGORY'], columns, underline=True)) +print(Columns([string_size, items, 'names'], columns)) +print(Columns([params_size, items, 'params'], columns)) +print(Columns([struct_size, items, 'structure'], columns)) +print(Columns([builtin_size, builtin_count, 'builtins'], columns))