aboutsummaryrefslogtreecommitdiffstats
path: root/prog/prog.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-04-25 15:05:19 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-05-05 14:01:52 +0200
commit4b76dd258977f4bc9b8a1996680f8b9fd96713d2 (patch)
tree5de611ae32f2f137053888d73bf81b40feaf59b1 /prog/prog.go
parent8cbfd71747917061fa744c07972ba65a7f73a236 (diff)
prog: use Ref as Arg type
Use Ref in Arg instead of full Type interface. This reduces size of all args. In partiuclar the most common ConstArg is reduces from 32 bytes to 16 and now does not contain any pointers (better for GC). Running syz-db bench on a beefy corpus: before: allocs 7262 MB (18 M), next GC 958 MB, sys heap 1279 MB, live allocs 479 MB (8 M), time 9.704699958s allocs 7262 MB (18 M), next GC 958 MB, sys heap 1279 MB, live allocs 479 MB (8 M), time 9.873792394s allocs 7262 MB (18 M), next GC 958 MB, sys heap 1279 MB, live allocs 479 MB (8 M), time 9.820479906s after: allocs 7163 MB (18 M), next GC 759 MB, sys heap 1023 MB, live allocs 379 MB (8 M), time 8.938939937s allocs 7163 MB (18 M), next GC 759 MB, sys heap 1087 MB, live allocs 379 MB (8 M), time 9.410243167s allocs 7163 MB (18 M), next GC 759 MB, sys heap 1023 MB, live allocs 379 MB (8 M), time 9.38225806s Max heap and live heap are reduced by 20%. Update #1580
Diffstat (limited to 'prog/prog.go')
-rw-r--r--prog/prog.go35
1 files changed, 19 insertions, 16 deletions
diff --git a/prog/prog.go b/prog/prog.go
index 00e290175..3e46e15ea 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -30,12 +30,15 @@ type Arg interface {
}
type ArgCommon struct {
- typ Type
+ ref Ref
dir Dir
}
-func (arg *ArgCommon) Type() Type {
- return arg.typ
+func (arg ArgCommon) Type() Type {
+ if arg.ref == 0 {
+ panic("broken type ref")
+ }
+ return typeRefs.Load().([]Type)[arg.ref]
}
func (arg *ArgCommon) Dir() Dir {
@@ -49,11 +52,11 @@ type ConstArg struct {
}
func MakeConstArg(t Type, dir Dir, v uint64) *ConstArg {
- return &ConstArg{ArgCommon: ArgCommon{typ: t, dir: dir}, Val: v}
+ return &ConstArg{ArgCommon: ArgCommon{ref: t.ref(), dir: dir}, Val: v}
}
func (arg *ConstArg) Size() uint64 {
- return arg.typ.Size()
+ return arg.Type().Size()
}
// Value returns value and pid stride.
@@ -95,7 +98,7 @@ func MakePointerArg(t Type, dir Dir, addr uint64, data Arg) *PointerArg {
panic("nil pointer data arg")
}
return &PointerArg{
- ArgCommon: ArgCommon{typ: t, dir: DirIn}, // pointers are always in
+ ArgCommon: ArgCommon{ref: t.ref(), dir: DirIn}, // pointers are always in
Address: addr,
Res: data,
}
@@ -106,7 +109,7 @@ func MakeVmaPointerArg(t Type, dir Dir, addr, size uint64) *PointerArg {
panic("unaligned vma address")
}
return &PointerArg{
- ArgCommon: ArgCommon{typ: t, dir: dir},
+ ArgCommon: ArgCommon{ref: t.ref(), dir: dir},
Address: addr,
VmaSize: size,
}
@@ -120,13 +123,13 @@ func MakeSpecialPointerArg(t Type, dir Dir, index uint64) *PointerArg {
dir = DirIn // pointers are always in
}
return &PointerArg{
- ArgCommon: ArgCommon{typ: t, dir: dir},
+ ArgCommon: ArgCommon{ref: t.ref(), dir: dir},
Address: -index,
}
}
func (arg *PointerArg) Size() uint64 {
- return arg.typ.Size()
+ return arg.Type().Size()
}
func (arg *PointerArg) IsSpecial() bool {
@@ -151,14 +154,14 @@ func MakeDataArg(t Type, dir Dir, data []byte) *DataArg {
if dir == DirOut {
panic("non-empty output data arg")
}
- return &DataArg{ArgCommon: ArgCommon{typ: t, dir: dir}, data: append([]byte{}, data...)}
+ return &DataArg{ArgCommon: ArgCommon{ref: t.ref(), dir: dir}, data: append([]byte{}, data...)}
}
func MakeOutDataArg(t Type, dir Dir, size uint64) *DataArg {
if dir != DirOut {
panic("empty input data arg")
}
- return &DataArg{ArgCommon: ArgCommon{typ: t, dir: dir}, size: size}
+ return &DataArg{ArgCommon: ArgCommon{ref: t.ref(), dir: dir}, size: size}
}
func (arg *DataArg) Size() uint64 {
@@ -190,7 +193,7 @@ type GroupArg struct {
}
func MakeGroupArg(t Type, dir Dir, inner []Arg) *GroupArg {
- return &GroupArg{ArgCommon: ArgCommon{typ: t, dir: dir}, Inner: inner}
+ return &GroupArg{ArgCommon: ArgCommon{ref: t.ref(), dir: dir}, Inner: inner}
}
func (arg *GroupArg) Size() uint64 {
@@ -238,7 +241,7 @@ type UnionArg struct {
}
func MakeUnionArg(t Type, dir Dir, opt Arg, index int) *UnionArg {
- return &UnionArg{ArgCommon: ArgCommon{typ: t, dir: dir}, Option: opt, Index: index}
+ return &UnionArg{ArgCommon: ArgCommon{ref: t.ref(), dir: dir}, Option: opt, Index: index}
}
func (arg *UnionArg) Size() uint64 {
@@ -261,7 +264,7 @@ type ResultArg struct {
}
func MakeResultArg(t Type, dir Dir, r *ResultArg, v uint64) *ResultArg {
- arg := &ResultArg{ArgCommon: ArgCommon{typ: t, dir: dir}, Res: r, Val: v}
+ arg := &ResultArg{ArgCommon: ArgCommon{ref: t.ref(), dir: dir}, Res: r, Val: v}
if r == nil {
return arg
}
@@ -276,11 +279,11 @@ func MakeReturnArg(t Type) *ResultArg {
if t == nil {
return nil
}
- return &ResultArg{ArgCommon: ArgCommon{typ: t, dir: DirOut}}
+ return &ResultArg{ArgCommon: ArgCommon{ref: t.ref(), dir: DirOut}}
}
func (arg *ResultArg) Size() uint64 {
- return arg.typ.Size()
+ return arg.Type().Size()
}
// Returns inner arg for pointer args.