if t.Sym == nil && len(methods(t)) == 0 {
return 0
}
- return 4 + 2 + 2
+ return 4 + 2 + 2 + 4 + 4
}
func makefield(name string, t *Type) *Field {
ot = dgopkgpathOffLSym(Linksym(s), ot, typePkg(t))
- dataAdd += 4 + 2 + 2
+ dataAdd += uncommonSize(t)
mcount := len(m)
if mcount != int(uint16(mcount)) {
Fatalf("too many methods on %s: %d", t, mcount)
}
- if dataAdd != int(uint16(dataAdd)) {
+ if dataAdd != int(uint32(dataAdd)) {
Fatalf("methods are too far away on %s: %d", t, dataAdd)
}
ot = duint16(s, ot, uint16(mcount))
- ot = duint16(s, ot, uint16(dataAdd))
+ ot = duint16(s, ot, 0)
+ ot = duint32(s, ot, uint32(dataAdd))
+ ot = duint32(s, ot, 0)
return ot
}
func commonsize() int { return 4*SysArch.PtrSize + 8 + 8 } // runtime._type
func structfieldSize() int { return 3 * SysArch.PtrSize } // runtime.structfield
-func uncommonSize() int { return 4 + 2 + 2 } // runtime.uncommontype
+func uncommonSize() int { return 4 + 2 + 2 + 4 + 4 } // runtime.uncommontype
// Type.commonType.kind
func decodetype_kind(s *LSym) uint8 {
}
mcount := int(decode_inuxi(s.P[off+4:], 2))
- moff := int(decode_inuxi(s.P[off+4+2:], 2))
+ moff := int(decode_inuxi(s.P[off+4+2+2:], 4))
off += moff // offset to array of reflect.method values
const sizeofMethod = 4 * 4 // sizeof reflect.method in program
return decode_methodsig(s, off, sizeofMethod, mcount)
type uncommonType struct {
pkgPath nameOff // import path; empty for built-in types like int, string
mcount uint16 // number of methods
- moff uint16 // offset from this uncommontype to [mcount]method
+ _ uint16 // unused
+ moff uint32 // offset from this uncommontype to [mcount]method
+ _ uint32 // unused
}
// ChanDir represents a channel type's direction.
panic("reflect.StructOf: too many methods")
}
ut.mcount = uint16(len(methods))
- ut.moff = uint16(unsafe.Sizeof(uncommonType{}))
+ ut.moff = uint32(unsafe.Sizeof(uncommonType{}))
if len(fs) > 0 {
repr = append(repr, ' ')
type uncommontype struct {
pkgpath nameOff
mcount uint16 // number of methods
- moff uint16 // offset from this uncommontype to [mcount]method
+ _ uint16 // unused
+ moff uint32 // offset from this uncommontype to [mcount]method
+ _ uint32 // unused
}
type imethod struct {
--- /dev/null
+// +build !nacl,!android
+// run
+
+// Copyright 2016 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 main
+
+import (
+ "bytes"
+ "fmt"
+ "html/template"
+ "io/ioutil"
+ "log"
+ "os"
+ "os/exec"
+ "path/filepath"
+)
+
+var tmpl = template.Must(template.New("main").Parse(`
+package main
+
+type T struct {
+ {{range .Names}}
+ {{.Name}} *string
+ {{end}}
+}
+
+{{range .Names}}
+func (t *T) Get{{.Name}}() string {
+ if t.{{.Name}} == nil {
+ return ""
+ }
+ return *t.{{.Name}}
+}
+{{end}}
+
+func main() {}
+`))
+
+func main() {
+ const n = 5000
+
+ type Name struct{ Name string }
+ var t struct{ Names []Name }
+ for i := 0; i < n; i++ {
+ t.Names = append(t.Names, Name{Name: fmt.Sprintf("H%06X", i)})
+ }
+
+ buf := new(bytes.Buffer)
+ if err := tmpl.Execute(buf, t); err != nil {
+ log.Fatal(err)
+ }
+
+ dir, err := ioutil.TempDir("", "issue16037-")
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer os.RemoveAll(dir)
+ path := filepath.Join(dir, "ridiculous_number_of_fields.go")
+ if err := ioutil.WriteFile(path, buf.Bytes(), 0664); err != nil {
+ log.Fatal(err)
+ }
+
+ out, err := exec.Command("go", "build", "-o="+filepath.Join(dir, "out"), path).CombinedOutput()
+ if err != nil {
+ log.Fatalf("build failed: %v\n%s", err, out)
+ }
+}