Fixed size array allocated using runtime.newobject

134 views
Skip to first unread message

Nugraha

unread,
Oct 31, 2023, 11:02:48 AM10/31/23
to golan...@googlegroups.com
Hi, I was wondering why is `var f [d * 4]byte` allocated with
`runtime.newobject`, as we can see the size is already known at compile
time because `d` is a constant value, by doing some propagation we can
end up having `[16]byte`.

TIA

> 42 . . }
> 43 . . }
> 44 . .
> 45 . . type ffx struct{}
> 46 . .
> 47 2MB 2MB func (ffx) PrecompF(a cipher.Block, h int, g string, e int) (res [16]byte) {
> 48 . . const d = 4
> 49 1MB 1MB var f [d * 4]byte
> . . 5aa4e0: LEAQ 0x1ec59(IP), AX ffx.go:49
> 1MB 1MB 5aa4e7: CALL runtime.newobject(SB) ffx.go:49
> . . 5aa4ec: MOVQ AX, 0x60(SP) ffx.go:49
>
> 50 . . fv := (*[d]uint32)(unsafe.Pointer(&f[0]))
> 51 . . c := len(g)
> 52 . . b := 10
> 53 . .
> 54 . . fv[0] |= 0x01_02_01_00
> 55 . . fv[0] |= uint32((e >> 16) & 255)
> 56 . .
> 57 . . fv[1] |= uint32((e >> 8) & 255 << 24)
> 58 . . fv[1] |= uint32((e & 255) << 16)
> 59 . . fv[1] |= uint32(b << 8)
> 60 . . fv[1] |= uint32((h / 2) & 255)
> 61 . .
> 62 . . fv[2] = uint32(h)
> 63 . . fv[3] = uint32(c)
> 64 . .
> 65 . . endianSwaps(fv)
> 66 . . a.Encrypt(res[:], f[:])
> 67 . . return
> 68 . . }
> 69 . .
> 70 . . func (ffx) Precompb(c int, g int) int {
> 71 . . var e int64 = int64(g) / 2
> 72 . . var a int = 0

Jason E. Aten

unread,
Oct 31, 2023, 5:25:57 PM10/31/23
to golang-nuts
Just a guess:

Maybe the escape analysis cannot prove that it does not escape the function?

The unsafe pointer probably makes it nearly impossible for the compiler to tell. Perhaps?

The pointer does get passed to a.Encrypt(), which could store it beyond the lifetime of the
Precomp() call.  I cannot tell myself..

Reply all
Reply to author
Forward
0 new messages