diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index ea63883..5a3ff87 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -101,6 +101,7 @@
package runtime
import (
+ "internal/abi"
"internal/goarch"
"internal/goexperiment"
"internal/goos"
@@ -2040,6 +2041,41 @@
return true
}
+// freeSlice records that the backing array for a slice is reusable and
+// available for immediate reuse in a subsequent mallocgc allocation.
+// It is a convenience wrapper function over freeSized.
+//
+// sl must contain a pointer to a slice (that is, *[]T). sl is an
+// interface to aid with finding the type.
+//
+// The slice data pointer must point to the base of the heap object (that is,
+// not resliced to the middle of the heap object). See freeSized
+// for additional requirements.
+func freeSlice(sl any) {
+ i := efaceOf(&sl)
+
+ capacity := (*slice)(i.data).cap
+ if capacity == 0 {
+ return
+ }
+
+ // Find the slice element type.
+ typ := (*_type)(abi.NoEscape(unsafe.Pointer(i._type))) // runtime types are never freed
+ if typ.Kind_&abi.KindMask != abi.Pointer {
+ throw("slice result of non-ptr type")
+ }
+ typ = (*ptrtype)(unsafe.Pointer(typ)).Elem
+ if typ.Kind_&abi.KindMask != abi.Slice {
+ throw("slice of non-ptr-to-slice type")
+ }
+ typ = (*slicetype)(unsafe.Pointer(typ)).Elem // slice element type
+
+ // Free the backing array.
+ noscan := !typ.Pointers()
+ freeSized((*slice)(i.data).array, uintptr(capacity)*typ.Size_, noscan)
+ *((*slice)(i.data)) = slice{}
+}
+
// nextReusableNoScan returns the next reusable object for a noscan span,
// or 0 if no reusable object is found.
func (c *mcache) nextReusableNoScan(s *mspan, spc spanClass) (gclinkptr, *mspan) {
@@ -2299,6 +2335,16 @@
return freeSized(p, size, noscan)
}
+//go:linkname slices_freeSized slices.runtimefreesized
+func slices_freeSized(p unsafe.Pointer, size uintptr, noscan bool) bool {
+ return freeSized(p, size, noscan)
+}
+
+//go:linkname slices_freeSlice slices.runtimefreeslice
+func slices_freeSlice(sl any) {
+ freeSlice(sl)
+}
+
// reflect_unsafe_New is meant for package reflect,
// but widely used packages access it using linkname.
// Notable members of the hall of shame include: