refactor: filter debug logs and deduplicate VPI loaders
Suppress DEBUG output at the default INFO level, share the VPI pre-registration walker, and share the .vpi read path between the annotation cache loaders. Source-only change: 53 added, 81 deleted (net -28 lines).
This commit is contained in:
1 parent
634321a12b
commit
38a521fcd2
3 files changed
+59
-85
No files matched your search
@@ -1071,6 +1071,33 @@ def _grow_vpi_ret_cache() -> int:
|
||||
return 1
|
||||
|
||||
|
||||
# _read_vpi_for_cache - read one .vpi file into a malloc buffer.
|
||||
# status[0]: 0 = path/open/allocation failure, 1 = read attempted (None means empty).
|
||||
def _read_vpi_for_cache(src_sha1: str, temp_dir: str, status: int*) -> bytes:
|
||||
if status is not None: status[0] = 0
|
||||
if src_sha1 is None or temp_dir is None: return None
|
||||
vpi_path: str = _vpi_build_path(temp_dir, src_sha1, ".vpi")
|
||||
if vpi_path is None: return None
|
||||
f: io.File* = io.File(vpi_path, io.MODE.R)
|
||||
if f.closed:
|
||||
stdlib.free(vpi_path)
|
||||
return None
|
||||
vpi_buf: bytes = stdlib.malloc(VPI_READ_BUF_SIZE)
|
||||
if vpi_buf is None:
|
||||
f.close()
|
||||
stdlib.free(vpi_path)
|
||||
return None
|
||||
bytes_read: LONG = f.read_all(vpi_buf, VPI_READ_BUF_SIZE)
|
||||
f.close()
|
||||
stdlib.free(vpi_path)
|
||||
if status is not None: status[0] = 1
|
||||
if bytes_read <= 0:
|
||||
stdlib.free(vpi_buf)
|
||||
return None
|
||||
if bytes_read < VPI_READ_BUF_SIZE: vpi_buf[bytes_read] = 0
|
||||
return vpi_buf
|
||||
|
||||
|
||||
# _ensure_vpi_ret_annot_loaded - lazily load a module's vpi stub return-annotation cache.
|
||||
# On cache miss reads {temp_dir}/{sha1[0:2]}/{sha1}.vpi directly; idempotent.
|
||||
def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
@@ -1088,28 +1115,11 @@ def _ensure_vpi_ret_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
for pre_i in range(int(_g_vpi_ret_count)):
|
||||
pre_key: bytes = _g_vpi_ret_keys + pre_i * VPI_KEY_LEN
|
||||
if pre_key[0] == s0 and pre_key[1] == s1 and string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.': return 1
|
||||
# build {temp_dir}/{slice}/{sha1}.vpi — the slice must follow Config.Sha1SliceLevel,
|
||||
# exactly like the writer (StubMergerCollect._sliced_path); hardcoding two hex chars
|
||||
# makes every lookup miss when the project uses slice level 0 or 2.
|
||||
vpi_path: str = _vpi_build_path(temp_dir, src_sha1, ".vpi")
|
||||
if vpi_path is None: return 0
|
||||
f: io.File* = io.File(vpi_path, io.MODE.R)
|
||||
if f.closed:
|
||||
stdlib.free(vpi_path)
|
||||
return 0
|
||||
vpi_buf: bytes = stdlib.malloc(VPI_READ_BUF_SIZE)
|
||||
if vpi_buf is None:
|
||||
f.close()
|
||||
stdlib.free(vpi_path)
|
||||
return 0
|
||||
bytes_read: LONG = f.read_all(vpi_buf, VPI_READ_BUF_SIZE)
|
||||
f.close()
|
||||
if bytes_read > 0:
|
||||
if bytes_read < VPI_READ_BUF_SIZE: vpi_buf[bytes_read] = 0
|
||||
# 单一入口:一次喂齐 ret / param / 逃逸摘要(见 _cache_vpi_annots_text 注释)
|
||||
_cache_vpi_annots_text(vpi_buf, src_sha1)
|
||||
st_r: int = 0
|
||||
vpi_buf: bytes = _read_vpi_for_cache(src_sha1, temp_dir, &st_r)
|
||||
if vpi_buf is None: return st_r
|
||||
_cache_vpi_annots_text(vpi_buf, src_sha1)
|
||||
stdlib.free(vpi_buf)
|
||||
stdlib.free(vpi_path)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -1703,27 +1713,11 @@ def _ensure_vpi_param_annot_loaded(src_sha1: str, temp_dir: str) -> int:
|
||||
for pre_i in range(int(_g_vpi_param_count)):
|
||||
pre_key: bytes = _g_vpi_param_keys + pre_i * VPI_PARAM_KEY_LEN
|
||||
if pre_key[0] == s0 and pre_key[1] == s1 and string.strncmp(pre_key, src_sha1, sha1_len) == 0 and pre_key[sha1_len] == '.': return 1
|
||||
# build {temp_dir}/{slice}/{sha1}.vpi — the slice must follow Config.Sha1SliceLevel,
|
||||
# exactly like the writer (StubMergerCollect._sliced_path); hardcoding two hex chars
|
||||
# makes every lookup miss when the project uses slice level 0 or 2.
|
||||
vpi_path: str = _vpi_build_path(temp_dir, src_sha1, ".vpi")
|
||||
if vpi_path is None: return 0
|
||||
f: io.File* = io.File(vpi_path, io.MODE.R)
|
||||
if f.closed:
|
||||
stdlib.free(vpi_path)
|
||||
return 0
|
||||
vpi_buf: bytes = stdlib.malloc(VPI_READ_BUF_SIZE)
|
||||
if vpi_buf is None:
|
||||
f.close()
|
||||
stdlib.free(vpi_path)
|
||||
return 0
|
||||
bytes_read: LONG = f.read_all(vpi_buf, VPI_READ_BUF_SIZE)
|
||||
f.close()
|
||||
if bytes_read > 0:
|
||||
if bytes_read < VPI_READ_BUF_SIZE: vpi_buf[bytes_read] = 0
|
||||
_cache_vpi_param_annots_text(vpi_buf, src_sha1)
|
||||
st_p: int = 0
|
||||
vpi_buf: bytes = _read_vpi_for_cache(src_sha1, temp_dir, &st_p)
|
||||
if vpi_buf is None: return st_p
|
||||
_cache_vpi_param_annots_text(vpi_buf, src_sha1)
|
||||
stdlib.free(vpi_buf)
|
||||
stdlib.free(vpi_path)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -2744,39 +2738,6 @@ def _ScanVpiDefaults(pool: memhub.MemBuddy*, vbuf: bytes, buf_len: sizet, sha1:
|
||||
stdlib.free(strs)
|
||||
return reg
|
||||
|
||||
# PreRegisterVpiDefaults - 在翻译开始前,把 store 里所有模块的 .vpi 缺省值一次性登记
|
||||
def PreRegisterVpiDefaults(pool: memhub.MemBuddy*, temp_dir: str) -> int:
|
||||
"""预登记所有模块 .vpi 里的函数缺省值;返回登记的函数个数"""
|
||||
if pool is None or temp_dir is None: return 0
|
||||
n: int = StubMergerStore.GetSha1StoreCount()
|
||||
if n <= 0: return 0
|
||||
sha1_arr: bytes = StubMergerStore.GetSha1StoreArrPtr()
|
||||
if sha1_arr is None: return 0
|
||||
total_reg: int = 0
|
||||
si: int
|
||||
for si in range(int(n)):
|
||||
sha1: str = sha1_arr + sizet(si) * 17
|
||||
if sha1[0] == '\0': continue
|
||||
fpath: str = _vpi_build_path(temp_dir, sha1, ".vpi")
|
||||
if fpath is None: continue
|
||||
vf: io.File* = io.File(fpath, io.MODE.R)
|
||||
stdlib.free(fpath)
|
||||
if vf.closed: continue
|
||||
vbuf: bytes = stdlib.malloc(VPI_READ_BUF_SIZE)
|
||||
if vbuf is None:
|
||||
vf.close()
|
||||
continue
|
||||
nrd: LONG = vf.read_all(vbuf, VPI_READ_BUF_SIZE)
|
||||
vf.close()
|
||||
if nrd <= 0:
|
||||
stdlib.free(vbuf)
|
||||
continue
|
||||
if nrd < VPI_READ_BUF_SIZE: vbuf[nrd] = 0
|
||||
total_reg += _ScanVpiDefaults(pool, vbuf, string.strlen(vbuf), sha1)
|
||||
stdlib.free(vbuf)
|
||||
return total_reg
|
||||
|
||||
|
||||
# 单个 .vpi 的枚举成员上限(与 ENUM_MEMBER_MAX 同量级)
|
||||
define VPI_ENUM_MEMBER_MAX = 128
|
||||
|
||||
@@ -2908,10 +2869,8 @@ def _ScanVpiEnumsText(pool: memhub.MemBuddy*, vbuf: bytes, vlen: sizet, sha1: st
|
||||
return reg
|
||||
|
||||
|
||||
# PreRegisterVpiEnums - 翻译开始前,把所有模块 .vpi 里的 `enum X:` 一次性登记进 EnumTable。
|
||||
# 与 PreRegisterVpiDefaults 同理:消除"谁先注入谁登记"的时序依赖。
|
||||
def PreRegisterVpiEnums(pool: memhub.MemBuddy*, temp_dir: str) -> int:
|
||||
"""预登记所有模块 .vpi 里的枚举;返回登记的枚举个数"""
|
||||
# _PreRegisterVpiFiles - run one pre-registration scanner over all registered .vpi files.
|
||||
def _PreRegisterVpiFiles(pool: memhub.MemBuddy*, temp_dir: str, scan_enums: int) -> int:
|
||||
if pool is None or temp_dir is None: return 0
|
||||
n: int = StubMergerStore.GetSha1StoreCount()
|
||||
if n <= 0: return 0
|
||||
@@ -2937,12 +2896,24 @@ def PreRegisterVpiEnums(pool: memhub.MemBuddy*, temp_dir: str) -> int:
|
||||
stdlib.free(vbuf)
|
||||
continue
|
||||
if nrd < VPI_READ_BUF_SIZE: vbuf[nrd] = 0
|
||||
total_reg += _ScanVpiEnumsText(pool, vbuf, string.strlen(vbuf), sha1)
|
||||
if scan_enums != 0: total_reg += _ScanVpiEnumsText(pool, vbuf, string.strlen(vbuf), sha1)
|
||||
else: total_reg += _ScanVpiDefaults(pool, vbuf, string.strlen(vbuf), sha1)
|
||||
stdlib.free(vbuf)
|
||||
return total_reg
|
||||
|
||||
|
||||
# _VpiParamCountAndVararg - 数参数个数;含 *args / **kwargs 时返回 -1(调用方跳过 arity 校验)
|
||||
# PreRegisterVpiDefaults - pre-register defaults from all registered .vpi files.
|
||||
def PreRegisterVpiDefaults(pool: memhub.MemBuddy*, temp_dir: str) -> int:
|
||||
"""Pre-register .vpi default values; returns the number of registrations."""
|
||||
return _PreRegisterVpiFiles(pool, temp_dir, 0)
|
||||
|
||||
|
||||
# PreRegisterVpiEnums - pre-register enums from all registered .vpi files.
|
||||
def PreRegisterVpiEnums(pool: memhub.MemBuddy*, temp_dir: str) -> int:
|
||||
"""Pre-register .vpi enums; returns the number of registrations."""
|
||||
return _PreRegisterVpiFiles(pool, temp_dir, 1)
|
||||
|
||||
|
||||
def _VpiParamCountAndVararg(vbuf: bytes, ps: sizet, pe: sizet) -> int:
|
||||
"""Number of parameters; -1 when the list contains *args/**kwargs."""
|
||||
n: int = VpiText.ParamCount(vbuf, ps, pe)
|
||||
@@ -2951,7 +2922,6 @@ def _VpiParamCountAndVararg(vbuf: bytes, ps: sizet, pe: sizet) -> int:
|
||||
return n
|
||||
|
||||
# LookupSignDefaultsByName - 直接在定义模块 .vpi 文本里查一个函数/方法的缺省参数快照
|
||||
# 与 PreRegisterVpiDefaults 的区别:不登记进全局表,只按名字现查现用(表键不可靠时的兜底)。
|
||||
# 返回 (参数个数 << 8) | 缺省值个数;-1 = 未找到或有不可重建的缺省值。
|
||||
# --- signature range cache --------------------------------------------------
|
||||
# LookupSignDefaultsByName re-scanned the whole .vpi text per query (one
|
||||
|
||||
@@ -90,6 +90,8 @@ novirtual class Logger:
|
||||
# _log - core log output with segmented coloring (prefix symbol / level tag / message).
|
||||
# Format: ├ LEVEL: msg or ├ LEVEL[category]: msg.
|
||||
def _log(self, level: int, prefix_sym: str, level_str: str, msg: str, sym_color: WORD, level_color: WORD, category: str = "") -> int:
|
||||
# Default level is INFO; DEBUG messages stay silent unless the level is lowered.
|
||||
if level < self._level: return 0
|
||||
# Color the prefix symbol
|
||||
self._set_color(sym_color)
|
||||
stdio.printf("%s ", prefix_sym)
|
||||
|
||||
+6
-4
@@ -114,7 +114,7 @@ Retained: `ClassGenEnum.RenumTableDump` is referenced from a diagnostic f-string
|
||||
The following duplicate implementations were merged or redirected:
|
||||
|
||||
- `Phase2`: one directory walker for `.vp` and `.s` sources.
|
||||
- `VpiReader`: shared `_vpi_method_key` for all cached-annotation lookups.
|
||||
- `VpiReader`: shared `_vpi_method_key` for all cached-annotation lookups, a shared pre-registration walker for defaults/enums, and a shared `.vpi` read helper for the two annotation cache loaders.
|
||||
- `StubMergerStore`: shared store initialization/append and alias parsing.
|
||||
- `AssignGenMixin` / `ExprGenCdef`: one `TypeGenCDef.NormalizeDefineBits`.
|
||||
- `AssignGenMixin` / `ExprGenCls`: removed the weaker duplicate class-annotation helpers; calls now use `ExprGenCls`.
|
||||
@@ -124,9 +124,11 @@ The following duplicate implementations were merged or redirected:
|
||||
- `ViperBuild`: one list-join helper.
|
||||
- LSP: removed duplicate `_Doc`, `_Cat`, `_Trim`, and `_HexVal` implementations; `_HashText` keeps its local None semantics.
|
||||
|
||||
Measured source-only reduction for this batch: **235 added / 793 deleted = net -558 lines** (excluding `App/main.vp` and this report).
|
||||
Measured source-only reduction for the main consolidation batch: **235 added / 793 deleted = net -558 lines** (excluding `App/main.vp` and this report).
|
||||
|
||||
Remaining candidates: `VpiReader` annotation-file scanners and cache loaders, `BuildPipeline` MLIR path setup, `LSP _SliceStr/_ByteAt`, and the list/dict iteration helpers.
|
||||
Follow-up batch: VLogger level filtering and the VpiReader pre-registration/read helpers, **53 added / 81 deleted = net -28 lines**.
|
||||
|
||||
Remaining candidates: `VpiReader` escape/willfree annotation scanners, `BuildPipeline` MLIR path setup, `LSP _SliceStr/_ByteAt`, and the list/dict iteration helpers.
|
||||
|
||||
---
|
||||
|
||||
@@ -140,7 +142,7 @@ Remaining candidates: `VpiReader` annotation-file scanners and cache loaders, `B
|
||||
|
||||
### P1: log level is not enforced
|
||||
|
||||
`VLogger` stores `_level` but `_log` never compares it, so `VLogger.debug` prints at the default INFO level. Either add `if level < self._level: return 0` at the start of `_log`, or remove the two debug call sites.
|
||||
Applied: `VLogger._log` now returns early when `level < self._level`, so DEBUG messages stay silent at the default INFO level. The two debug call sites remain available for diagnostic builds.
|
||||
|
||||
### P2: verbose but intentional
|
||||
|
||||
|
||||
Reference in new issue
Block a user