bazel collect: simplify NestedSet depth limit check

(Second attempt at commit ed9d6390eb78303631c25b3d4776cb07eeded544, which was rolled back in commit 867d232f27aa762d4b15e811df18b1939cc1a34b.)

This change causes NestedSet to record the depth of the graph,
exposed to the package as NestedSet.getApproxDepth().

To save space, we squirrel the value into the 30 bits liberated by the
removal of the size field, which since commit ea5ec545fbcf815163e419a0e853f65527028acf is now recorded
in the memo field, along with the traversal replay information.
The previous attempt recorded the depth in the graph, but this led
to a greater than expected RAM regression, of about 1%, causing it
to be rolled back.

This approach in this CL has a significant drawback: because NestedSet
is just a wrapper around the Object[] array that represents the graph
node, the depth is not durably recorded in the graph, as it was in the
previous approach. The union constructor effectively discards the depth of
all direct successors except the deepest, thus the getNonLeaves method cannot
restore the correct depth, so the NestedSets it returns may report a depth
larger than their true depth.

Having access to the (approximate) depth in constant time, without flattening,
allows the Starlark depset constructor to reject too-deep sets eagerly instead
of deferring the check till flattening time, which resulted in the scattering
of unchecked NestedSetDepthExceptions throughout the code base,
including in such places as the Starlark interpreter's 'str' operator.

Java code that uses NestedSet is not subject to any depth limit or check,
but could in principle add explicit checks at important boundaries, such as
rule construction, provider construction, and so on.
(That said, getApproxDepth is currently not public.)
Even in the absence of such explicit checks, if an overly deep depset
is constructed by alternating Java and Starlark operations,
a Starlark operation will eventually fail even it was not the one
that crossed the threshold of the limit.

RELNOTES: The --debug_depset_flag has been removed as it is in effect always on at no cost.
PiperOrigin-RevId: 316676111
16 files changed
tree: d50b2b9f9e8b28d4b4c0fe514d34322a2dc03b22
  1. .bazelci/
  2. examples/
  3. scripts/
  4. site/
  5. src/
  6. third_party/
  7. tools/
  8. .bazelrc
  9. .gitattributes
  10. .gitignore
  11. AUTHORS
  12. BUILD
  13. CHANGELOG.md
  14. CODEOWNERS
  15. combine_distfiles.py
  16. combine_distfiles_to_tar.sh
  17. compile.sh
  18. CONTRIBUTING.md
  19. CONTRIBUTORS
  20. distdir.bzl
  21. ISSUE_TEMPLATE.md
  22. LICENSE
  23. README.md
  24. WORKSPACE
README.md

Bazel

{Fast, Correct} - Choose two

Build and test software of any size, quickly and reliably.

  • Speed up your builds and tests: Bazel rebuilds only what is necessary. With advanced local and distributed caching, optimized dependency analysis and parallel execution, you get fast and incremental builds.

  • One tool, multiple languages: Build and test Java, C++, Android, iOS, Go, and a wide variety of other language platforms. Bazel runs on Windows, macOS, and Linux.

  • Scalable: Bazel helps you scale your organization, codebase, and continuous integration solution. It handles codebases of any size, in multiple repositories or a huge monorepo.

  • Extensible to your needs: Easily add support for new languages and platforms with Bazel's familiar extension language. Share and re-use language rules written by the growing Bazel community.

Getting Started

Documentation

Contributing to Bazel

See CONTRIBUTING.md

Build status