-
Notifications
You must be signed in to change notification settings - Fork 15
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
Implement one shot SHA and reduce allocs #24
Conversation
// compiles down to zero instructions. | ||
// USE CAREFULLY! | ||
//go:nosplit | ||
func noescape(p unsafe.Pointer) unsafe.Pointer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand what impact this has on the program? I believe the intent is to trick the Go compiler into thinking a pointer cannot escape when it reality it does. What benefit does that end up having though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I read up a bit about this. Escape logic impacts cgo in the sense that it's important that pointers which are passed to C and are stored there need to be allocated on the heap. If they are allocated on the stack then that creates a memory hole. The default of cgo is to ensure all pointers are marked as escaping so they get pushed to the heap (based on the Russ change). This is reasonable because it's the safest default.
The noescape
function is then used to trick the cgo tooling. Basically and "I know better, this isn't stored" escape hatch for developers
This is my reading of it at least
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the same sense based on golang/go#10303.
golang/go#24450 also points out that even though cgo has some strict-seeming pointer passing prerequisites, it's still not always easy to identify when it's safe to noescape. (If the C function calls back into Go, Go might rearrange the stack, so even having a pointer to something in the Go stack in a C parameter or local variable can turn out badly.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To the best of my knowledge, OpenSSL is not storing the few pointers we are passing as noescape
, so it is safe to trick cgo tooling.
I've found something good: So there are only three remaining usages of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, a few questions/suggestions.
This PR contains two performance improvements which landed into
dev.boringbranch
during this development cycle, both committed in https://go-review.googlesource.com/c/go/+/395876/11.NewSha1
and friends, as these functions return a pointer which normally escapes in the caller side.The benchmarks demonstrates that the new code does not allocate:
Removing the SHA allocations is important for when openssl is integrated into go1.19, else we would have to disable a new test that checks boring SHAs don't allocate.