Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rvgo: experimental no-alloc noescape merkle funcs #88

Draft
wants to merge 1 commit into
base: feature/mininny/rvgo-radix-memory
Choose a base branch
from

Conversation

protolambda
Copy link
Collaborator

@protolambda protolambda commented Oct 16, 2024

Description

A little bit hacky. And makes the assumption there's only 1 concurrent hasher (this could be fixed by allocating a keccakState per Memory merkleization job, and passing it as typed function argument through the merkle functions).

  • Share hasher, so hasher doesn't get re-allocated every hash call
  • Tricks with go:noescape and go:linkname to force it to not assume the function interface, and not allow any slice data to escape to the heap

This essentially removes all the non-essential allocations from the merkleization work, in a bit of an unsafe non-recommended way, to see how much performance can improve with this kind of heap-analysis informed memory optimization.

Profiles of the benchmark show that it's only a little bit faster, even after removing a theorectical ~10 million object allocations.

Before:
before

After:
after

CPU:
Before:

cpu: AMD Ryzen 9 5950X 16-Core Processor            
BenchmarkMemoryOperations
BenchmarkMemoryOperations/RandomReadWrite_Small
BenchmarkMemoryOperations/RandomReadWrite_Small-32         	48573948	        23.16 ns/op
BenchmarkMemoryOperations/RandomReadWrite_Medium
BenchmarkMemoryOperations/RandomReadWrite_Medium-32        	   12456	    126946 ns/op
BenchmarkMemoryOperations/RandomReadWrite_Large
BenchmarkMemoryOperations/RandomReadWrite_Large-32         	    9952	    112717 ns/op
BenchmarkMemoryOperations/SequentialReadWrite_Small
BenchmarkMemoryOperations/SequentialReadWrite_Small-32     	231982236	         5.219 ns/op
BenchmarkMemoryOperations/SequentialReadWrite_Large
BenchmarkMemoryOperations/SequentialReadWrite_Large-32     	222372898	         5.442 ns/op
BenchmarkMemoryOperations/SparseMemoryUsage
BenchmarkMemoryOperations/SparseMemoryUsage-32             	  528241	      2216 ns/op
BenchmarkMemoryOperations/DenseMemoryUsage
BenchmarkMemoryOperations/DenseMemoryUsage-32              	141923272	         8.803 ns/op
BenchmarkMemoryOperations/SmallFrequentUpdates
BenchmarkMemoryOperations/SmallFrequentUpdates-32          	36277586	        32.13 ns/op
BenchmarkMemoryOperations/MerkleProofGeneration_Small
BenchmarkMemoryOperations/MerkleProofGeneration_Small-32   	  655786	      1573 ns/op
BenchmarkMemoryOperations/MerkleProofGeneration_Large
BenchmarkMemoryOperations/MerkleProofGeneration_Large-32   	  561040	      1985 ns/op
BenchmarkMemoryOperations/MerkleRootCalculation_Small
BenchmarkMemoryOperations/MerkleRootCalculation_Small-32   	224840816	         5.409 ns/op
BenchmarkMemoryOperations/MerkleRootCalculation_Large
BenchmarkMemoryOperations/MerkleRootCalculation_Large-32   	205111311	         5.721 ns/op
PASS

After:

cpu: AMD Ryzen 9 5950X 16-Core Processor            
BenchmarkMemoryOperations
BenchmarkMemoryOperations/RandomReadWrite_Small
BenchmarkMemoryOperations/RandomReadWrite_Small-32         	51766090	        21.48 ns/op
BenchmarkMemoryOperations/RandomReadWrite_Medium
BenchmarkMemoryOperations/RandomReadWrite_Medium-32        	   12172	    130552 ns/op
BenchmarkMemoryOperations/RandomReadWrite_Large
BenchmarkMemoryOperations/RandomReadWrite_Large-32         	   10000	    113670 ns/op
BenchmarkMemoryOperations/SequentialReadWrite_Small
BenchmarkMemoryOperations/SequentialReadWrite_Small-32     	223583344	         4.971 ns/op
BenchmarkMemoryOperations/SequentialReadWrite_Large
BenchmarkMemoryOperations/SequentialReadWrite_Large-32     	232579297	         5.322 ns/op
BenchmarkMemoryOperations/SparseMemoryUsage
BenchmarkMemoryOperations/SparseMemoryUsage-32             	  423361	      2386 ns/op
BenchmarkMemoryOperations/DenseMemoryUsage
BenchmarkMemoryOperations/DenseMemoryUsage-32              	145170620	         8.592 ns/op
BenchmarkMemoryOperations/SmallFrequentUpdates
BenchmarkMemoryOperations/SmallFrequentUpdates-32          	36379844	        30.87 ns/op
BenchmarkMemoryOperations/MerkleProofGeneration_Small
BenchmarkMemoryOperations/MerkleProofGeneration_Small-32   	  702778	      1490 ns/op
BenchmarkMemoryOperations/MerkleProofGeneration_Large
BenchmarkMemoryOperations/MerkleProofGeneration_Large-32   	  555963	      1900 ns/op
BenchmarkMemoryOperations/MerkleRootCalculation_Small
BenchmarkMemoryOperations/MerkleRootCalculation_Small-32   	233706420	         5.124 ns/op
BenchmarkMemoryOperations/MerkleRootCalculation_Large
BenchmarkMemoryOperations/MerkleRootCalculation_Large-32   	218443596	         5.557 ns/op
PASS

Heap-escape:

./keccakfast.go:17:6: cannot inline keccakReset: no function body
./keccakfast.go:21:6: cannot inline keccakWrite: no function body
./keccakfast.go:25:6: cannot inline keccakRead: no function body
./keccakfast.go:30:6: cannot inline hashPair: function too complex: cost 259 exceeds budget 80
./keccakfast.go:38:6: cannot inline hash: function too complex: cost 193 exceeds budget 80
./keccakfast.go:28:68: inlining call to sha3.NewLegacyKeccak256
./keccakfast.go:28:68: Before inlining: 
.   CALLFUNC hash.Hash tc(1) # keccakfast.go:28:68
./keccakfast.go:28:68: After inlining 
.   .   AS2 Def tc(1) # keccakfast.go:28:68
.   .   INLMARK # +keccakfast.go:28:68
.   INLCALL hash.Hash tc(1) # keccakfast.go:28:68
.   .   BLOCK tc(1) # keccakfast.go:28:68
.   .   .   DCL tc(1) # keccakfast.go:28:68
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   .   AS2 tc(1) # keccakfast.go:28:68
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   .   .   CONVIFACE Implicit hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   PTRLIT PTR-*sha3.state tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   STRUCTLIT sha3.state tc(1) # keccakfast.go:28:68 hashes.go:71:52
.   .   .   .   .   .   .   STRUCTKEY sha3.rate # keccakfast.go:28:68 hashes.go:71:53
.   .   .   .   .   .   .   .   LITERAL-136 int tc(1) # keccakfast.go:28:68 hashes.go:71:59
.   .   .   .   .   .   .   STRUCTKEY sha3.outputLen # keccakfast.go:28:68 hashes.go:71:64
.   .   .   .   .   .   .   .   LITERAL-32 int tc(1) # keccakfast.go:28:68 hashes.go:71:75
.   .   .   .   .   .   .   STRUCTKEY sha3.dsbyte # keccakfast.go:28:68 hashes.go:71:79
.   .   .   .   .   .   .   .   LITERAL-1 byte tc(1) # keccakfast.go:28:68 hashes.go:71:87
.   .   .   .   .   ADDR PTR-*uint8 tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   ADDR PTR-*uint8 tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   GOTO fast..i0 tc(1) # keccakfast.go:28:68
.   .   LABEL fast..i0 # keccakfast.go:28:68
.   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
./keccakfast.go:28:44: inlining call to reflect.ValueOf
./keccakfast.go:28:44: Before inlining: 
.   CALLFUNC reflect.Value tc(1) # keccakfast.go:28:44
.   .   CONVIFACE Implicit any tc(1) # keccakfast.go:28:68
.   .   .   PAREN hash.Hash tc(1) # keccakfast.go:28:68
.   .   .   .   .   AS2 Def tc(1) # keccakfast.go:28:68
.   .   .   .   .   INLMARK # +keccakfast.go:28:68
.   .   .   .   INLCALL hash.Hash tc(1) # keccakfast.go:28:68
.   .   .   .   .   BLOCK tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   DCL tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   .   .   .   .   AS2 tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   .   .   .   .   .   CONVIFACE Implicit hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   .   PTRLIT PTR-*sha3.state tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   .   .   STRUCTLIT sha3.state tc(1) # keccakfast.go:28:68 hashes.go:71:52
.   .   .   .   .   .   .   .   .   .   STRUCTKEY sha3.rate # keccakfast.go:28:68 hashes.go:71:53
.   .   .   .   .   .   .   .   .   .   .   LITERAL-136 int tc(1) # keccakfast.go:28:68 hashes.go:71:59
.   .   .   .   .   .   .   .   .   .   STRUCTKEY sha3.outputLen # keccakfast.go:28:68 hashes.go:71:64
.   .   .   .   .   .   .   .   .   .   .   LITERAL-32 int tc(1) # keccakfast.go:28:68 hashes.go:71:75
.   .   .   .   .   .   .   .   .   .   STRUCTKEY sha3.dsbyte # keccakfast.go:28:68 hashes.go:71:79
.   .   .   .   .   .   .   .   .   .   .   LITERAL-1 byte tc(1) # keccakfast.go:28:68 hashes.go:71:87
.   .   .   .   .   .   .   .   ADDR PTR-*uint8 tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   .   ADDR PTR-*uint8 tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   GOTO fast..i0 tc(1) # keccakfast.go:28:68
.   .   .   .   .   LABEL fast..i0 # keccakfast.go:28:68
.   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
./keccakfast.go:28:44: After inlining 
.   .   .   DCL # keccakfast.go:28:44
.   .   .   .   NAME-reflect.i Class:PAUTO Offset:0 InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3262:14
.   .   AS2 Def tc(1) # keccakfast.go:28:44
.   .   .   NAME-reflect.i Class:PAUTO Offset:0 InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3262:14
.   .   .   CONVIFACE Implicit any tc(1) # keccakfast.go:28:68
.   .   .   .   PAREN hash.Hash tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   AS2 Def tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   INLMARK # +keccakfast.go:28:68
.   .   .   .   .   INLCALL hash.Hash tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   BLOCK tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   .   DCL tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   .   .   .   .   .   AS2 tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   .   .   .   .   .   .   CONVIFACE Implicit hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   .   .   PTRLIT PTR-*sha3.state tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   .   .   .   STRUCTLIT sha3.state tc(1) # keccakfast.go:28:68 hashes.go:71:52
.   .   .   .   .   .   .   .   .   .   .   STRUCTKEY sha3.rate # keccakfast.go:28:68 hashes.go:71:53
.   .   .   .   .   .   .   .   .   .   .   .   LITERAL-136 int tc(1) # keccakfast.go:28:68 hashes.go:71:59
.   .   .   .   .   .   .   .   .   .   .   STRUCTKEY sha3.outputLen # keccakfast.go:28:68 hashes.go:71:64
.   .   .   .   .   .   .   .   .   .   .   .   LITERAL-32 int tc(1) # keccakfast.go:28:68 hashes.go:71:75
.   .   .   .   .   .   .   .   .   .   .   STRUCTKEY sha3.dsbyte # keccakfast.go:28:68 hashes.go:71:79
.   .   .   .   .   .   .   .   .   .   .   .   LITERAL-1 byte tc(1) # keccakfast.go:28:68 hashes.go:71:87
.   .   .   .   .   .   .   .   .   ADDR PTR-*uint8 tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   .   .   ADDR PTR-*uint8 tc(1) # keccakfast.go:28:68 hashes.go:71:46
.   .   .   .   .   .   .   GOTO fast..i0 tc(1) # keccakfast.go:28:68
.   .   .   .   .   .   LABEL fast..i0 # keccakfast.go:28:68
.   .   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack hash.Hash tc(1) # keccakfast.go:28:68 hashes.go:71:27
.   .   DCL # keccakfast.go:28:44
.   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3262:21
.   .   AS tc(1) # keccakfast.go:28:44
.   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3262:21
.   .   INLMARK Index:1 # +keccakfast.go:28:44
.   INLCALL reflect.Value tc(1) # keccakfast.go:28:44
.   .   IF tc(1) # keccakfast.go:28:44 value.go:3263:2
.   .   .   EQ bool tc(1) # keccakfast.go:28:44 value.go:3263:7
.   .   .   .   NAME-reflect.i Class:PAUTO Offset:0 InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3262:14
.   .   .   .   NIL any tc(1) # keccakfast.go:28:44 value.go:3263:10
.   .   .   BLOCK tc(1) # keccakfast.go:28:44
.   .   .   .   AS2 tc(1) # keccakfast.go:28:44
.   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3262:21
.   .   .   .   .   STRUCTLIT reflect.Value tc(1) # keccakfast.go:28:44 value.go:3264:15
.   .   .   .   GOTO fast..i1 tc(1) # keccakfast.go:28:44
.   .   BLOCK tc(1) # keccakfast.go:28:44
.   .   .   AS2 tc(1) # keccakfast.go:28:44
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3262:21
.   .   .   .   CALLFUNC reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   .   .   NAME-reflect.i Class:PAUTO Offset:0 InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3262:14
.   .   .   GOTO fast..i1 tc(1) # keccakfast.go:28:44
.   .   LABEL fast..i1 # keccakfast.go:28:44
.   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3262:21
./keccakfast.go:28:44: inlining call to reflect.unpackEface
./keccakfast.go:28:44: Before inlining: 
.   CALLFUNC reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   NAME-reflect.i Class:PAUTO Offset:0 InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3262:14
./keccakfast.go:28:44: After inlining 
.   .   .   DCL # keccakfast.go:28:44 value.go:3266:20
.   .   .   .   NAME-reflect.i Class:PAUTO Offset:0 Addrtaken InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:18
.   .   AS2 Def tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   NAME-reflect.i Class:PAUTO Offset:0 Addrtaken InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:18
.   .   .   NAME-reflect.i Class:PAUTO Offset:0 InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3262:14
.   .   DCL # keccakfast.go:28:44 value.go:3266:20
.   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:25
.   .   AS tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:25
.   .   INLMARK Index:2 # +keccakfast.go:28:44 value.go:3266:20
.   INLCALL reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   DCL # keccakfast.go:28:44 value.go:3266:20 value.go:155:2
.   .   .   .   NAME-reflect.e Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.EmptyInterface tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:2
.   .   AS Def tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:4
.   .   .   NAME-reflect.e Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.EmptyInterface tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:2
.   .   .   CONVNOP PTR-*abi.EmptyInterface tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:43
.   .   .   .   CONVNOP UNSAFEPTR-unsafe.Pointer tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:44
.   .   .   .   .   ADDR PTR-*any tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:44
.   .   .   .   .   .   NAME-reflect.i Class:PAUTO Offset:0 Addrtaken InlFormal OnStack Used any tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:18
.   .   .   DCL # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   AS Def tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:4
.   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   .   DOTPTR fast.Type PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:8
.   .   .   .   NAME-reflect.e Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.EmptyInterface tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:2
.   .   IF tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:158:2
.   .   .   EQ bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:158:7
.   .   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   .   .   NIL PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:158:10
.   .   .   BLOCK tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   .   AS2 tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:25
.   .   .   .   .   STRUCTLIT reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:159:15
.   .   .   .   GOTO fast..i2 tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   DCL # keccakfast.go:28:44 value.go:3266:20 value.go:161:2
.   .   .   .   NAME-reflect.f Class:PAUTO Offset:0 InlLocal OnStack Used reflect.flag tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:2
.   .   AS Def tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:4
.   .   .   NAME-reflect.f Class:PAUTO Offset:0 InlLocal OnStack Used reflect.flag tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:2
.   .   .   CONV reflect.flag tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   .   CALLFUNC abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   .   .   METHEXPR fast.Kind FUNC-func(*abi.Type) abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:13
.   .   .   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   IF tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:2
.   .   .   CALLFUNC bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   .   .   METHEXPR fast.IfaceIndir FUNC-func(*abi.Type) bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:6
.   .   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   .   ASOP-OR AsOp:OR tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:163:5
.   .   .   .   NAME-reflect.f Class:PAUTO Offset:0 InlLocal OnStack Used reflect.flag tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:2
.   .   .   .   LITERAL-128 reflect.flag tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:163:8
.   .   BLOCK tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   AS2 tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:25
.   .   .   .   STRUCTLIT reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:165:14
.   .   .   .   .   STRUCTKEY reflect.typ_ # keccakfast.go:28:44 value.go:3266:20 value.go:165:15
.   .   .   .   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   .   .   .   STRUCTKEY reflect.ptr # keccakfast.go:28:44 value.go:3266:20 value.go:165:19
.   .   .   .   .   .   DOTPTR fast.Data UNSAFEPTR-unsafe.Pointer tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:165:19
.   .   .   .   .   .   .   NAME-reflect.e Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.EmptyInterface tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:155:2
.   .   .   .   .   STRUCTKEY reflect.flag # keccakfast.go:28:44 value.go:3266:20 value.go:165:26
.   .   .   .   .   .   NAME-reflect.f Class:PAUTO Offset:0 InlLocal OnStack Used reflect.flag tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:2
.   .   .   GOTO fast..i2 tc(1) # keccakfast.go:28:44 value.go:3266:20
.   .   LABEL fast..i2 # keccakfast.go:28:44 value.go:3266:20
.   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack reflect.Value tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:154:25
./keccakfast.go:28:44: inlining call to abi.(*Type).Kind
./keccakfast.go:28:44: Before inlining: 
.   CALLFUNC abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   METHEXPR fast.Kind FUNC-func(*abi.Type) abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:13
.   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
./keccakfast.go:28:44: After inlining 
.   .   .   DCL # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   .   NAME-abi.t Class:PAUTO Offset:0 InlFormal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:7
.   .   AS2 Def tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   NAME-abi.t Class:PAUTO Offset:0 InlFormal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:7
.   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   INLMARK Index:3 # +keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   INLCALL abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   BLOCK tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   DCL tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:23
.   .   .   AS2 tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:23
.   .   .   .   AND abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:45
.   .   .   .   .   DOTPTR fast.Kind_ abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:38
.   .   .   .   .   .   NAME-abi.t Class:PAUTO Offset:0 InlFormal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:7
.   .   .   .   .   LITERAL-31 abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:47
.   .   .   GOTO fast..i3 tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   LABEL fast..i3 # keccakfast.go:28:44 value.go:3266:20 value.go:161:18
.   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:161:18 type.go:189:23
./keccakfast.go:28:44: inlining call to abi.(*Type).IfaceIndir
./keccakfast.go:28:44: Before inlining: 
.   CALLFUNC bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   METHEXPR fast.IfaceIndir FUNC-func(*abi.Type) bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:6
.   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
./keccakfast.go:28:44: After inlining 
.   .   .   DCL # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   .   .   NAME-abi.t Class:PAUTO Offset:0 InlFormal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:199:7
.   .   AS2 Def tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   .   NAME-abi.t Class:PAUTO Offset:0 InlFormal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:199:7
.   .   .   NAME-reflect.t Class:PAUTO Offset:0 InlLocal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:157:2
.   .   INLMARK Index:4 # +keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   INLCALL bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   BLOCK tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   .   DCL tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:199:29
.   .   .   AS2 tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   .   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:199:29
.   .   .   .   EQ bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:200:33
.   .   .   .   .   AND abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:200:16
.   .   .   .   .   .   DOTPTR fast.Kind_ abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:200:10
.   .   .   .   .   .   .   NAME-abi.t Class:PAUTO Offset:0 InlFormal OnStack Used PTR-*abi.Type tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:199:7
.   .   .   .   .   .   LITERAL-32 abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:200:17
.   .   .   .   .   LITERAL-0 abi.Kind tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:200:36
.   .   .   GOTO fast..i4 tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   LABEL fast..i4 # keccakfast.go:28:44 value.go:3266:20 value.go:162:17
.   .   NAME-fast.~r0 Class:PAUTO Offset:0 InlFormal OnStack bool tc(1) # keccakfast.go:28:44 value.go:3266:20 value.go:162:17 type.go:199:29
./keccakfast.go:17:18: st does not escape
./keccakfast.go:21:18: st does not escape
./keccakfast.go:21:35: p does not escape
./keccakfast.go:25:17: st does not escape
./keccakfast.go:25:34: out does not escape
./keccakfast.go:31:13:[1] hashPair stmt: keccakReset(hasher)
./keccakfast.go:32:7:[1] hashPair stmt: _, _ = int(.autotmp_3), .autotmp_4
./keccakfast.go:32:7:[1] hashPair stmt: .autotmp_3, .autotmp_4 := keccakWrite(hasher, left[:])
./keccakfast.go:32:7:[1] hashPair stmt: var .autotmp_3 int
./keccakfast.go:32:7:[1] hashPair stmt: var .autotmp_4 error
./keccakfast.go:33:7:[1] hashPair stmt: _, _ = int(.autotmp_5), .autotmp_6
./keccakfast.go:33:7:[1] hashPair stmt: .autotmp_5, .autotmp_6 := keccakWrite(hasher, right[:])
./keccakfast.go:33:7:[1] hashPair stmt: var .autotmp_5 int
./keccakfast.go:33:7:[1] hashPair stmt: var .autotmp_6 error
./keccakfast.go:34:7:[1] hashPair stmt: _, _ = int(.autotmp_7), .autotmp_8
./keccakfast.go:34:7:[1] hashPair stmt: .autotmp_7, .autotmp_8 := keccakRead(hasher, out[:])
./keccakfast.go:34:7:[1] hashPair stmt: var .autotmp_7 int
./keccakfast.go:34:7:[1] hashPair stmt: var .autotmp_8 error
./keccakfast.go:35:2:[1] hashPair stmt: return 
./keccakfast.go:28:5:[1] init stmt: hasher = (*keccakState)(reflect.Value.UnsafePointer(~r0))
./keccakfast.go:28:44:[1] init stmt: reflect.i := ~r0
./keccakfast.go:28:44:[1] init stmt: var reflect.i any
./keccakfast.go:28:68:[1] init stmt:  := 
./keccakfast.go:28:68:[1] init stmt: <node inlmark>
./keccakfast.go:28:68:[1] init stmt: var ~r0 hash.Hash; ~r0 = &sha3.state{...}; goto .i0
./keccakfast.go:28:68:[1] init stmt: var ~r0 hash.Hash
./keccakfast.go:28:68:[1] init stmt: ~r0 = &sha3.state{...}
./keccakfast.go:28:68:[1] init stmt: goto .i0
./keccakfast.go:28:68:[1] init stmt: .i0: 
./keccakfast.go:28:68:.i0:  non-looping label
./keccakfast.go:28:44:[1] init stmt: var ~r0 reflect.Value
./keccakfast.go:28:44:[1] init stmt: ~r0 = <nil>
./keccakfast.go:28:44:[1] init stmt: <node inlmark>
./keccakfast.go:28:44:[1] init stmt: if reflect.i == nil { ~r0 = reflect.Value{}; goto .i1 }
./keccakfast.go:28:44:[1] init stmt: ~r0 = reflect.Value{}; goto .i1
./keccakfast.go:28:44:[1] init stmt: ~r0 = reflect.Value{}
./keccakfast.go:28:44:[1] init stmt: goto .i1
./keccakfast.go:28:44:[1] init stmt: ~r0 = ~r0; goto .i1
./keccakfast.go:28:44:[1] init stmt: ~r0 = ~r0
./keccakfast.go:28:44:[1] init stmt: reflect.i := reflect.i
./keccakfast.go:28:44:[1] init stmt: var reflect.i any
./keccakfast.go:28:44:[1] init stmt: var ~r0 reflect.Value
./keccakfast.go:28:44:[1] init stmt: ~r0 = <nil>
./keccakfast.go:28:44:[1] init stmt: <node inlmark>
./keccakfast.go:28:44:[1] init stmt: reflect.e := (*abi.EmptyInterface)(unsafe.Pointer(&reflect.i))
./keccakfast.go:28:44:[1] init stmt: var reflect.e *abi.EmptyInterface
./keccakfast.go:28:44:[1] init stmt: reflect.t := reflect.e.Type
./keccakfast.go:28:44:[1] init stmt: var reflect.t *abi.Type
./keccakfast.go:28:44:[1] init stmt: if reflect.t == nil { ~r0 = reflect.Value{}; goto .i2 }
./keccakfast.go:28:44:[1] init stmt: ~r0 = reflect.Value{}; goto .i2
./keccakfast.go:28:44:[1] init stmt: ~r0 = reflect.Value{}
./keccakfast.go:28:44:[1] init stmt: goto .i2
./keccakfast.go:28:44:[1] init stmt: reflect.f := reflect.flag(~r0)
./keccakfast.go:28:44:[1] init stmt: var reflect.f reflect.flag
./keccakfast.go:28:44:[1] init stmt: abi.t := reflect.t
./keccakfast.go:28:44:[1] init stmt: var abi.t *abi.Type
./keccakfast.go:28:44:[1] init stmt: <node inlmark>
./keccakfast.go:28:44:[1] init stmt: var ~r0 abi.Kind; ~r0 = abi.t.Kind_ & abi.Kind(31); goto .i3
./keccakfast.go:28:44:[1] init stmt: var ~r0 abi.Kind
./keccakfast.go:28:44:[1] init stmt: ~r0 = abi.t.Kind_ & abi.Kind(31)
./keccakfast.go:28:44:[1] init stmt: goto .i3
./keccakfast.go:28:44:[1] init stmt: .i3: 
./keccakfast.go:28:44:.i3:  non-looping label
./keccakfast.go:28:44:[1] init stmt: if ~r0 { reflect.f |= reflect.flag(128) }
./keccakfast.go:28:44:[1] init stmt: abi.t := reflect.t
./keccakfast.go:28:44:[1] init stmt: var abi.t *abi.Type
./keccakfast.go:28:44:[1] init stmt: <node inlmark>
./keccakfast.go:28:44:[1] init stmt: var ~r0 bool; ~r0 = abi.t.Kind_ & abi.Kind(32) == abi.Kind(0); goto .i4
./keccakfast.go:28:44:[1] init stmt: var ~r0 bool
./keccakfast.go:28:44:[1] init stmt: ~r0 = abi.t.Kind_ & abi.Kind(32) == abi.Kind(0)
./keccakfast.go:28:44:[1] init stmt: goto .i4
./keccakfast.go:28:44:[1] init stmt: .i4: 
./keccakfast.go:28:44:.i4:  non-looping label
./keccakfast.go:28:44:[1] init stmt: reflect.f |= reflect.flag(128)
./keccakfast.go:28:44:[1] init stmt: ~r0 = reflect.Value{...}; goto .i2
./keccakfast.go:28:44:[1] init stmt: ~r0 = reflect.Value{...}
./keccakfast.go:28:44:[1] init stmt: goto .i2
./keccakfast.go:28:44:[1] init stmt: .i2: 
./keccakfast.go:28:44:.i2:  non-looping label
./keccakfast.go:28:44:[1] init stmt: goto .i1
./keccakfast.go:28:44:[1] init stmt: .i1: 
./keccakfast.go:28:44:.i1:  non-looping label
./keccakfast.go:28:68: &sha3.state{...} escapes to heap:
./keccakfast.go:28:68:   flow: ~r0 = &{storage for &sha3.state{...}}:
./keccakfast.go:28:68:     from &sha3.state{...} (spill) at ./keccakfast.go:28:68
./keccakfast.go:28:68:     from &sha3.state{...} (interface-converted) at ./keccakfast.go:28:68
./keccakfast.go:28:68:     from ~r0 = &sha3.state{...} (assign-pair) at ./keccakfast.go:28:68
./keccakfast.go:28:68:   flow: reflect.i = ~r0:
./keccakfast.go:28:68:     from ~r0 (interface-converted) at ./keccakfast.go:28:68
./keccakfast.go:28:68:     from reflect.i := ~r0 (assign-pair) at ./keccakfast.go:28:44
./keccakfast.go:28:68:   flow: reflect.i = reflect.i:
./keccakfast.go:28:68:     from reflect.i := reflect.i (assign-pair) at ./keccakfast.go:28:44
./keccakfast.go:28:68:   flow: reflect.e = &reflect.i:
./keccakfast.go:28:68:     from &reflect.i (address-of) at ./keccakfast.go:28:44
./keccakfast.go:28:68:     from reflect.e := (*abi.EmptyInterface)(unsafe.Pointer(&reflect.i)) (assign) at ./keccakfast.go:28:44
./keccakfast.go:28:68:   flow: ~r0 = *reflect.e:
./keccakfast.go:28:68:     from reflect.e.Data (dot of pointer) at ./keccakfast.go:28:44
./keccakfast.go:28:68:     from reflect.Value{...} (struct literal element) at ./keccakfast.go:28:44
./keccakfast.go:28:68:     from ~r0 = reflect.Value{...} (assign-pair) at ./keccakfast.go:28:44
./keccakfast.go:28:68:   flow: ~r0 = ~r0:
./keccakfast.go:28:68:     from ~r0 = ~r0 (assign-pair) at ./keccakfast.go:28:44
./keccakfast.go:28:68:   flow: {heap} = ~r0:
./keccakfast.go:28:68:     from reflect.Value.UnsafePointer(~r0) (call parameter) at ./keccakfast.go:28:85
./keccakfast.go:28:68:     from hasher = (*keccakState)(reflect.Value.UnsafePointer(~r0)) (assign) at ./keccakfast.go:28:5
./keccakfast.go:28:68: &sha3.state{...} escapes to heap
./keccakfast.go:39:13:[1] hash stmt: keccakReset(hasher)
./keccakfast.go:40:7:[1] hash stmt: _, _ = int(.autotmp_2), .autotmp_3
./keccakfast.go:40:7:[1] hash stmt: .autotmp_2, .autotmp_3 := keccakWrite(hasher, data[:])
./keccakfast.go:40:7:[1] hash stmt: var .autotmp_2 int
./keccakfast.go:40:7:[1] hash stmt: var .autotmp_3 error
./keccakfast.go:41:7:[1] hash stmt: _, _ = int(.autotmp_4), .autotmp_5
./keccakfast.go:41:7:[1] hash stmt: .autotmp_4, .autotmp_5 := keccakRead(hasher, out[:])
./keccakfast.go:41:7:[1] hash stmt: var .autotmp_4 int
./keccakfast.go:41:7:[1] hash stmt: var .autotmp_5 error
./keccakfast.go:42:2:[1] hash stmt: return 

Thought I'd share this little experiment and the results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant