From 3452afee29f2d36af8c0fc61ef34df8823e796ae Mon Sep 17 00:00:00 2001 From: v1rtl Date: Tue, 29 Sep 2026 12:30:40 +0200 Subject: [PATCH 1/2] runtime: add remaining MemStats fields for API compatibility Adds the MemStats fields upstream Go defines that TinyGo did not have: Lookups, StackInuse, StackSys, MSpanInuse, MSpanSys, MCacheInuse, MCacheSys, BuckHashSys, OtherSys, NextGC and GCCPUFraction. TinyGo has no runtime structures for these to describe, so they always report 0 rather than carry made up values. They exist so that packages reading MemStats can be compiled. github.com/prometheus/client_golang fails to type check against TinyGo because these fields are missing. See #3879. --- src/runtime/mstats.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go index 4271bab9a4..aceda6a4ec 100644 --- a/src/runtime/mstats.go +++ b/src/runtime/mstats.go @@ -4,6 +4,9 @@ package runtime // Subset of memory statistics from upstream Go. // Works with conservative gc only. +// +// Fields tracking runtime structures that TinyGo does not have are present for +// API compatibility only and always report 0. // A MemStats records statistics about the memory allocator. type MemStats struct { @@ -21,6 +24,10 @@ type MemStats struct { // heap, stacks, and other internal data structures. Sys uint64 + // Lookups is the number of pointer lookups performed by the + // runtime. Unused, as in upstream Go. + Lookups uint64 + // Heap memory statistics. // HeapAlloc is bytes of allocated heap objects. @@ -80,11 +87,47 @@ type MemStats struct { // structures that are not allocated from heap memory (usually // because they are part of implementing the heap). + // StackInuse is bytes in stack spans. + StackInuse uint64 + + // StackSys is bytes of stack memory obtained from the OS. + StackSys uint64 + + // MSpanInuse is bytes of allocated mspan structures. + MSpanInuse uint64 + + // MSpanSys is bytes of memory obtained from the OS for mspan + // structures. + MSpanSys uint64 + + // MCacheInuse is bytes of allocated mcache structures. + MCacheInuse uint64 + + // MCacheSys is bytes of memory obtained from the OS for mcache + // structures. + MCacheSys uint64 + + // BuckHashSys is bytes of memory in profiling bucket hash tables. + BuckHashSys uint64 + // GCSys is bytes of memory in garbage collection metadata. GCSys uint64 + // OtherSys is bytes of memory in miscellaneous off-heap runtime + // allocations. + OtherSys uint64 + + // Garbage collector statistics. + + // NextGC is the target heap size of the next GC cycle. + NextGC uint64 + // NumGC is the number of completed GC cycles. // // The leaking collector never collects, so it always reports 0. NumGC uint32 + + // GCCPUFraction is the fraction of available CPU time used by the GC + // since the program started. + GCCPUFraction float64 } From ef4d9e8aff6bf71825de86de95b9a228d5d8abbe Mon Sep 17 00:00:00 2001 From: v1rtl Date: Tue, 29 Sep 2026 12:30:40 +0200 Subject: [PATCH 2/2] runtime: add ThreadCreateProfile stub Adds runtime.StackRecord and a runtime.ThreadCreateProfile stub that always reports an empty profile, matching the existing SetBlockProfileRate and SetMutexProfileFraction stubs. github.com/prometheus/client_golang calls ThreadCreateProfile to count OS threads. See #3879. --- src/runtime/debug.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/runtime/debug.go b/src/runtime/debug.go index 62f6727f71..e8faec8cb7 100644 --- a/src/runtime/debug.go +++ b/src/runtime/debug.go @@ -26,3 +26,25 @@ func SetBlockProfileRate(rate int) { func SetMutexProfileFraction(rate int) int { return 0 } + +// A StackRecord describes a single execution stack. +type StackRecord struct { + Stack0 [32]uintptr // stack trace for this record, ends at first 0 entry +} + +// Stack returns the stack trace associated with the record, a prefix of +// r.Stack0. +func (r *StackRecord) Stack() []uintptr { + for i, v := range r.Stack0 { + if v == 0 { + return r.Stack0[0:i] + } + } + return r.Stack0[0:] +} + +// Stub for ThreadCreateProfile, always reports an empty profile. TinyGo has no +// thread creation profiler. +func ThreadCreateProfile(p []StackRecord) (n int, ok bool) { + return 0, true +}