-
Notifications
You must be signed in to change notification settings - Fork 18k
reflect: add func (Value) UnsafePointer() unsafe.Pointer #40592
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
Comments
My recollection is that one of the reasons that
from giving (This also gets us to a discussion about type based alias analysis. In ordinary Go code a pointer to |
Re type-based alias analysis: even if the package does not import So I think if we want to do any deep reasoning about aliasing we would generally need whole-program analysis either way. |
Yes, that reason was justifiable back when Go supported "safe" mode, but we removed that back in 2018. There are many better ways to run untrusted Go programs today (e.g., within a process sandbox like gVisor or by compiling them to wasm).
This seems like an orthogonal concern to me. The only way to safely use |
It's somewhat orthogonal but perhaps not entirely negligible: see #26070. |
I don't see any mention of type-based alias analysis in #26070. Can you elaborate on how they're related? |
The connection I see here is what should happen when people write Perhaps this concern is not important. |
I see. I wrote "This seems like an orthogonal concern to me," with "this" referring to type-based alias analysis. When you wrote "It's somewhat orthogonal," I thought you were still talking about type-based alias analysis too. Assuming both #26070 and this proposal were accepted, I expect users would adapt by writing |
#26070 was retracted.
(2) is no longer a concern, and (1) seems well enough handled by the name v.UnsafePointer, which seems just as clearly "unsafe" as So overall this seems like a fine change. It might be worth thinking about for Go 1.17 along with the other unsafe/pointer cleanup. |
Based on the discussion above, this seems like a likely accept (for Go 1.17). |
No change in consensus, so accepted. |
I'm not so sure about this. I've spent some time optimising a reflect based encoder. Starting with a per-field loop
I ended up with 22% of CPU time on a moderately simple benchmark spent in I decided to try and optimize it using (as a first pass)
The result was... 33% of CPU time being spent in This is probably not a big deal in the grand scheme of things; the overhead is only really notable because I've spent a bunch of effort optimizing other aspects (and I have ways of working around it in the general case), and there's still optimizations which can be done to avoid the reflect overhead in many cases, but it makes these kinds of optimizations a bit trickier (in that you're more likely to bump into situations where you've accidentally made things slower) So if I were to make a couple of requests, they'd be:
|
Change https://golang.org/cl/350691 mentions this issue: |
Change https://golang.org/cl/356252 mentions this issue: |
Updates #40592 Change-Id: I16252dd57aceb5c49ddc11d8c12c601ca87ca902 Reviewed-on: https://go-review.googlesource.com/c/go/+/356252 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Change https://golang.org/cl/356255 mentions this issue: |
Updates #40592 Change-Id: If66629e47ca9859128ee3ad8fb584e022d7a6982 Reviewed-on: https://go-review.googlesource.com/c/go/+/356255 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
Change https://golang.org/cl/360855 mentions this issue: |
The latter returns a uintptr, while the former returns a unsafe.Pointer. A uintptr is unsafe if Go ever switches to a moving GC, while a unsafe.Pointer will be properly tracked by the GC. We do not use unsafe.Pointer for any unsafe type conversions, and only use it for comparability purposes, which is relatively safe. Updates #40592 Change-Id: I813e218668704b63a3043acda4331205a3835a66 Reviewed-on: https://go-review.googlesource.com/c/go/+/360855 Trust: Joseph Tsai <joetsai@digital-static.net> Trust: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Joseph Tsai <joetsai@digital-static.net> TryBot-Result: Gopher Robot <gobot@golang.org>
[Splitting out separately from my comment on #40481, per @rsc's suggestion.]
This proposal is to add a method
This would allow callers to migrate from
Value.Addr
andValue.Pointer
so that the later could be deprecated (fulfilling their TODOs [1], [2]), and eliminating a class of possible misuse ofunsafe.Pointer
.Optionally, we can then also have
go fix
rewrite:unsafe.Pointer(v.Pointer())
->v.UnsafePointer()
unsafe.Pointer(v.UnsafeAddr())
->v.Addr().UnsafePointer()
v.Pointer()
->uintptr(v.UnsafePointer())
v.UnsafeAddr()
->uintptr(v.Addr().UnsafePointer())
Replacing
v.UnsafeAddr()
withv.Addr().UnsafePointer()
has a slight added costv.UnsafeAddr()
was able to simply directly return the address pointer, whileAddr()
potentially has to compute the resulting pointer's type. However,(*rtype).ptrTo
already uses caching, and the compiler also already eagerly generates*T
types for most types, so I expect in practice this to have negligible overhead.--
Tangentially, the
InterfaceData
method also has a TODO to deprecate. I don't think there's anything preventing this from being deprecated today. Callers should probably just useElem()
to get aValue
representing the concrete value, and then do something based on itsKind()
.Within Google's internal Go code base, the only two uses of
reflect.Value.InterfaceData
appear to be:https://github.com/hashicorp/terraform/blob/master/dag/marshal.go#L205, which looks like dead code anyway:
reflect.ValueOf(...).Kind()
never returnsreflect.Interface
.https://fuchsia.googlesource.com/fuchsia.git/+/refs/heads/master/src/connectivity/network/netstack/socket_encode.go#41, which needs to be fixed anyway since it's using
reflect.SliceHeader
incorrectly too.The text was updated successfully, but these errors were encountered: