Skip to content

Commit 49d8df1

Browse files
authored
Merge pull request #211 from microsoft/dev/qmuntal/inlinehash
cng: allow hash constructors to be inlined
2 parents fa20a3c + 572fd35 commit 49d8df1

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

cng/hash.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ type hashAlgorithm struct {
125125
blockSize uint32
126126
}
127127

128+
// Keep this out of line so newHash can be inlined and callers that only
129+
// need hash metadata can avoid allocating a Hash.
130+
//
131+
//go:noinline
128132
func mustLoadHash(id string, flags bcrypt.AlgorithmProviderFlags) *hashAlgorithm {
129133
h, err := loadHash(id, flags)
130134
if err != nil {

cng/hash_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,37 @@ func TestHashAllocations(t *testing.T) {
232232
}
233233
}
234234

235+
func TestHashConstructorAllocations(t *testing.T) {
236+
// Call the constructors directly inside each function so they can be
237+
// inlined and the Hash need not escape when only its size is needed.
238+
tests := []struct {
239+
h crypto.Hash
240+
size func() int
241+
}{
242+
{crypto.MD4, func() int { return cng.NewMD4().Size() }},
243+
{crypto.MD5, func() int { return cng.NewMD5().Size() }},
244+
{crypto.SHA1, func() int { return cng.NewSHA1().Size() }},
245+
{crypto.SHA256, func() int { return cng.NewSHA256().Size() }},
246+
{crypto.SHA384, func() int { return cng.NewSHA384().Size() }},
247+
{crypto.SHA512, func() int { return cng.NewSHA512().Size() }},
248+
{crypto.SHA3_256, func() int { return cng.NewSHA3_256().Size() }},
249+
{crypto.SHA3_384, func() int { return cng.NewSHA3_384().Size() }},
250+
{crypto.SHA3_512, func() int { return cng.NewSHA3_512().Size() }},
251+
}
252+
for _, tt := range tests {
253+
t.Run(tt.h.String(), func(t *testing.T) {
254+
if !cng.SupportsHash(tt.h) {
255+
t.Skip("skipping: not supported")
256+
}
257+
if allocs := testing.AllocsPerRun(10, func() {
258+
sink ^= byte(tt.size())
259+
}); allocs != 0 {
260+
t.Errorf("allocs = %v, want 0", allocs)
261+
}
262+
})
263+
}
264+
}
265+
235266
func TestHashStructAllocations(t *testing.T) {
236267
msg := []byte("testing")
237268

0 commit comments

Comments
 (0)