Commit df9eeb19 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

go/types: remove struct Sizeof cache

It was not responsive to the sizes param.
Remove it, and unwind the extra layers.

Fixes #16316

Change-Id: I940a57184a1601f52348d4bff8638f3f7462f5cd
Reviewed-on: https://go-review.googlesource.com/26995
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent 133d231a
......@@ -132,8 +132,8 @@ func (s *StdSizes) Sizeof(T Type) int64 {
if n == 0 {
return 0
}
setOffsets(t, s)
return t.offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
offsets := s.Offsetsof(t.fields)
return offsets[n-1] + s.Sizeof(t.fields[n-1].typ)
case *Interface:
return s.WordSize * 2
}
......@@ -158,22 +158,18 @@ func (conf *Config) offsetsof(T *Struct) []int64 {
if T.NumFields() > 0 {
// compute offsets on demand
if s := conf.Sizes; s != nil {
calculated := setOffsets(T, s)
offsets = T.offsets
if calculated {
// sanity checks
if len(offsets) != T.NumFields() {
panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
}
for _, o := range offsets {
if o < 0 {
panic("Config.Sizes.Offsetsof returned an offset < 0")
}
offsets := s.Offsetsof(T.fields)
// sanity checks
if len(offsets) != T.NumFields() {
panic("Config.Sizes.Offsetsof returned the wrong number of offsets")
}
for _, o := range offsets {
if o < 0 {
panic("Config.Sizes.Offsetsof returned an offset < 0")
}
}
} else {
setOffsets(T, &stdSizes)
offsets = T.offsets
offsets = stdSizes.Offsetsof(T.fields)
}
}
return offsets
......@@ -207,15 +203,3 @@ func align(x, a int64) int64 {
y := x + a - 1
return y - y%a
}
// setOffsets sets the offsets of s for the given sizes if necessary.
// The result is true if the offsets were not set before; otherwise it
// is false.
func setOffsets(s *Struct, sizes Sizes) bool {
var calculated bool
s.offsetsOnce.Do(func() {
calculated = true
s.offsets = sizes.Offsetsof(s.fields)
})
return calculated
}
// 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.
// This file contains tests for sizes.
package types_test
import (
"go/ast"
"go/parser"
"go/token"
"go/types"
"testing"
)
// findStructType typechecks src and returns the first struct type encountered.
func findStructType(t *testing.T, src string) *types.Struct {
fset := token.NewFileSet()
f, err := parser.ParseFile(fset, "x.go", src, 0)
if err != nil {
t.Fatal(err)
}
info := types.Info{Types: make(map[ast.Expr]types.TypeAndValue)}
var conf types.Config
_, err = conf.Check("x", fset, []*ast.File{f}, &info)
if err != nil {
t.Fatal(err)
}
for _, tv := range info.Types {
if ts, ok := tv.Type.(*types.Struct); ok {
return ts
}
}
t.Fatalf("failed to find a struct type in src:\n%s\n", src)
return nil
}
// Issue 16316
func TestMultipleSizeUse(t *testing.T) {
const src = `
package main
type S struct {
i int
b bool
s string
n int
}
`
ts := findStructType(t, src)
sizes := types.StdSizes{WordSize: 4, MaxAlign: 4}
if got := sizes.Sizeof(ts); got != 20 {
t.Errorf("Sizeof(%v) with WordSize 4 = %d want 20", ts, got)
}
sizes = types.StdSizes{WordSize: 8, MaxAlign: 8}
if got := sizes.Sizeof(ts); got != 40 {
t.Errorf("Sizeof(%v) with WordSize 8 = %d want 40", ts, got)
}
}
......@@ -4,10 +4,7 @@
package types
import (
"sort"
"sync"
)
import "sort"
// A Type represents a type of Go.
// All types implement the Type interface.
......@@ -121,10 +118,8 @@ func (s *Slice) Elem() Type { return s.elem }
// A Struct represents a struct type.
type Struct struct {
fields []*Var
tags []string // field tags; nil if there are no tags
offsets []int64 // field offsets in bytes, lazily initialized
offsetsOnce sync.Once // for threadsafe lazy initialization of offsets
fields []*Var
tags []string // field tags; nil if there are no tags
}
// NewStruct returns a new struct with the given fields and corresponding field tags.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment