Commit graph

216 commits

Author SHA1 Message Date
Colin Cross
8514b5c26d Optimize returning the zero value from provider APIs
Now that nothing calls *Context.*Provider directly, make the blueprint
methods return a nil any interface instead of the zero value that was
constructed via reflection.  The type-safe wrappers will return a
zero value that can be constructed without any reflection or copying.

Bug: 316410648
Test: provider_test.go
Change-Id: I0abde5bacab9964a83f03c1644b51295a6c34d0b
2023-12-14 16:59:19 -08:00
Colin Cross
ed49204e85 Use generics for providers API
Using generics for the providers API allows a type to be associated
with a ProviderKey, resulting in a type-safe API without that doesn't
require runtime type assertions by every caller.

Unfortunately, Go does not allow generic types in methods, only in
functions [1].  This prevents a type-safe API on ModuleContext, and
requires moving the API to be functions that take a ModuleContext as
a parameter.

[1] https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#no-parameterized-methods)

Bug: 316410648
Test: provider_test.go
Change-Id: Ide91de9f2a2a7d075b05e287c7cc86b395db0edb
2023-12-14 16:59:16 -08:00
Treehugger Robot
228915b2f1 Merge "Remove pre singletons" into main 2023-11-02 18:04:52 +00:00
Cole Faust
41cbc49a25 Remove pre singletons
They're no longer used.

Test: m nothing --no-skip-soong-tests
Change-Id: I6481381a2ac6bca4211c88173dd4275261123e86
2023-11-01 15:26:17 -07:00
Colin Cross
95bec3331c Use strings instead of simpleNinjaStrings where possible
Storing every string without ninja variable references through
simpleNinjaString costs 24 bytes and a heap allocation.  16 bytes
is used for the ninjaString.str string, 8 bytes for the
ninjaString.variables *[]variableReference.  An additional 8 bytes
is used for the resulting pointer into the heap.

The vast majority of calls to simpleNinjaString originate in
blueprint.parseBuildParams, which converts all of the parameters
passed to ctx.Build into ninjaStrings.  All together this was
allocating 1.575 GB of *ninjaString objects.

Add a parseNinjaOrSimpleStrings function that converts input strings
into ninjaStrings if they have ninja variable references, but also
returns a slice of plain strings for input strings without any ninja
variable references.  That still results in 1.39 GB of allocations just
for the output string slice, so also add an optimization that reuses
the input string slice as the output slice if all of the strings had
no variable references.

Plumb the resulting strings through everywhere that the []*ninjaStrings
were used.

This reduces the total memory allocations inside
blueprint.parseBuildParams in my AOSP aosp_cf_x86_64_phone-userdebug
build from 3.337 GB to 1.786 GB.

Test: ninja_strings_test.go
Change-Id: I51bc138a2a6b1cc7383c7df0a483ccb067ffa02b
2023-11-01 15:15:15 -07:00
Colin Cross
6126fe8067 Optimize memory usage of ninjaString
ninjaString is an interface, which uses 16 bytes of memory on top
of the size of the concrete type.  A literalNinjaString is a string,
which is another 16 bytes for the string header for a total of 32
bytes.  A varNinjaString is two slices, which are 24 bytes each
for the slice headers, for a total of 64 bytes.  The slices contain
the first constant string, and then altenrating variable and string
parts of the ninjaString, resulting in 16 bytes plus 32 bytes per
variable.

This patch replaces the ninjaString interface with a *ninjaString
concrete struct type.  The ninjaString struct is a string and a
pointer to a slice of variable references, for a total of 24 bytes.

ninjaStrings with no variable references (the equivalent of the old
literalNinjaString) have a nil slice, and now use 24 bytes instead
of 32 bytes.

ninjaStrings with variable references allocate a slice of variable
references that contain 32-bit start and end offsets and a Variable
interface, but reuse the original string and so avoid the extra
string headers, resulting in 24 bytes for the slice header, and
24 bytes per variable.

These savings reduce the peak memory usage averaged across 10 runs of
/bin/time -v build/soong/soong_ui.bash --make-mode nothing
on the internal master branch cf_x86_64_phone-userdebug build
from 50114842kB to 45577638kB, a savings of 4537204kB or 9%.

The new Benchmark_parseNinjaString shows savings in both time and
memory.  Before:
Benchmark_parseNinjaString/constant/1-128       	594251787	         2.006 ns/op	       0 B/op	       0 allocs/op
Benchmark_parseNinjaString/constant/10-128      	21191347	        65.57 ns/op	      16 B/op	       1 allocs/op
Benchmark_parseNinjaString/constant/100-128     	 9983748	       130.2 ns/op	     112 B/op	       1 allocs/op
Benchmark_parseNinjaString/constant/1000-128    	 2632527	       445.1 ns/op	    1024 B/op	       1 allocs/op
Benchmark_parseNinjaString/variable/1-128       	 2964896	       419.4 ns/op	     176 B/op	       4 allocs/op
Benchmark_parseNinjaString/variable/10-128      	 1807341	       670.6 ns/op	     192 B/op	       7 allocs/op
Benchmark_parseNinjaString/variable/100-128     	 1000000	      1092 ns/op	     352 B/op	       7 allocs/op
Benchmark_parseNinjaString/variable/1000-128    	  300649	      3773 ns/op	    1584 B/op	       7 allocs/op
Benchmark_parseNinjaString/variables/1-128      	 2858432	       441.6 ns/op	     176 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/2-128      	 2360505	       513.4 ns/op	     208 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/3-128      	 1867136	       635.6 ns/op	     240 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/4-128      	 1584045	       752.1 ns/op	     272 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/5-128      	 1338189	       885.8 ns/op	     304 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/10-128     	 1000000	      1468 ns/op	     464 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/100-128    	   88768	     12895 ns/op	    3712 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/1000-128   	    8972	    133627 ns/op	   32896 B/op	       4 allocs/op

After:
Benchmark_parseNinjaString/constant/1-128       	584600864	         2.004 ns/op	       0 B/op	       0 allocs/op
Benchmark_parseNinjaString/constant/10-128      	19274581	        64.84 ns/op	      16 B/op	       1 allocs/op
Benchmark_parseNinjaString/constant/100-128     	 9017640	       127.6 ns/op	     112 B/op	       1 allocs/op
Benchmark_parseNinjaString/constant/1000-128    	 2630797	       453.0 ns/op	    1024 B/op	       1 allocs/op
Benchmark_parseNinjaString/variable/1-128       	 3460422	       347.0 ns/op	     136 B/op	       4 allocs/op
Benchmark_parseNinjaString/variable/10-128      	 2103404	       519.9 ns/op	     152 B/op	       7 allocs/op
Benchmark_parseNinjaString/variable/100-128     	 1315778	       906.5 ns/op	     312 B/op	       7 allocs/op
Benchmark_parseNinjaString/variable/1000-128    	  354812	      3284 ns/op	    1544 B/op	       7 allocs/op
Benchmark_parseNinjaString/variables/1-128      	 3386868	       361.5 ns/op	     136 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/2-128      	 2675594	       456.9 ns/op	     160 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/3-128      	 2344670	       520.0 ns/op	     192 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/4-128      	 1919482	       648.1 ns/op	     208 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/5-128      	 1560556	       723.9 ns/op	     240 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/10-128     	 1000000	      1169 ns/op	     352 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/100-128    	  116738	     10168 ns/op	    2800 B/op	       4 allocs/op
Benchmark_parseNinjaString/variables/1000-128   	   10000	    105646 ns/op	   24688 B/op	       4 allocs/op

Bug: 286423944
Test: ninja_strings_test.go
Test: out/soong/build*.ninja is the same before and after this change
Change-Id: I1ecffbaccb0d0469a41fa31255c1b17311e01687
2023-06-15 21:53:56 -07:00
Chris Parsons
1b5e9aba43 Make skip-cloning blueprint option public
This allows non-test integrations to set this mode.

Test: Treehugger
Change-Id: I4c69be30bd9ac917113ee8e4d0425dd40753f66f
2023-06-13 01:25:06 +00:00
Liz Kammer
6f42cdc60f Add description to json module actions
Test: m json-module-graph and spot check
Change-Id: Ia825cd6910d42ce7be34200f5d4a669f2d675727
2023-06-08 10:01:06 -04:00
LaMont Jones
12ccb17d4e context: Allow running some singletons in parallel.
Many of the singletons are trivial and can be run in parallel, improving
the performance during analysis.

Bug: 281536768
Test: manual, presubmit
Change-Id: Ia63e4bc42a68e65dfa800e770982fa5826355fad
2023-05-19 19:03:08 +00:00
Jeongik Cha
2621c909e5 Replace GetOutputsFromModuleNames with GetWeightedOutputsFromPredicate
Bug: 273282046
Test: m --ninja_weight_source=ninja_log
Change-Id: I3f35406a7334f737ea010d5453c85e5f2d993708
2023-04-15 00:57:28 +09:00
Steven Moreland
aefc0a9b9b Merge "Add name hint to blueprint." 2023-04-11 20:26:04 +00:00
Steven Moreland
d457f11884 Add name hint to blueprint.
Bug: N/A
Test: updated
Change-Id: Iac9218aa7621dd6223dc26a9f2ebec5d68211328
2023-04-10 20:21:15 +00:00
Liz Kammer
6717f89de4 Add variant name to module info
Without this, we cannot correctly join action and module graph
information as we cannot distinguish variants on action graph.

Test: m json-module-graph
Change-Id: If7379845fc865d8a150f3995df6bf601456a71c3
2023-04-07 09:11:30 -04:00
Treehugger Robot
82aa0ffb51 Merge "ignore bp files from PRODUCT_SOURCE_ROOT_DIRS" 2023-03-29 17:04:37 +00:00
Sam Delmerico
08bd504b62 ignore bp files from PRODUCT_SOURCE_ROOT_DIRS
Soong analyzes the entire source tree even though not every lunch target
needs to know about every module. For example, OEM sources can be
ignored for cuttlefish products. This functionality allows blueprint to
ignore a list of undesired directories.

Bug: 269457150
Change-Id: Icbbf8f3b66813ad639a7ebd27b1a3ec153cbf269
2023-03-27 14:43:07 -04:00
Jeongik Cha
4589dfd812 Add GetOutputsFromModuleNames in Context
To build ninja hint including output path from module name

Test: m --ninja_weight_source=soong
Bug: 273282046
Change-Id: Ibb94c2c4efef4a6dedc973cbb90625231845d42e
2023-03-23 11:17:11 +09:00
Cole Faust
bef8688e45 Optimize and simplify order-only dep deduplication
This reduces the extract_phonys (now deduplicate_order_only_deps)
event's time from ~1.9s to ~1.5s on aosp-master, and from ~5.3s to ~4.6s
on internal master.

It does so by making keyForPhonyCandidate be based on a hash instead
of joining all the deps together. Having a hash allows us to also use
it as the name of the phony target, which simplifies the code a little.

Bug: None (original cl introducing extractPhonys also didn't have a bug)
Test: go tests
Change-Id: I2ff6e4614f19ccbfe99112ea7ae1ea33cd1df21b
2023-03-16 16:43:55 -07:00
Cole Faust
2ed895448b Merge "Fix error messages not printing names" 2023-03-08 23:57:31 +00:00
Cole Faust
ff87a5128b Fix error messages not printing names
Bug: 271424349
Test: Presubmits
Change-Id: I8dd6ab7109c29bd8a03fd2f898eebe1a50a28914
2023-03-08 11:53:24 -08:00
Usta Shrestha
2bae13b095 Use phony ninja outputs to reduce file-size
1. scan if any set of order-only deps are repeated
  2. if so extract them as a phony output to be shared

Test: m libc
Bug: NA
Change-Id: I0689111b97bbbd1f3b26650e8ae2e0a4ffb5085e
2023-03-07 01:39:27 -05:00
Usta Shrestha
4cff07db25 cosmetic: readability
Test: run `m nothing`
Bug: NA
Change-Id: Id58635cc949f07e5263ad67b0e78c66d19abba40
2023-02-27 11:41:51 -05:00
Sam Delmerico
26e44b7b78 apply gofmt
Change-Id: I2416e246b3d8485a6b7810b998cff2f45f6a0494
2023-02-21 15:11:20 -05:00
Liz Kammer
a988f08000 Add event handler for each mutator
Collect additional metrics for individual mutators in order to
understand impact of individual mutators.

Test: m nothing
Change-Id: Ic3ecb1e79a79dd665c9f60d29f0dfd3732481c2d
2023-02-13 18:02:23 -05:00
Liz Kammer
073f69d723 Add getter for EventHandler so its easier to mock
Test: m nothing
Change-Id: Ied338a25f12404ddc88c3b3cb7d7f2ff9ade3aab
2023-02-13 18:02:22 -05:00
Spandan Das
ed4af01be6 Conditional inclusion of blueprint modules
This introduces a new `blueprint_package_includes` module type. If
present, other blueprint modules in that file will be analyzed
if and only if the requested include tags are met

example syntax:
```
Android.bp
blueprint_packgage_includes {
  match_all: ["tag1", "tag2", ...],
}

other_module1 {...}
other_module2 {...}
```
other_module1 and other_module2 will not be analyzed unless
tag1,tag2, ... are set

This also adds a new object of type `IncludeTags` to the Context object,
which is a container for these string keys.

Test: In build/blueprint, go test ./
Test: TH

Change-Id: I79de0d7da3224a5b2025c27a5137f39d00c7382e
2022-12-02 01:46:28 +00:00
Colin Cross
1b457a5e10 Add VariableFuncContext argument to VariableFuncs
Add a VariableFuncContext argument to VariableFuncs that implements
GlobWithDeps.  This will allow Soong to use optimized glob dependencies
in VariableFuncs.

Bug: 257079828
Test: no dependencies on directories in build.ninja.d
Change-Id: Iee5fc9c9ae3087662a5d1a3d7323a87462299205
2022-11-04 18:21:31 +00:00
Lukacs T. Berki
e76d4122ee Add godoc for TransitionMutator.
Test: Presubmits.
Change-Id: I5eba0a4f4d4653a36ff52ed81ee101461ff92b5d
2022-06-27 08:51:58 +02:00
Lukacs T. Berki
eb641de659 Implement transition mutators.
These are more limited than bottom-up or top-down mutators but in
exchange have some pleasant properties:

- "variant not found" errors are impossible
- The logic is pleasantly split into multiple, mostly orthogonal
  parts
- Theoretically, if every mutator is refactored like this, they
  make it possible to partially cache the module graph
- Are quite close to a "configuration transition" in Bazel.

Bug: 231370928
Test: Presubmits.
Change-Id: Idcdb66b5ea75c0d2838f527aaa988df3b12553d8
2022-06-17 17:51:04 +02:00
Usta Shrestha
2a95e590b6 recommend a EventHandler.Do()
Test: manually verified equivalence
Bug: N/A
Change-Id: I2a5abd5b1230ab1f1b5851672e80833c5d18d5c7
2022-05-27 15:39:16 -04:00
Treehugger Robot
57d5937e6f Merge "Allow users to specify extra json action data" 2022-05-27 13:29:54 +00:00
Liz Kammer
d625c97587 Allow users to specify extra json action data
Test: m json-module-graph and validate output
Change-Id: I7ff7c2c98e49f515efb19845aa3a860e14360a32
2022-05-26 16:17:35 -04:00
Treehugger Robot
54c00c6618 Merge "Add info to json module graph about CreateModule" 2022-05-24 19:20:28 +00:00
Chris Parsons
91f638f692 Support pre-build-action hook in blueprint
This allows for a bazel-invocation hook in mixed builds, which allows
for mixed builds to take place in only a single pass, greatly improving
its performance and complexity.

Test: Conjunction with build/soong CL
Change-Id: If89fb56830b4eb06d3263d6ca6da7b285e7ba315
2022-05-10 13:46:40 -04:00
Liz Kammer
0cd0d4fbbc Add info to json module graph about CreateModule
Blueprint already stores the module that called CreateModule, let's
surface it.

Test: m json-module-graph and view results
Change-Id: Ie67bf8e431d764eb23727c90200f57c9de4ab053
2022-05-03 10:49:10 -04:00
Liz Kammer
c6d80893cb Rename jsonVariationMap to jsonVariations.
Test: m json-module-graph
Change-Id: I99663586ded4c5d7c0f61859292afbcf80a1e526
2022-05-03 12:33:02 +00:00
Lukacs T. Berki
83a5a308b1 Remove the concept of "early mutator".
It was unused and as such, maintenance cost for no benefit.

Test: Presubmits.
Change-Id: Ifc35c0f55647ef88ed0bfa44bcf709e51a904ea4
2022-04-19 18:12:03 +02:00
Liz Kammer
8097d1a0e6 Change jsonVariationMap to array of struct
This more structured data is easier to query

Test: m json-module-graph & look at the graph
Change-Id: I44ba6a8df12208705f37ee6908ad5391a6f404a1
2022-04-08 13:14:13 -04:00
Chris Parsons
18ebb2318a Add event handling to blueprint for metrics
In conjunction with soong/build changes, this materialized runtime
metrics for various soong_build events.

Test: Manually verified materialized protos for bp2build, mixed builds,
and legacy build.

Change-Id: Ia92403605e3063028dbf6a1ded8449c190b9e63e
2022-03-25 13:15:17 -04:00
Liz Kammer
6e7e6a92c7 Close file after reading
Test: m nothing
Change-Id: Ib2daa2081d47c52bd3994520d522c5df95973e4a
2022-02-07 10:04:51 -05:00
kgui
a78b020089 Support writing inputs/outputs of actions of modules into a file from the moduleInfo.actionDefs.
An example module variant in the module-actions.json:
{
	"Name": "metalava-gradle-plugin-deps",
	"Variations": null,
	"DependencyVariations": null,
	"Deps": [
		{
			"Name": "prebuilts_gradle-plugin_license",
			"Variations": null,
			"DependencyVariations": null,
			"Tag": ""
		}
	],
	"Type": "",
	"Blueprint": "prebuilts/gradle-plugin/Android.bp",
	"Module": {
		"Actions": [
			{
				"Inputs": [
					"prebuilts/gradle-plugin/com/android/tools/lint/lint-api/30.1.0-alpha13/lint-api-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/lint/lint-checks/30.1.0-alpha13/lint-checks-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/lint/lint/30.1.0-alpha13/lint-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/lint/lint-gradle/30.1.0-alpha13/lint-gradle-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/lint/lint-model/30.1.0-alpha13/lint-model-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/common/30.1.0-alpha13/common-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/sdk-common/30.1.0-alpha13/sdk-common-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/sdklib/30.1.0-alpha13/sdklib-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/external/org-jetbrains/uast/30.1.0-alpha13/uast-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/external/com-intellij/intellij-core/30.1.0-alpha13/intellij-core-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/external/com-intellij/kotlin-compiler/30.1.0-alpha13/kotlin-compiler-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/repository/30.1.0-alpha13/repository-30.1.0-alpha13.jar",
					"prebuilts/gradle-plugin/com/android/tools/build/manifest-merger/30.1.0-alpha13/manifest-merger-30.1.0-alpha13.jar"
				],
				"Outputs": [
					"out/soong/.intermediates/prebuilts/gradle-plugin/metalava-gradle-plugin-deps/linux_glibc_common/combined/metalava-gradle-plugin-deps.jar"
				]
			},
			{
				"Inputs": null,
				"Outputs": [
					"out/soong/.intermediates/prebuilts/gradle-plugin/metalava-gradle-plugin-deps/linux_glibc_common/meta_lic"
				]
			}
		]
	}
}

Test: local
Change-Id: Icbb7236507251e257f6773b110ae8a0788eef41e
2022-01-28 14:50:24 +08:00
Usta Shrestha
ee7a5d7a16 Typos and missing parameter names use in doc comment
Test: N/A
Bug: N/A
Change-Id: I01331365925decef22502da02a23ed4ce610da98
2022-01-18 16:46:30 -05:00
kgui
20f19a5d9b Add JSON data related struct and function into context.
Test: local test
Change-Id: I7a2000b458378f240cd6481066c15dec98d110ea
2022-01-10 14:55:06 +08:00
Yi Kong
a08e722192 Apply toNinjaName for variant names
Variant names are part of the name of the generated Ninja rule.
toNinjaName needs to be applied to it as well.

Test: presubmit
Change-Id: I4fb908b6824179440b1c207240bad59dc85009fa
2021-12-22 13:35:02 +08:00
Lukacs T. Berki
eef5685c65 Rename Blueprints to Android.bp .
This was the only one in the source tree.

Side cleanup: remove some dead code that I assume comes from the time
where Blueprint files had to specify what subdirectories other Blueprint
files are in.

Test: Presubmits.
Change-Id: If84c4e85bc5516f30da97c1be29b56e50dddb3c4
2021-09-02 11:48:19 +02:00
Lukacs T. Berki
5c4abb15e3 Rename BuildDir and NinjaBuildDir.
These are just out/ and out/soong/ and the old names were quite
confusing.

Test: Presubmits.
Merged-In: Idd9ce3c38a259faabcc56f0cd3fdac8b289123b1
Merged-In: I334ab40c668d2a94536f3e63d5f1fa0b401388ac
Change-Id: Ib7c568c6a97701f2240c5e3f0f2ce67397819ac0
2021-08-26 15:08:09 +02:00
Liz Kammer
6e4ee8db2d Use pretty print for json module graph
Test: SOONG_DUMP_JSON_MODULE_GRAPH=/tmp/json/srcs m nothing and verify
      output
Change-Id: I779dcebce7435f2f48263909c4c62c27c0fbfec4
2021-08-17 17:32:42 -04:00
Lukacs T. Berki
1602226f23 Module/providers can now emit extra JSON data.
Test: Presubmits.
Change-Id: I448e85f9144b9b35e7822ab7629329bae7a2fb8e
2021-06-25 10:31:10 +02:00
Colin Cross
13b5befc5c Fix AddNinjaFileDeps in a LoadHook
Propagate the ninja file deps from a LoadHook to the build.ninja.d
file.

Bug: 188547846
Test: next CL
Change-Id: If8176474b5094ee40d07df12f5da79a906ce7290
2021-05-19 10:30:58 -07:00
Colin Cross
e5ff770c95 Add variant to dependency cycle errors
Use moduleInfo.String() to print dependency cycle errors so they
contain the variant.

Test: Test_parallelVisit
Change-Id: I2bddaa35c8abb57c42b4c424e861361a8813d588
2021-04-28 09:40:47 -07:00
Colin Cross
9793b0a5e0 Speed up finding dependency cycles
parallelVisit supports mutating the dependency graph while it is being
visited by proceeding until there are no modules with their dependencies
satisfied, and then checking if there are modules that haven't been
visited yet.  If so, it assumes there was a newly introduced dependency
cycle and tries to find it to return as an error.

Finding the dependency cycle could traverse outside of the cycle.
If the dependency cycle occurs near the bottom of the dependency graph,
that traversal could be both long and wide, leading to very long
runtimes.

Memoize traversed modules that were not found to be part of the
dependency cycle to prevent repeated traversals.

Fixes: 186572387
Test: introduce cycle into libc, m nothing
Test: Test_parallelVisit
Change-Id: I38d0749dbedffbe8a39e433d97fbe08486451321
2021-04-28 09:40:47 -07:00