]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: create funcTypes using StructOf
authorcuiweixie <cuiweixie@gmail.com>
Wed, 24 Aug 2022 14:00:45 +0000 (22:00 +0800)
committerGopher Robot <gobot@golang.org>
Mon, 26 Sep 2022 21:39:25 +0000 (21:39 +0000)
follow the TODO to use StructOf, this cl can save the used memory.
for example, old code alloc [128]*rtype for func with 65 arguments(in+out),
this cl change to alloc [65]*rtype to save memory.

Change-Id: I1494bb6b3524d0d46869c3f24a628fec88119d8b
Reviewed-on: https://go-review.googlesource.com/c/go/+/425314
Run-TryBot: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
src/reflect/type.go

index 984091ffc4b443540c8611fe05a4034b780d1238..13fa725a22ebbba08d0906bca3cbae3aeaf36f22 100644 (file)
@@ -1999,31 +1999,32 @@ func MapOf(key, elem Type) Type {
        return ti.(Type)
 }
 
-// TODO(crawshaw): as these funcTypeFixedN structs have no methods,
-// they could be defined at runtime using the StructOf function.
-type funcTypeFixed4 struct {
-       funcType
-       args [4]*rtype
-}
-type funcTypeFixed8 struct {
-       funcType
-       args [8]*rtype
-}
-type funcTypeFixed16 struct {
-       funcType
-       args [16]*rtype
-}
-type funcTypeFixed32 struct {
-       funcType
-       args [32]*rtype
-}
-type funcTypeFixed64 struct {
-       funcType
-       args [64]*rtype
-}
-type funcTypeFixed128 struct {
-       funcType
-       args [128]*rtype
+var funcTypes []Type
+var funcTypesMutex sync.Mutex
+
+func initFuncTypes(n int) {
+       funcTypesMutex.Lock()
+       defer funcTypesMutex.Unlock()
+       if n < len(funcTypes) {
+               if funcTypes[n] != nil {
+                       return
+               }
+       } else {
+               newFuncTypes := make([]Type, n+1)
+               copy(newFuncTypes, funcTypes)
+               funcTypes = newFuncTypes
+       }
+
+       funcTypes[n] = StructOf([]StructField{
+               {
+                       Name: "FuncType",
+                       Type: TypeOf(funcType{}),
+               },
+               {
+                       Name: "Args",
+                       Type: ArrayOf(n, TypeOf(&rtype{})),
+               },
+       })
 }
 
 // FuncOf returns the function type with the given argument and result types.
@@ -2045,34 +2046,15 @@ func FuncOf(in, out []Type, variadic bool) Type {
 
        var ft *funcType
        var args []*rtype
-       switch {
-       case n <= 4:
-               fixed := new(funcTypeFixed4)
-               args = fixed.args[:0:len(fixed.args)]
-               ft = &fixed.funcType
-       case n <= 8:
-               fixed := new(funcTypeFixed8)
-               args = fixed.args[:0:len(fixed.args)]
-               ft = &fixed.funcType
-       case n <= 16:
-               fixed := new(funcTypeFixed16)
-               args = fixed.args[:0:len(fixed.args)]
-               ft = &fixed.funcType
-       case n <= 32:
-               fixed := new(funcTypeFixed32)
-               args = fixed.args[:0:len(fixed.args)]
-               ft = &fixed.funcType
-       case n <= 64:
-               fixed := new(funcTypeFixed64)
-               args = fixed.args[:0:len(fixed.args)]
-               ft = &fixed.funcType
-       case n <= 128:
-               fixed := new(funcTypeFixed128)
-               args = fixed.args[:0:len(fixed.args)]
-               ft = &fixed.funcType
-       default:
+       if n <= 128 {
+               initFuncTypes(n)
+               o := New(funcTypes[n]).Elem()
+               ft = (*funcType)(unsafe.Pointer(o.Field(0).Addr().Pointer()))
+               args = unsafe.Slice((**rtype)(unsafe.Pointer(o.Field(1).Addr().Pointer())), n)[0:0:n]
+       } else {
                panic("reflect.FuncOf: too many arguments")
        }
+
        *ft = *prototype
 
        // Build a hash and minimally populate ft.