arena.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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 EXECUTABLE_SEMANTICS_COMMON_ARENA_H_
  5. #define EXECUTABLE_SEMANTICS_COMMON_ARENA_H_
  6. #include <memory>
  7. #include <vector>
  8. #include "executable_semantics/common/ptr.h"
  9. #include "llvm/Support/ManagedStatic.h"
  10. namespace Carbon {
  11. class Arena {
  12. public:
  13. // Allocates an object in the arena, returning a pointer to it.
  14. template <typename T, typename... Args>
  15. auto New(Args&&... args) -> Ptr<T> {
  16. auto smart_ptr =
  17. std::make_unique<ArenaEntryTyped<T>>(std::forward<Args>(args)...);
  18. Ptr<T> ptr = smart_ptr->Instance();
  19. arena.push_back(std::move(smart_ptr));
  20. return ptr;
  21. }
  22. // TODO: Remove. This is only to help findability during migration.
  23. template <typename T, typename... Args>
  24. auto RawNew(Args&&... args) -> T* {
  25. auto smart_ptr =
  26. std::make_unique<ArenaEntryTyped<T>>(std::forward<Args>(args)...);
  27. T* raw_ptr = smart_ptr->Instance().Get();
  28. arena.push_back(std::move(smart_ptr));
  29. return raw_ptr;
  30. }
  31. private:
  32. // Virtualizes arena entries so that a single vector can contain many types,
  33. // avoiding templated statics.
  34. class ArenaEntry {
  35. public:
  36. virtual ~ArenaEntry() = default;
  37. };
  38. // Templated destruction of a pointer.
  39. template <typename T>
  40. class ArenaEntryTyped : public ArenaEntry {
  41. public:
  42. template <typename... Args>
  43. explicit ArenaEntryTyped(Args&&... args)
  44. : instance(std::forward<Args>(args)...) {}
  45. auto Instance() -> Ptr<T> { return Ptr<T>(&instance); }
  46. private:
  47. T instance;
  48. };
  49. // Manages allocations in an arena for destruction at shutdown.
  50. std::vector<std::unique_ptr<ArenaEntry>> arena;
  51. };
  52. extern llvm::ManagedStatic<Arena> global_arena;
  53. } // namespace Carbon
  54. #endif // EXECUTABLE_SEMANTICS_COMMON_ARENA_H_