From 9150b3e5442f9e9ebc53ef5d5a2cd00f01e6f118 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Wed, 13 Dec 2017 11:58:10 +0100 Subject: prog: lazily initialize targets We now have a bunch of targets compiled into each binary. All targets are initialized eagerly on startup time. As the result a do nothing binary starts for ~0.58s and consumes ~21MB. Initialize targets lazily. Usually only 1 target is used. This reduces startup time to ~0.00s and memory consumption to ~5.4MB. --- prog/target.go | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/prog/target.go b/prog/target.go index 4563f107d..29fb100a6 100644 --- a/prog/target.go +++ b/prog/target.go @@ -7,6 +7,7 @@ import ( "fmt" "math/rand" "sort" + "sync" ) // Target describes target OS/arch pair. @@ -52,6 +53,8 @@ type Target struct { StringDictionary []string // Filled by prog package: + init sync.Once + initArch func(target *Target) SyscallMap map[string]*Syscall ConstMap map[string]uint64 resourceMap map[string]*ResourceDesc @@ -66,10 +69,7 @@ func RegisterTarget(target *Target, initArch func(target *Target)) { if targets[key] != nil { panic(fmt.Sprintf("duplicate target %v", key)) } - target.SanitizeCall = func(c *Call) {} - initTarget(target) - initArch(target) - target.ConstMap = nil // currently used only by initArch + target.initArch = initArch targets[key] = target } @@ -84,13 +84,15 @@ func GetTarget(OS, arch string) (*Target, error) { sort.Strings(supported) return nil, fmt.Errorf("unknown target: %v (supported: %v)", key, supported) } + target.init.Do(target.lazyInit) return target, nil } func AllTargets() []*Target { var res []*Target - for _, t := range targets { - res = append(res, t) + for _, target := range targets { + target.init.Do(target.lazyInit) + res = append(res, target) } sort.Slice(res, func(i, j int) bool { if res[i].OS != res[j].OS { @@ -101,7 +103,14 @@ func AllTargets() []*Target { return res } -func initTarget(target *Target) { +func (target *Target) lazyInit() { + target.SanitizeCall = func(c *Call) {} + target.initTarget() + target.initArch(target) + target.ConstMap = nil // currently used only by initArch +} + +func (target *Target) initTarget() { target.ConstMap = make(map[string]uint64) for _, c := range target.Consts { target.ConstMap[c.Name] = c.Value -- cgit mrf-deployment