LLVM 22.0.0git
ObjectStore.cpp
Go to the documentation of this file.
1//===- ObjectStore.cpp ------------------------------------------*- 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-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "llvm/ADT/DenseSet.h"
11#include "llvm/Support/Debug.h"
12#include "llvm/Support/Errc.h"
15#include <optional>
16
17using namespace llvm;
18using namespace llvm::cas;
19
20void CASContext::anchor() {}
21void ObjectStore::anchor() {}
22
26
27std::string CASID::toString() const {
28 std::string S;
29 raw_string_ostream(S) << *this;
30 return S;
31}
32
34 uint64_t InternalRef, std::optional<CASID> ID) {
35 OS << Kind << "=" << InternalRef;
36 if (ID)
37 OS << "[" << *ID << "]";
38}
39
41 assert(this == &This);
42 printReferenceBase(OS, "object-handle", InternalRef, std::nullopt);
43}
44
45void ReferenceBase::print(raw_ostream &OS, const ObjectRef &This) const {
46 assert(this == &This);
47
48 std::optional<CASID> ID;
49#if LLVM_ENABLE_ABI_BREAKING_CHECKS
50 if (CAS)
51 ID = CAS->getID(This);
52#endif
53 printReferenceBase(OS, "object-ref", InternalRef, ID);
54}
55
57 std::optional<ObjectHandle> Handle;
58 if (Error E = loadIfExists(Ref).moveInto(Handle))
59 return std::move(E);
60 if (!Handle)
62 "missing object '" + getID(Ref).toString() + "'");
63 return *Handle;
64}
65
66std::unique_ptr<MemoryBuffer>
68 bool RequiresNullTerminator) {
70 toStringRef(getData(Node, RequiresNullTerminator)), Name,
71 RequiresNullTerminator);
72}
73
75 SmallVectorImpl<ObjectRef> &Refs) const {
76 consumeError(forEachRef(Node, [&Refs](ObjectRef Ref) -> Error {
77 Refs.push_back(Ref);
78 return Error::success();
79 }));
80}
81
83 std::optional<ObjectRef> Ref = getReference(ID);
84 if (!Ref)
86
87 return getProxy(*Ref);
88}
89
91 std::optional<ObjectHandle> H;
92 if (Error E = load(Ref).moveInto(H))
93 return std::move(E);
94
95 return ObjectProxy::load(*this, Ref, *H);
96}
97
100 std::optional<ObjectHandle> H;
101 if (Error E = loadIfExists(Ref).moveInto(H))
102 return std::move(E);
103 if (!H)
104 return std::nullopt;
105 return ObjectProxy::load(*this, Ref, *H);
106}
107
109 return createStringError(std::make_error_code(std::errc::invalid_argument),
110 "unknown object '" + ID.toString() + "'");
111}
112
114 StringRef Data) {
115 Expected<ObjectRef> Ref = store(Refs, arrayRefFromStringRef<char>(Data));
116 if (!Ref)
117 return Ref.takeError();
118 return getProxy(*Ref);
119}
120
123 std::optional<sys::fs::file_status> Status) {
124 // TODO: For the on-disk CAS implementation use cloning to store it as a
125 // standalone file if the file-system supports it and the file is large.
126 uint64_t Size = Status ? Status->getSize() : -1;
127 auto Buffer = MemoryBuffer::getOpenFile(FD, /*Filename=*/"", Size);
128 if (!Buffer)
129 return errorCodeToError(Buffer.getError());
130
131 return store({}, arrayRefFromStringRef<char>((*Buffer)->getBuffer()));
132}
133
135 SmallDenseSet<ObjectRef> ValidatedRefs;
136 SmallVector<ObjectRef, 16> RefsToValidate;
137 RefsToValidate.push_back(Root);
138
139 while (!RefsToValidate.empty()) {
140 ObjectRef Ref = RefsToValidate.pop_back_val();
141 auto [I, Inserted] = ValidatedRefs.insert(Ref);
142 if (!Inserted)
143 continue; // already validated.
144 if (Error E = validate(getID(Ref)))
145 return E;
147 if (!Obj)
148 return Obj.takeError();
149 if (Error E = forEachRef(*Obj, [&RefsToValidate](ObjectRef R) -> Error {
150 RefsToValidate.push_back(R);
151 return Error::success();
152 }))
153 return E;
154 }
155 return Error::success();
156}
157
158std::unique_ptr<MemoryBuffer>
160 bool RequiresNullTerminator) const {
161 return CAS->getMemoryBuffer(H, Name, RequiresNullTerminator);
162}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Mark last scratch load
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:638
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
#define H(x, y, z)
Definition: MD5.cpp:57
static void printReferenceBase(raw_ostream &OS, StringRef Kind, uint64_t InternalRef, std::optional< CASID > ID)
Definition: ObjectStore.cpp:33
raw_pwrite_stream & OS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
Tagged union holding either a T or a Error.
Definition: Error.h:485
Error takeError()
Take ownership of the stored error.
Definition: Error.h:612
static ErrorOr< std::unique_ptr< MemoryBuffer > > getOpenFile(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Given an already-open file descriptor, read the file and return a MemoryBuffer.
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition: DenseSet.h:283
bool empty() const
Definition: SmallVector.h:82
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Unique identifier for a CAS object.
Definition: CASID.h:58
void dump() const
Definition: ObjectStore.cpp:23
void print(raw_ostream &OS) const
Print CASID.
Definition: CASID.h:68
std::string toString() const
Return a printable string for CASID.
Definition: ObjectStore.cpp:27
Handle to a loaded object in a ObjectStore instance.
Definition: CASReference.h:150
void print(raw_ostream &OS) const
Print internal ref and/or CASID. Only suitable for debugging.
Definition: CASReference.h:160
LLVM_DUMP_METHOD void dump() const
Definition: ObjectStore.cpp:25
static ObjectProxy load(ObjectStore &CAS, ObjectRef Ref, ObjectHandle Node)
Definition: ObjectStore.h:280
std::unique_ptr< MemoryBuffer > getMemoryBuffer(StringRef Name="", bool RequiresNullTerminator=true) const
Reference to an object in an ObjectStore instance.
Definition: CASReference.h:108
void print(raw_ostream &OS) const
Print internal ref and/or CASID. Only suitable for debugging.
Definition: CASReference.h:127
LLVM_DUMP_METHOD void dump() const
Definition: ObjectStore.cpp:24
Expected< ObjectHandle > load(ObjectRef Ref)
Like loadIfExists but returns an error if the object is missing.
Definition: ObjectStore.cpp:56
Expected< ObjectProxy > createProxy(ArrayRef< ObjectRef > Refs, StringRef Data)
Helper functions to store object and returns a ObjectProxy.
Expected< std::optional< ObjectProxy > > getProxyIfExists(ObjectRef Ref)
Definition: ObjectStore.cpp:99
virtual Expected< ObjectRef > store(ArrayRef< ObjectRef > Refs, ArrayRef< char > Data)=0
Store object into ObjectStore.
virtual ArrayRef< char > getData(ObjectHandle Node, bool RequiresNullTerminator=false) const =0
virtual CASID getID(ObjectRef Ref) const =0
Get an ID for Ref.
static Error createUnknownObjectError(const CASID &ID)
virtual Expected< std::optional< ObjectHandle > > loadIfExists(ObjectRef Ref)=0
Load the object referenced by Ref.
virtual Error validate(const CASID &ID)=0
Validate the underlying object referred by CASID.
Error validateTree(ObjectRef Ref)
Validate the whole node tree.
virtual Expected< ObjectRef > storeFromOpenFileImpl(sys::fs::file_t FD, std::optional< sys::fs::file_status > Status)
Get ObjectRef from open file.
virtual void readRefs(ObjectHandle Node, SmallVectorImpl< ObjectRef > &Refs) const
Read all the refs from object in a SmallVector.
Definition: ObjectStore.cpp:74
std::unique_ptr< MemoryBuffer > getMemoryBuffer(ObjectHandle Node, StringRef Name="", bool RequiresNullTerminator=true)
Get a lifetime-extended MemoryBuffer pointing at Data.
Definition: ObjectStore.cpp:67
virtual std::optional< ObjectRef > getReference(const CASID &ID) const =0
Get an existing reference to the object called ID.
Expected< ObjectProxy > getProxy(const CASID &ID)
Create ObjectProxy from CASID. If the object doesn't exist, get an error.
Definition: ObjectStore.cpp:82
virtual Error forEachRef(ObjectHandle Node, function_ref< Error(ObjectRef)> Callback) const =0
Methods for handling objects.
void print(raw_ostream &OS, const ObjectHandle &This) const
Definition: ObjectStore.cpp:40
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1305
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
@ Ref
The access may reference the value stored in memory.
const char * toString(DWARFSectionKind Kind)
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:111
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1083