File: record_section_tracker.h

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,245,028 kB
  • sloc: cpp: 7,619,726; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,675; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (113 lines) | stat: -rw-r--r-- 3,427 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//===- record_section_tracker.h -- for fixed-sized record sects -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// RecordSectionsTracker: Responsible for managing sections of metadata records
// with fixed sizes.
//
//===----------------------------------------------------------------------===//

#ifndef ORC_RT_RECORD_SECTION_TRACKER_H
#define ORC_RT_RECORD_SECTION_TRACKER_H

#include "error.h"
#include "executor_address.h"
#include <algorithm>
#include <vector>

namespace orc_rt {

/// Used to manage sections of fixed-sized metadata records (e.g. pointer
/// sections, selector refs, etc.)
template <typename RecordElement> class RecordSectionsTracker {
public:
  /// Add a section to the "new" list.
  void add(span<RecordElement> Sec) { New.push_back(std::move(Sec)); }

  /// Returns true if there are new sections to process.
  bool hasNewSections() const { return !New.empty(); }

  /// Returns the number of new sections to process.
  size_t numNewSections() const { return New.size(); }

  /// Process all new sections.
  template <typename ProcessSectionFunc>
  std::enable_if_t<std::is_void_v<
      std::invoke_result_t<ProcessSectionFunc, span<RecordElement>>>>
  processNewSections(ProcessSectionFunc &&ProcessSection) {
    for (auto &Sec : New)
      ProcessSection(Sec);
    moveNewToProcessed();
  }

  /// Proces all new sections with a fallible handler.
  ///
  /// Successfully handled sections will be moved to the Processed
  /// list.
  template <typename ProcessSectionFunc>
  std::enable_if_t<
      std::is_same_v<
          Error, std::invoke_result_t<ProcessSectionFunc, span<RecordElement>>>,
      Error>
  processNewSections(ProcessSectionFunc &&ProcessSection) {
    for (size_t I = 0; I != New.size(); ++I) {
      if (auto Err = ProcessSection(New[I])) {
        for (size_t J = 0; J != I; ++J)
          Processed.push_back(New[J]);
        New.erase(New.begin(), New.begin() + I);
        return Err;
      }
    }
    moveNewToProcessed();
    return Error::success();
  }

  /// Move all sections back to New for reprocessing.
  void reset() {
    moveNewToProcessed();
    New = std::move(Processed);
  }

  /// Remove the section with the given range.
  bool removeIfPresent(ExecutorAddrRange R) {
    if (removeIfPresent(New, R))
      return true;
    return removeIfPresent(Processed, R);
  }

private:
  void moveNewToProcessed() {
    if (Processed.empty())
      Processed = std::move(New);
    else {
      Processed.reserve(Processed.size() + New.size());
      std::copy(New.begin(), New.end(), std::back_inserter(Processed));
      New.clear();
    }
  }

  bool removeIfPresent(std::vector<span<RecordElement>> &V,
                       ExecutorAddrRange R) {
    auto RI = std::find_if(
        V.rbegin(), V.rend(),
        [RS = R.toSpan<RecordElement>()](const span<RecordElement> &E) {
          return E.data() == RS.data();
        });
    if (RI != V.rend()) {
      V.erase(std::next(RI).base());
      return true;
    }
    return false;
  }

  std::vector<span<RecordElement>> Processed;
  std::vector<span<RecordElement>> New;
};

} // namespace orc_rt

#endif // ORC_RT_RECORD_SECTION_TRACKER_H