This patch is extracted from D96035, it adds support for the existing DWARFLinker functionality. What is not supported yet: 1. Types deduplication(--odr mode). 2. Modules deduplication. 3. Generation of index tables. Reland2: temporarily disabled call to "--linker llvm" for tls-variable.test and location-expression.test as it does not work properly on bigendian architecture. Differential Revision: https://reviews.llvm.org/D153268
93 lines
2.8 KiB
C++
93 lines
2.8 KiB
C++
//===- ArrayList.h ----------------------------------------------*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H
|
|
#define LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H
|
|
|
|
#include "DWARFLinkerGlobalData.h"
|
|
#include "llvm/Support/PerThreadBumpPtrAllocator.h"
|
|
|
|
namespace llvm {
|
|
namespace dwarflinker_parallel {
|
|
|
|
/// This class is a simple list of T structures. It keeps elements as
|
|
/// pre-allocated groups to save memory for each element's next pointer.
|
|
/// It allocates internal data using specified per-thread BumpPtrAllocator.
|
|
template <typename T, size_t ItemsGroupSize = 512> class ArrayList {
|
|
public:
|
|
/// Copy specified \p Item into the list.
|
|
T ¬eItem(const T &Item) {
|
|
assert(Allocator != nullptr);
|
|
|
|
ItemsGroup *CurGroup = LastGroup;
|
|
|
|
if (CurGroup == nullptr) {
|
|
// Allocate first ItemsGroup.
|
|
LastGroup = Allocator->Allocate<ItemsGroup>();
|
|
LastGroup->ItemsCount = 0;
|
|
LastGroup->Next = nullptr;
|
|
GroupsHead = LastGroup;
|
|
CurGroup = LastGroup;
|
|
}
|
|
|
|
if (CurGroup->ItemsCount == ItemsGroupSize) {
|
|
// Allocate next ItemsGroup if current one is full.
|
|
LastGroup = Allocator->Allocate<ItemsGroup>();
|
|
LastGroup->ItemsCount = 0;
|
|
LastGroup->Next = nullptr;
|
|
CurGroup->Next = LastGroup;
|
|
CurGroup = LastGroup;
|
|
}
|
|
|
|
// Copy item into the next position inside current ItemsGroup.
|
|
CurGroup->Items[CurGroup->ItemsCount] = Item;
|
|
return CurGroup->Items[CurGroup->ItemsCount++];
|
|
}
|
|
|
|
using ItemHandlerTy = function_ref<void(T &)>;
|
|
|
|
/// Enumerate all items and apply specified \p Handler to each.
|
|
void forEach(ItemHandlerTy Handler) {
|
|
for (ItemsGroup *CurGroup = GroupsHead; CurGroup != nullptr;
|
|
CurGroup = CurGroup->Next) {
|
|
for (size_t Idx = 0; Idx < CurGroup->ItemsCount; Idx++) {
|
|
Handler(CurGroup->Items[Idx]);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Check whether list is empty.
|
|
bool empty() { return GroupsHead == nullptr; }
|
|
|
|
/// Erase list.
|
|
void erase() {
|
|
GroupsHead = nullptr;
|
|
LastGroup = nullptr;
|
|
}
|
|
|
|
void setAllocator(parallel::PerThreadBumpPtrAllocator *Allocator) {
|
|
this->Allocator = Allocator;
|
|
}
|
|
|
|
protected:
|
|
struct ItemsGroup {
|
|
std::array<T, ItemsGroupSize> Items;
|
|
ItemsGroup *Next = nullptr;
|
|
size_t ItemsCount = 0;
|
|
};
|
|
|
|
ItemsGroup *GroupsHead = nullptr;
|
|
ItemsGroup *LastGroup = nullptr;
|
|
parallel::PerThreadBumpPtrAllocator *Allocator = nullptr;
|
|
};
|
|
|
|
} // end of namespace dwarflinker_parallel
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_LIB_DWARFLINKERPARALLEL_ARRAYLIST_H
|