brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 1ac729a Raw
114 lines · c
1//===- record_section_tracker.h -- for fixed-sized record sects -*- C++ -*-===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// RecordSectionsTracker: Responsible for managing sections of metadata records10// with fixed sizes.11//12//===----------------------------------------------------------------------===//13 14#ifndef ORC_RT_RECORD_SECTION_TRACKER_H15#define ORC_RT_RECORD_SECTION_TRACKER_H16 17#include "error.h"18#include "executor_address.h"19#include <algorithm>20#include <vector>21 22namespace orc_rt {23 24/// Used to manage sections of fixed-sized metadata records (e.g. pointer25/// sections, selector refs, etc.)26template <typename RecordElement> class RecordSectionsTracker {27public:28  /// Add a section to the "new" list.29  void add(span<RecordElement> Sec) { New.push_back(std::move(Sec)); }30 31  /// Returns true if there are new sections to process.32  bool hasNewSections() const { return !New.empty(); }33 34  /// Returns the number of new sections to process.35  size_t numNewSections() const { return New.size(); }36 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) {42    for (auto &Sec : New)43      ProcessSection(Sec);44    moveNewToProcessed();45  }46 47  /// Proces all new sections with a fallible handler.48  ///49  /// Successfully handled sections will be moved to the Processed50  /// list.51  template <typename ProcessSectionFunc>52  std::enable_if_t<53      std::is_same_v<54          Error, std::invoke_result_t<ProcessSectionFunc, span<RecordElement>>>,55      Error>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);62        return Err;63      }64    }65    moveNewToProcessed();66    return Error::success();67  }68 69  /// Move all sections back to New for reprocessing.70  void reset() {71    moveNewToProcessed();72    New = std::move(Processed);73  }74 75  /// Remove the section with the given range.76  bool removeIfPresent(ExecutorAddrRange R) {77    if (removeIfPresent(New, R))78      return true;79    return removeIfPresent(Processed, R);80  }81 82private:83  void moveNewToProcessed() {84    if (Processed.empty())85      Processed = std::move(New);86    else {87      Processed.reserve(Processed.size() + New.size());88      std::copy(New.begin(), New.end(), std::back_inserter(Processed));89      New.clear();90    }91  }92 93  bool removeIfPresent(std::vector<span<RecordElement>> &V,94                       ExecutorAddrRange R) {95    auto RI = std::find_if(96        V.rbegin(), V.rend(),97        [RS = R.toSpan<RecordElement>()](const span<RecordElement> &E) {98          return E.data() == RS.data();99        });100    if (RI != V.rend()) {101      V.erase(std::next(RI).base());102      return true;103    }104    return false;105  }106 107  std::vector<span<RecordElement>> Processed;108  std::vector<span<RecordElement>> New;109};110 111} // namespace orc_rt112 113#endif // ORC_RT_RECORD_SECTION_TRACKER_H114