aboutsummaryrefslogtreecommitdiffstats
path: root/prog/size.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-05-01 17:19:27 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-05-02 12:16:06 +0200
commit58da4c35b15200b7279f18ea15bc8644618aae78 (patch)
tree412d59572c980c4eb582d6d0e187eb6ec32345c9 /prog/size.go
parentbc734e7ada413654f1b7d948b2a857260a52dd9c (diff)
prog: introduce Field type
Remvoe FieldName from Type and add a separate Field type that holds field name. Use Field for struct fields, union options and syscalls arguments, only these really have names. Reduces size of sys/linux/gen/amd64.go from 5665583 to 5201321 (-8.2%). Allows to not create new type for squashed any pointer. But main advantages will follow, e.g. removing StructDesc, using TypeRef in Arg, etc. Update #1580
Diffstat (limited to 'prog/size.go')
-rw-r--r--prog/size.go70
1 files changed, 39 insertions, 31 deletions
diff --git a/prog/size.go b/prog/size.go
index a7fdb093e..61d382723 100644
--- a/prog/size.go
+++ b/prog/size.go
@@ -14,7 +14,8 @@ const (
SyscallRef = "syscall"
)
-func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg, syscallArgs []Arg, autos map[Arg]bool) {
+func (target *Target) assignSizes(args []Arg, fields []Field, parentsMap map[Arg]Arg,
+ syscallArgs []Arg, syscallFields []Field, autos map[Arg]bool) {
for _, arg := range args {
if arg = InnerArg(arg); arg == nil {
continue // Pointer to optional len field, no need to fill in value.
@@ -31,19 +32,26 @@ func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg, syscallArg
}
a := arg.(*ConstArg)
if typ.Path[0] == SyscallRef {
- target.assignSize(a, nil, typ.Path[1:], syscallArgs, parentsMap)
+ target.assignSize(a, nil, typ.Path[1:], syscallArgs, syscallFields, parentsMap)
} else {
- target.assignSize(a, a, typ.Path, args, parentsMap)
+ target.assignSize(a, a, typ.Path, args, fields, parentsMap)
}
}
}
-func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []Arg, parentsMap map[Arg]Arg) {
+func (target *Target) assignSizeStruct(dst *ConstArg, buf Arg, path []string, parentsMap map[Arg]Arg) {
+ arg := buf.(*GroupArg)
+ typ := arg.Type().(*StructType)
+ target.assignSize(dst, buf, path, arg.Inner, typ.Fields, parentsMap)
+}
+
+func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []Arg,
+ fields []Field, parentsMap map[Arg]Arg) {
elem := path[0]
path = path[1:]
var offset uint64
- for _, buf := range args {
- if elem != buf.Type().FieldName() {
+ for i, buf := range args {
+ if elem != fields[i].Name {
offset += buf.Size()
continue
}
@@ -58,39 +66,39 @@ func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []A
dst.Val = 0 // target is an optional pointer
return
}
- if len(path) == 0 {
- dst.Val = target.computeSize(buf, offset, dst.Type().(*LenType))
- } else {
- target.assignSize(dst, buf, path, buf.(*GroupArg).Inner, parentsMap)
+ if len(path) != 0 {
+ target.assignSizeStruct(dst, buf, path, parentsMap)
+ return
}
+ dst.Val = target.computeSize(buf, offset, dst.Type().(*LenType))
return
}
if elem == ParentRef {
buf := parentsMap[pos]
- if len(path) == 0 {
- dst.Val = target.computeSize(buf, noOffset, dst.Type().(*LenType))
- } else {
- target.assignSize(dst, buf, path, buf.(*GroupArg).Inner, parentsMap)
+ if len(path) != 0 {
+ target.assignSizeStruct(dst, buf, path, parentsMap)
+ return
}
+ dst.Val = target.computeSize(buf, noOffset, dst.Type().(*LenType))
return
}
for buf := parentsMap[pos]; buf != nil; buf = parentsMap[buf] {
if elem != buf.Type().TemplateName() {
continue
}
- if len(path) == 0 {
- dst.Val = target.computeSize(buf, noOffset, dst.Type().(*LenType))
- } else {
- target.assignSize(dst, buf, path, buf.(*GroupArg).Inner, parentsMap)
+ if len(path) != 0 {
+ target.assignSizeStruct(dst, buf, path, parentsMap)
+ return
}
+ dst.Val = target.computeSize(buf, noOffset, dst.Type().(*LenType))
return
}
- var argNames []string
- for _, arg := range args {
- argNames = append(argNames, arg.Type().FieldName())
+ var fieldNames []string
+ for _, field := range fields {
+ fieldNames = append(fieldNames, field.Name)
}
- panic(fmt.Sprintf("len field %q references non existent field %q, pos=%q/%q, argsMap: %+v",
- dst.Type().FieldName(), elem, pos.Type().Name(), pos.Type().FieldName(), argNames))
+ panic(fmt.Sprintf("len field %q references non existent field %q, pos=%q, argsMap: %v, path: %v",
+ dst.Type().Name(), elem, pos.Type().Name(), fieldNames, path))
}
const noOffset = ^uint64(0)
@@ -121,7 +129,7 @@ func (target *Target) computeSize(arg Arg, offset uint64, lenType *LenType) uint
}
}
-func (target *Target) assignSizesArray(args []Arg, autos map[Arg]bool) {
+func (target *Target) assignSizesArray(args []Arg, fields []Field, autos map[Arg]bool) {
parentsMap := make(map[Arg]Arg)
for _, arg := range args {
ForeachSubArg(arg, func(arg Arg, _ *ArgCtx) {
@@ -132,29 +140,29 @@ func (target *Target) assignSizesArray(args []Arg, autos map[Arg]bool) {
}
})
}
- target.assignSizes(args, parentsMap, args, autos)
+ target.assignSizes(args, fields, parentsMap, args, fields, autos)
for _, arg := range args {
ForeachSubArg(arg, func(arg Arg, _ *ArgCtx) {
- if _, ok := arg.Type().(*StructType); ok {
- target.assignSizes(arg.(*GroupArg).Inner, parentsMap, args, autos)
+ if typ, ok := arg.Type().(*StructType); ok {
+ target.assignSizes(arg.(*GroupArg).Inner, typ.Fields, parentsMap, args, fields, autos)
}
})
}
}
func (target *Target) assignSizesCall(c *Call) {
- target.assignSizesArray(c.Args, nil)
+ target.assignSizesArray(c.Args, c.Meta.Args, nil)
}
-func (r *randGen) mutateSize(arg *ConstArg, parent []Arg) bool {
+func (r *randGen) mutateSize(arg *ConstArg, parent []Arg, fields []Field) bool {
typ := arg.Type().(*LenType)
elemSize := typ.BitSize / 8
if elemSize == 0 {
elemSize = 1
// TODO(dvyukov): implement path support for size mutation.
if len(typ.Path) == 1 {
- for _, field := range parent {
- if typ.Path[0] != field.Type().FieldName() {
+ for i, field := range parent {
+ if typ.Path[0] != fields[i].Name {
continue
}
if inner := InnerArg(field); inner != nil {