stack_space.h 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_EXPLORER_INTERPRETER_STACK_SPACE_H_
  5. #define CARBON_EXPLORER_INTERPRETER_STACK_SPACE_H_
  6. #include <optional>
  7. #include "llvm/ADT/STLFunctionalExtras.h"
  8. namespace Carbon {
  9. namespace Internal {
  10. // Returns true if a new thread should be started for more stack space.
  11. auto IsStackSpaceNearlyExhausted() -> bool;
  12. // Starts a thread to run the function.
  13. auto RunWithExtraStackHelper(llvm::function_ref<void()> fn) -> void;
  14. } // namespace Internal
  15. // Runs `fn` after ensuring there is a reasonable amount of space left on the
  16. // stack for it to run in. This will run `fn` in a separate thread if there is
  17. // not enough space left on the current stack, or if RunWithExtraStack didn't
  18. // create the current thread.
  19. //
  20. // Usage:
  21. // return RunWithExtraStack([&]() -> ReturnType {
  22. // <function body>
  23. // });
  24. template <typename Fn>
  25. auto RunWithExtraStack(Fn fn) -> decltype(fn()) {
  26. using ReturnType = decltype(fn());
  27. static_assert(!std::is_reference_v<ReturnType>);
  28. if (Internal::IsStackSpaceNearlyExhausted()) {
  29. std::optional<ReturnType> result;
  30. Internal::RunWithExtraStackHelper([&] { result = fn(); });
  31. return std::move(*result);
  32. } else {
  33. return fn();
  34. }
  35. }
  36. } // namespace Carbon
  37. #endif // CARBON_EXPLORER_INTERPRETER_STACK_SPACE_H_