diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-08-23 11:16:10 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-08-23 11:46:14 +0200 |
| commit | a6d5f3ad1385fe724cdb2c9ee3b05c7d4ce48ef6 (patch) | |
| tree | 81588d72f247d1937414ac43d041ca8a58e532c9 | |
| parent | 1da71ab086c5d9e6a32beae37b109efaa856b257 (diff) | |
prog: prune recursion for resourceCentric/createResource
Currently we only prune recursion for createResource.
But createResource can still recurse into resourceCentric,
this can produce huge programs and may be very slow
(esp. if we already in createResource doing failing attempts).
With this change:
$ CI=yes go test -run TestMutateCorpus -count=2 ./prog
passes in ~3 seconds. If I comment out inGenerateResource
logic, it times out after 100 seconds. So this can indeed
have significant effect on generation/mutation performance.
| -rw-r--r-- | prog/rand.go | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/prog/rand.go b/prog/rand.go index 05a9c30df..cfe20fb0b 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -26,9 +26,9 @@ const ( type randGen struct { *rand.Rand - target *Target - inCreateResource bool - recDepth map[string]int + target *Target + inGenerateResource bool + recDepth map[string]int } func newRand(target *Target, rs rand.Source) *randGen { @@ -345,12 +345,6 @@ func (r *randGen) allocVMA(s *state, typ Type, dir Dir, numPages uint64) *Pointe } func (r *randGen) createResource(s *state, res *ResourceType, dir Dir) (arg Arg, calls []*Call) { - if r.inCreateResource { - return nil, nil - } - r.inCreateResource = true - defer func() { r.inCreateResource = false }() - kind := res.Desc.Name // We may have no resources, but still be in createResource due to ANYRES. if len(r.target.resourceMap) != 0 && r.oneOf(1000) { @@ -659,20 +653,28 @@ func (r *randGen) generateArgImpl(s *state, typ Type, dir Dir, ignoreSpecial boo } func (a *ResourceType) generate(r *randGen, s *state, dir Dir) (arg Arg, calls []*Call) { - if r.oneOf(3) { - arg = r.existingResource(s, a, dir) - if arg != nil { - return + if !r.inGenerateResource { + // Don't allow recursion for resourceCentric/createResource. + // That can lead to generation of huge programs and may be very slow + // (esp. if we are generating some failing attempts in createResource already). + r.inGenerateResource = true + defer func() { r.inGenerateResource = false }() + + if r.oneOf(4) { + arg, calls = r.resourceCentric(s, a, dir) + if arg != nil { + return + } } - } - if r.nOutOf(2, 3) { - arg, calls = r.resourceCentric(s, a, dir) - if arg != nil { - return + if r.oneOf(3) { + arg, calls = r.createResource(s, a, dir) + if arg != nil { + return + } } } - if r.nOutOf(4, 5) { - arg, calls = r.createResource(s, a, dir) + if r.nOutOf(9, 10) { + arg = r.existingResource(s, a, dir) if arg != nil { return } |
