1 //===- record_section_tracker.h -- for fixed-sized record sects -*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // RecordSectionsTracker: Responsible for managing sections of metadata records
12 //===----------------------------------------------------------------------===//
14 #ifndef ORC_RT_RECORD_SECTION_TRACKER_H
15 #define ORC_RT_RECORD_SECTION_TRACKER_H
18 #include "executor_address.h"
24 /// Used to manage sections of fixed-sized metadata records (e.g. pointer
25 /// sections, selector refs, etc.)
26 template <typename RecordElement
> class RecordSectionsTracker
{
28 /// Add a section to the "new" list.
29 void add(span
<RecordElement
> Sec
) { New
.push_back(std::move(Sec
)); }
31 /// Returns true if there are new sections to process.
32 bool hasNewSections() const { return !New
.empty(); }
34 /// Returns the number of new sections to process.
35 size_t numNewSections() const { return New
.size(); }
37 /// Process all new sections.
38 template <typename ProcessSectionFunc
>
39 std::enable_if_t
<std::is_void_v
<
40 std::invoke_result_t
<ProcessSectionFunc
, span
<RecordElement
>>>>
41 processNewSections(ProcessSectionFunc
&&ProcessSection
) {
47 /// Proces all new sections with a fallible handler.
49 /// Successfully handled sections will be moved to the Processed
51 template <typename ProcessSectionFunc
>
54 Error
, std::invoke_result_t
<ProcessSectionFunc
, span
<RecordElement
>>>,
56 processNewSections(ProcessSectionFunc
&&ProcessSection
) {
57 for (size_t I
= 0; I
!= New
.size(); ++I
) {
58 if (auto Err
= ProcessSection(New
[I
])) {
59 for (size_t J
= 0; J
!= I
; ++J
)
60 Processed
.push_back(New
[J
]);
61 New
.erase(New
.begin(), New
.begin() + I
);
66 return Error::success();
69 /// Move all sections back to New for reprocessing.
72 New
= std::move(Processed
);
75 /// Remove the section with the given range.
76 bool removeIfPresent(ExecutorAddrRange R
) {
77 if (removeIfPresent(New
, R
))
79 return removeIfPresent(Processed
, R
);
83 void moveNewToProcessed() {
84 if (Processed
.empty())
85 Processed
= std::move(New
);
87 Processed
.reserve(Processed
.size() + New
.size());
88 std::copy(New
.begin(), New
.end(), std::back_inserter(Processed
));
93 bool removeIfPresent(std::vector
<span
<RecordElement
>> &V
,
94 ExecutorAddrRange R
) {
95 auto RI
= std::find_if(
97 [RS
= R
.toSpan
<RecordElement
>()](const span
<RecordElement
> &E
) {
98 return E
.data() == RS
.data();
100 if (RI
!= V
.rend()) {
101 V
.erase(std::next(RI
).base());
107 std::vector
<span
<RecordElement
>> Processed
;
108 std::vector
<span
<RecordElement
>> New
;
111 } // namespace orc_rt
113 #endif // ORC_RT_RECORD_SECTION_TRACKER_H