-
Notifications
You must be signed in to change notification settings - Fork 400
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Search before asking
- I had searched in the issues and found no similar issues.
Version
Current
Component(s)
Go
It was introduced in the PR #3071
Minimal reproduce step
Run go build -gcflags='-m -m'
Output -
buffer.go:71: cannot inline (*ByteBuffer).WriteByte: cost 86 > budget 80
buffer.go:86: cannot inline (*ByteBuffer).WriteInt8: cost 85 > budget 80
buffer.go:114: cannot inline (*ByteBuffer).WriteUint32: cost 85 > budget 80
buffer.go:121: cannot inline (*ByteBuffer).WriteInt32: cost 86 > budget 80
buffer.go:199: cannot inline (*ByteBuffer).ReadByte: cost 94 > budget 80
buffer.go:251: cannot inline (*ByteBuffer).ReadUint32: cost 96 > budget 80
buffer.go:264: cannot inline (*ByteBuffer).ReadUint64: cost 96 > budget 80Summary
buffer.go uses //go:inline on functions. This is not a valid Go compiler directive — the standard gc compiler silently ignores it. As a result, critical hot-path functions like WriteInt32, ReadByte, ReadUint64 etc. are not being inlined, paying full function call overhead on every invocation.
Root Cause
- Write functions: the
grow()call adds enough cost (~40) to push the total over 80. - Read functions: the inline
BufferOutOfBoundError()construction adds ~15–20 cost, pushing totals to 94–97.
Proposed Fix
- Remove all
//go:inlinepragmas — they are no-ops and misleading. - Write path: inline the fast-path bounds check directly and keep only
growSlow()as//go:noinline:func (b *ByteBuffer) WriteInt8(value int8) { if b.writerIndex+1 > len(b.data) { b.growSlow(1) } b.data[b.writerIndex] = byte(value) b.writerIndex++ }
- Read path: move error construction to a
//go:noinlinecold-path helper:func (b *ByteBuffer) ReadInt8(err *Error) int8 { if b.readerIndex+1 > len(b.data) { b.readBoundsError(err, 1) return 0 } v := int8(b.data[b.readerIndex]) b.readerIndex++ return v } //go:noinline func (b *ByteBuffer) readBoundsError(err *Error, n int) { *err = BufferOutOfBoundError(b.readerIndex, n, len(b.data)) }
Both changes bring function costs well under 80, enabling automatic compiler inlining with no pragmas needed.
Impact
These are the most frequently called functions in the entire serialization pipeline. Enabling inlining eliminates function call overhead (stack frame, argument spilling) on every primitive read/write operation.
Are you willing to submit a PR?
- I'm willing to submit a PR!
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working