34using InMemoryIndexValueT = InMemoryIndexT::value_type;
49 Kind getKind()
const {
return IndexAndKind.getInt(); }
50 const InMemoryIndexValueT &getIndex()
const {
51 assert(IndexAndKind.getPointer());
52 return *IndexAndKind.getPointer();
57 InMemoryObject() =
delete;
58 InMemoryObject(InMemoryObject &&) =
delete;
59 InMemoryObject(
const InMemoryObject &) =
delete;
62 InMemoryObject(Kind K,
const InMemoryIndexValueT &
I) : IndexAndKind(&
I,
K) {}
69 static_assert((1U << NumKindBits) <=
alignof(InMemoryIndexValueT),
70 "Kind will clobber pointer");
71 static_assert(((int)Kind::Max >> NumKindBits) == 0,
"Kind will be truncated");
79class InMemoryRefObject final :
public InMemoryObject {
81 static constexpr Kind KindValue = Kind::RefNode;
82 static bool classof(
const InMemoryObject *O) {
83 return O->getKind() == KindValue;
92 const InMemoryIndexValueT &
I,
95 void *Mem = Allocate(
sizeof(InMemoryRefObject));
96 return *
new (Mem) InMemoryRefObject(
I, Refs, Data);
100 InMemoryRefObject(
const InMemoryIndexValueT &
I,
102 : InMemoryObject(KindValue,
I), Refs(Refs), Data(Data) {
105 assert(*Data.end() == 0 &&
"Expected null-termination");
112class InMemoryInlineObject final
113 :
public InMemoryObject,
117 static constexpr Kind KindValue = Kind::InlineNode;
118 static bool classof(
const InMemoryObject *O) {
119 return O->getKind() == KindValue;
124 return ArrayRef(getTrailingObjects<const InMemoryObject *>(), NumRefs);
129 return ArrayRef(getTrailingObjects<char>(), DataSize);
132 static InMemoryInlineObject &
136 void *Mem = Allocate(
sizeof(InMemoryInlineObject) +
137 sizeof(uintptr_t) * Refs.
size() + Data.size() + 1);
138 return *
new (Mem) InMemoryInlineObject(
I, Refs, Data);
141 size_t numTrailingObjects(OverloadToken<const InMemoryObject *>)
const {
146 InMemoryInlineObject(
const InMemoryIndexValueT &
I,
149 : InMemoryObject(KindValue,
I), NumRefs(Refs.
size()),
150 DataSize(Data.
size()) {
151 auto *BeginRefs =
reinterpret_cast<const InMemoryObject **
>(
this + 1);
153 auto *BeginData =
reinterpret_cast<char *
>(BeginRefs + NumRefs);
155 BeginData[Data.size()] = 0;
179 assert(!(
reinterpret_cast<uintptr_t
>(&
Node) & 0x1ULL));
180 return makeObjectHandle(
reinterpret_cast<uintptr_t
>(&
Node));
184 return getObjectHandle(asInMemoryObject(
Ref));
188 return *
Index.insertLazy(
189 Hash, [](
auto ValueConstructor) { ValueConstructor.emplace(
nullptr); });
194 const InMemoryObject *getInMemoryObject(
CASID ID)
const {
195 assert(
ID.getContext().getHashSchemaIdentifier() ==
196 getContext().getHashSchemaIdentifier() &&
197 "Expected ID from same hash schema");
198 if (InMemoryIndexT::const_pointer
P =
Index.find(
ID.getHash()))
203 const InMemoryObject &getInMemoryObject(
ObjectHandle OH)
const {
204 return *
reinterpret_cast<const InMemoryObject *
>(
209 uintptr_t
P =
Ref.getInternalRef(*
this);
210 return *
reinterpret_cast<const InMemoryObject *
>(
P);
212 ObjectRef toReference(
const InMemoryObject &O)
const {
213 return makeObjectRef(
reinterpret_cast<uintptr_t
>(&O));
218 return getID(asInMemoryObject(
Ref));
222 if (
const InMemoryObject *Object = getInMemoryObject(
ID))
223 return toReference(*Object);
230 return cast<InMemoryObject>(asInMemoryObject(
Node)).getData();
233 InMemoryCAS() =
default;
237 return getInMemoryObject(
Node).getRefs().size();
240 return toReference(*getInMemoryObject(
Node).getRefs()[
I]);
250 InMemoryIndexT
Index;
260 if (
auto *Derived = dyn_cast<InMemoryRefObject>(
this))
261 return Derived->getDataImpl();
262 return cast<InMemoryInlineObject>(
this)->getDataImpl();
266 if (
auto *Derived = dyn_cast<InMemoryRefObject>(
this))
267 return Derived->getRefsImpl();
268 return cast<InMemoryInlineObject>(
this)->getRefsImpl();
276 auto &
I = indexHash(ComputedHash);
280 return Objects.Allocate(
Size,
alignof(InMemoryObject));
282 auto Generator = [&]() ->
const InMemoryObject * {
283 return &InMemoryRefObject::create(Allocator,
I, {}, Data);
285 const InMemoryObject &
Node =
286 cast<InMemoryObject>(
I.Data.loadOrGenerate(Generator));
289 if (
auto *RefNode = dyn_cast<InMemoryRefObject>(&
Node))
290 if (RefNode->getData().data() ==
Map.data())
293 return toReference(
Node);
300 auto &
I = indexHash(ComputedHash);
307 return Objects.Allocate(
Size,
alignof(InMemoryObject));
309 auto Generator = [&]() ->
const InMemoryObject * {
310 return &InMemoryInlineObject::create(Allocator,
I, InternalRefs, Data);
312 return toReference(cast<InMemoryObject>(
I.Data.loadOrGenerate(Generator)));
317 auto &
Node = getInMemoryObject(Handle);
318 for (
const InMemoryObject *
Ref :
Node.getRefs())
319 if (
Error E = Callback(toReference(*
Ref)))
325 return std::make_unique<InMemoryCAS>();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
This file defines the PointerIntPair class.
This header defines support for implementing classes that have some trailing object (or arrays of obj...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
PointerIntPair - This class implements a pair of a pointer and small integer.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Thread-safe allocator adaptor.
Lock-free thread-safe hash-mapped trie.
See the file comment for details on the usage of the TrailingObjects type.
Unique identifier for a CAS object.
static CASID create(const CASContext *Context, StringRef Hash)
Create CASID from CASContext and raw hash bytes.
Handle to a loaded object in a ObjectStore instance.
Reference to an object in an ObjectStore instance.
virtual Expected< bool > isMaterialized(ObjectRef Ref) const =0
virtual CASID getID(ObjectRef Ref) const =0
Get an ID for Ref.
virtual Expected< std::optional< ObjectHandle > > loadIfExists(ObjectRef Ref)=0
Load the object referenced by Ref.
const CASContext & getContext() const
Get CASContext.
virtual ObjectRef readRef(ObjectHandle Node, size_t I) const =0
virtual size_t getNumRefs(ObjectHandle Node) const =0
virtual std::optional< ObjectRef > getReference(const CASID &ID) const =0
Get an existing reference to the object called ID.
virtual Error forEachRef(ObjectHandle Node, function_ref< Error(ObjectRef)> Callback) const =0
Methods for handling objects.
Base class for references to things in ObjectStore.
uint64_t getInternalRef(const ObjectStore &ExpectedCAS) const
Get an internal reference.
Common base class for builtin CAS implementations using the same CASContext.
virtual Expected< ObjectRef > storeFromNullTerminatedRegion(ArrayRef< uint8_t > ComputedHash, sys::fs::mapped_file_region Map)
virtual ArrayRef< char > getDataConst(ObjectHandle Node) const =0
Both builtin CAS implementations provide lifetime for free, so this can be const, and readData() and ...
virtual Expected< ObjectRef > storeImpl(ArrayRef< uint8_t > ComputedHash, ArrayRef< ObjectRef > Refs, ArrayRef< char > Data)=0
An efficient, type-erasing, non-owning reference to a callable.
This class represents a memory mapped file.
decltype(HasherT::hash(std::declval< ArrayRef< uint8_t > & >())) HashType
std::unique_ptr< ObjectStore > createInMemoryCAS()
StringRef toStringRef(const std::optional< DWARFFormValue > &V, StringRef Default={})
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
@ Ref
The access may reference the value stored in memory.
OutputIt copy(R &&Range, OutputIt Out)
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
This struct is a compact representation of a valid (non-zero power of two) alignment.