llvm.org GIT mirror llvm / d9900c9
My previous Registry.h header, as well as Collectors.h, which is the registry for dynamically-loaded garbage collection compiler plugins. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42415 91177308-0d34-0410-b5e6-96231b3b80d8 Gordon Henriksen 12 years ago
3 changed file(s) with 300 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===-- Collectors.h - Garbage collector registry -------------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Gordon Henriksen and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the CollectorRegistry class, which is used to discover
10 // pluggable garbage collectors.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CODEGEN_COLLECTORS_H
15 #define LLVM_CODEGEN_COLLECTORS_H
16
17 #include "llvm/Support/Registry.h"
18
19 namespace llvm {
20
21 class Collector;
22
23 /// The collector registry uses all the defaults from Registry.
24 ///
25 typedef Registry CollectorRegistry;
26
27 /// Creates an ocaml-compatible garbage collector.
28 Collector *createOcamlCollector();
29
30 /// Creates a shadow stack garbage collector. This collector requires no code
31 /// generator support.
32 Collector *createShadowStackCollector();
33 }
34
35 #endif
0 //=== Registry.h - Linker-supported plugin registries -----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Gordon Henriksen and is distributed under the
5 // University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Defines a registry template for discovering pluggable modules.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_SUPPORT_REGISTRY_H
14 #define LLVM_SUPPORT_REGISTRY_H
15
16 #include "llvm/Support/CommandLine.h"
17
18 namespace llvm {
19 /// A simple registry entry which provides only a name, description, and
20 /// no-argument constructor.
21 template
22 class SimpleRegistryEntry {
23 const char *Name, *Desc;
24 T *(*Ctor)();
25
26 public:
27 SimpleRegistryEntry(const char *N, const char *D, T *(*C)())
28 : Name(N), Desc(D), Ctor(C)
29 {}
30
31 const char *getName() const { return Name; }
32 const char *getDesc() const { return Desc; }
33 T *instantiate() const { return Ctor(); }
34 };
35
36
37 /// Traits for registry entries. If using other than SimpleRegistryEntry, it
38 /// is necessary to define an alternate traits class.
39 template
40 class RegistryTraits {
41 RegistryTraits(); // Do not implement.
42
43 public:
44 typedef SimpleRegistryEntry entry;
45
46 /// Accessors for .
47 ///
48 static const char *nameof(const entry &Entry) { return Entry.getName(); }
49 static const char *descof(const entry &Entry) { return Entry.getDesc(); }
50 };
51
52
53 /// A global registry used in conjunction with static constructors to make
54 /// pluggable components (like targets or garbage collectors) "just work" when
55 /// linked with an executable.
56 template >
57 class Registry {
58 public:
59 typedef U traits;
60 typedef typename U::entry entry;
61
62 class node;
63 class listener;
64 class iterator;
65
66 private:
67 Registry(); // Do not implement.
68
69 static void Announce(node *);
70
71 friend class node;
72 static node *Head, *Tail;
73
74 friend class listener;
75 static listener *ListenerHead, *ListenerTail;
76
77 public:
78 class iterator;
79
80
81 /// Node in linked list of entries.
82 ///
83 class node {
84 friend class iterator;
85
86 node *Next;
87 const entry& Val;
88
89 public:
90 node(const entry& V) : Next(0), Val(V) {
91 if (Tail)
92 Tail->Next = this;
93 else
94 Head = this;
95 Tail = this;
96
97 Announce(V);
98 }
99 };
100
101
102 /// Iterators for registry entries.
103 ///
104 class iterator {
105 const node *Cur;
106
107 public:
108 explicit iterator(const node *N) : Cur(N) {}
109
110 bool operator==(const iterator &That) const { return Cur == That.Cur; }
111 bool operator!=(const iterator &That) const { return Cur != That.Cur; }
112 iterator &operator++() { Cur = Cur->Next; return *this; }
113 const entry &operator*() const { return Cur->Val; }
114 const entry *operator->() const { return &Cur->Val; }
115 };
116
117 static iterator begin() { return iterator(Head); }
118 static iterator end() { return iterator(0); }
119
120
121 /// Abstract base class for registry listeners, which are informed when new
122 /// entries are added to the registry. Simply subclass and instantiate:
123 ///
124 /// class CollectorPrinter : public Registry::listener {
125 /// protected:
126 /// void registered(const Registry::entry &e) {
127 /// cerr << "collector now available: " << e->getName() << "\n";
128 /// }
129 ///
130 /// public:
131 /// CollectorPrinter() { init(); } // Print those already registered.
132 /// };
133 ///
134 /// CollectorPrinter Printer;
135 ///
136 class listener {
137 listener *Prev, *Next;
138
139 friend void Registry::Announce(const entry &E);
140
141 protected:
142 /// Called when an entry is added to the registry.
143 ///
144 virtual void registered(const entry &) = 0;
145
146 /// Calls 'registered' for each pre-existing entry.
147 ///
148 void init() {
149 for (iterator I = begin(), E = end(); I != E; ++I)
150 registered(*I);
151 }
152
153 public:
154 listener() : Prev(ListenerTail), Next(0) {
155 if (Prev)
156 Prev->Next = this;
157 else
158 ListenerHead = this;
159 ListenerTail = this;
160 }
161
162 virtual ~listener() {
163 if (Next)
164 Next->Prev = Prev;
165 else
166 ListenerTail = Prev;
167 if (Prev)
168 Prev->Next = Next;
169 else
170 ListenerHead = Next;
171 }
172 };
173
174
175 /// A static registration template. Use like such:
176 ///
177 /// Registry::Add
178 /// X("fancy-gc", "Newfangled garbage collector.");
179 ///
180 /// Use of this template requires that:
181 ///
182 /// 1. The registered subclass has a default constructor.
183 //
184 /// 2. The registry entry type has a constructor compatible with this
185 /// signature:
186 ///
187 /// entry(const char *Name, const char *ShortDesc, T *(*Ctor)());
188 ///
189 /// If you have more elaborate requirements, then copy and modify.
190 ///
191 template
192 class Add {
193 entry Entry;
194 node Node;
195
196 static T *CtorFn() { return new V(); }
197
198 public:
199 Add(const char *Name, const char *Desc)
200 : Entry(Name, Desc, CtorFn), Node(Entry) {}
201 };
202
203
204 /// A command-line parser for a registry. Use like such:
205 ///
206 /// static cl::opt::entry, false,
207 /// Registry::Parser>
208 /// GCOpt("gc", cl::desc("Garbage collector to use."),
209 /// cl::value_desc());
210 ///
211 /// To make use of the value:
212 ///
213 /// Collector *TheCollector = GCOpt->instantiate();
214 ///
215 class Parser : public cl::parser, public listener{
216 typedef U traits;
217 typedef typename U::entry entry;
218
219 protected:
220 void registered(const entry &E) {
221 addLiteralOption(traits::nameof(E), &E, traits::descof(E));
222 }
223
224 public:
225 void initialize(cl::Option &O) {
226 listener::init();
227 cl::parser::initialize(O);
228 }
229 };
230
231
232 private:
233 static void Announce(const entry &E) {
234 for (listener *Cur = ListenerHead; Cur; Cur = Cur->Next)
235 Cur->registered(E);
236 }
237
238 };
239
240 }
241
242 #endif
0 //===-- Collectors.cpp - Garbage collector registry -----------------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by Gordon Henriksen and is distributed under
5 // the University of Illinois Open Source License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the static data members of the CollectorRegistry class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/CodeGen/Collectors.h"
14
15 using namespace llvm;
16
17 template<> CollectorRegistry::node *CollectorRegistry::Head = 0;
18 template<> CollectorRegistry::node *CollectorRegistry::Tail = 0;
19 template<> CollectorRegistry::listener *CollectorRegistry::ListenerHead = 0;
20 template<> CollectorRegistry::listener *CollectorRegistry::ListenerTail = 0;