aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2020-08-23 11:16:10 +0200
committerDmitry Vyukov <dvyukov@google.com>2020-08-23 11:46:14 +0200
commita6d5f3ad1385fe724cdb2c9ee3b05c7d4ce48ef6 (patch)
tree81588d72f247d1937414ac43d041ca8a58e532c9
parent1da71ab086c5d9e6a32beae37b109efaa856b257 (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.go42
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
}