-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
weak: move internal/weak to weak, and update according to proposal
The updates are: - API documentation changes. - Removal of the old package documentation discouraging linkname. - Addition of new package documentation with some advice. - Renaming of weak.Pointer.Strong -> weak.Pointer.Value. Fixes #67552. Change-Id: Ifad7e629b6d339dacaf2ca37b459d7f903e31bf8 Reviewed-on: https://go-review.googlesource.com/c/go/+/628455 LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Carlos Amedee <[email protected]> Auto-Submit: Michael Knyszek <[email protected]>
- Loading branch information
Showing
15 changed files
with
129 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pkg weak, func Make[$0 interface{}](*$0) Pointer[$0] #67552 | ||
pkg weak, method (Pointer[$0]) Value() *$0 #67552 | ||
pkg weak, type Pointer[$0 interface{}] struct #67552 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
### New weak package | ||
|
||
The new [weak](/pkg/weak) package provides weak pointers. | ||
|
||
Weak pointers are a low-level primitive provided to enable the | ||
creation of memory-efficient structures, such as weak maps for | ||
associating values, canonicalization maps for anything not | ||
covered by package [unique](/pkg/unique), and various kinds | ||
of caches. | ||
For supporting these use-cases, this release also provides | ||
[runtime.AddCleanup](/pkg/runtime#AddCleanup) and | ||
[maphash.Comparable](/pkg/maphash#Comparable). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
<!-- This is a new package; covered in 6-stdlib/1-weak.md. --> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
/* | ||
Package weak provides weak pointers with the goal of memory efficiency. | ||
The primary use-cases for weak pointers are for implementing caches, | ||
canonicalization maps (like the unique package), and for tying together | ||
the lifetimes of separate values. | ||
## Advice | ||
This package is intended to target niche use-cases like the unique | ||
package, not as a general replacement for regular Go pointers, maps, | ||
etc. | ||
Misuse of the structures in this package will generate unexpected and | ||
hard-to-reproduce bugs. | ||
Using the facilities in this package to try and resolve out-of-memory | ||
issues and/or memory leaks is very likely the wrong answer. | ||
The structures in this package are intended to be an implementation | ||
detail of the package they are used by (again, see the unique package). | ||
Avoid exposing weak structures across API boundaries, since that exposes | ||
users of your package to the subtleties of this package. | ||
*/ | ||
package weak |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package weak | ||
|
||
import ( | ||
"internal/abi" | ||
"runtime" | ||
"unsafe" | ||
) | ||
|
||
// Pointer is a weak pointer to a value of type T. | ||
// | ||
// Two Pointer values compare equal if the pointers | ||
// that they were created from compare equal. This property is retained even | ||
// after the object referenced by the pointer used to create a weak reference | ||
// is reclaimed. | ||
// | ||
// If multiple weak pointers are made to different offsets within same object | ||
// (for example, pointers to different fields of the same struct), those pointers | ||
// will not compare equal. | ||
// If a weak pointer is created from an object that becomes unreachable, but is | ||
// then resurrected due to a finalizer, that weak pointer will not compare equal | ||
// with weak pointers created after resurrection. | ||
// | ||
// Calling Make with a nil pointer returns a weak pointer whose Value method | ||
// always returns nil. The zero value of a Pointer behaves as if it was created | ||
// by passing nil to Make and compares equal with such pointers. | ||
type Pointer[T any] struct { | ||
u unsafe.Pointer | ||
} | ||
|
||
// Make creates a weak pointer from a strong pointer to some value of type T. | ||
func Make[T any](ptr *T) Pointer[T] { | ||
// Explicitly force ptr to escape to the heap. | ||
ptr = abi.Escape(ptr) | ||
|
||
var u unsafe.Pointer | ||
if ptr != nil { | ||
u = runtime_registerWeakPointer(unsafe.Pointer(ptr)) | ||
} | ||
runtime.KeepAlive(ptr) | ||
return Pointer[T]{u} | ||
} | ||
|
||
// Value returns the original pointer used to create the weak pointer. | ||
// It returns nil if the value pointed to by the original pointer was reclaimed by | ||
// the garbage collector. | ||
// If a weak pointer points to an object with a finalizer, then Value will | ||
// return nil as soon as the object's finalizer is queued for execution. | ||
func (p Pointer[T]) Value() *T { | ||
return (*T)(runtime_makeStrongFromWeak(p.u)) | ||
} | ||
|
||
// Implemented in runtime. | ||
|
||
//go:linkname runtime_registerWeakPointer | ||
func runtime_registerWeakPointer(unsafe.Pointer) unsafe.Pointer | ||
|
||
//go:linkname runtime_makeStrongFromWeak | ||
func runtime_makeStrongFromWeak(unsafe.Pointer) unsafe.Pointer |
Oops, something went wrong.