20
20
#include " llvm/Transforms/Scalar.h"
21
21
#include " llvm/Transforms/IPO.h"
22
22
#include " llvm/ADT/Triple.h"
23
+ #include " llvm/ADT/DenseSet.h"
23
24
#include " llvm/Assembly/Parser.h"
24
25
#include " llvm/Assembly/PrintModulePass.h"
25
26
#include " llvm/Support/FormattedStream.h"
42
43
#include " llvm-c/Core.h"
43
44
#include " llvm-c/BitReader.h"
44
45
#include " llvm-c/Object.h"
45
- #include < cstdlib>
46
46
47
47
// Used by RustMCJITMemoryManager::getPointerToNamedFunction()
48
48
// to get around glibc issues. See the function for more information.
53
53
#endif
54
54
55
55
using namespace llvm ;
56
+ using namespace llvm ::sys;
56
57
57
58
static const char *LLVMRustError;
58
59
@@ -100,18 +101,6 @@ void LLVMRustInitializeTargets() {
100
101
LLVMInitializeX86AsmParser ();
101
102
}
102
103
103
- extern " C" bool
104
- LLVMRustLoadLibrary (const char * file) {
105
- std::string err;
106
-
107
- if (llvm::sys::DynamicLibrary::LoadLibraryPermanently (file, &err)) {
108
- LLVMRustError = err.c_str ();
109
- return false ;
110
- }
111
-
112
- return true ;
113
- }
114
-
115
104
// Custom memory manager for MCJITting. It needs special features
116
105
// that the generic JIT memory manager doesn't entail. Based on
117
106
// code from LLI, change where needed for Rust.
@@ -121,10 +110,13 @@ class RustMCJITMemoryManager : public JITMemoryManager {
121
110
SmallVector<sys::MemoryBlock, 16 > AllocatedCodeMem;
122
111
SmallVector<sys::MemoryBlock, 16 > FreeCodeMem;
123
112
void * __morestack;
113
+ DenseSet<DynamicLibrary*> crates;
124
114
125
115
RustMCJITMemoryManager (void * sym) : __morestack(sym) { }
126
116
~RustMCJITMemoryManager ();
127
117
118
+ bool loadCrate (const char *, std::string*);
119
+
128
120
virtual uint8_t *allocateCodeSection (uintptr_t Size, unsigned Alignment,
129
121
unsigned SectionID);
130
122
@@ -197,6 +189,19 @@ class RustMCJITMemoryManager : public JITMemoryManager {
197
189
}
198
190
};
199
191
192
+ bool RustMCJITMemoryManager::loadCrate (const char * file, std::string* err) {
193
+ DynamicLibrary crate = DynamicLibrary::getPermanentLibrary (file,
194
+ err);
195
+
196
+ if (crate.isValid ()) {
197
+ crates.insert (&crate);
198
+
199
+ return true ;
200
+ }
201
+
202
+ return false ;
203
+ }
204
+
200
205
uint8_t *RustMCJITMemoryManager::allocateDataSection (uintptr_t Size,
201
206
unsigned Alignment,
202
207
unsigned SectionID) {
@@ -276,6 +281,19 @@ void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
276
281
if (Name == " __morestack" ) return &__morestack;
277
282
278
283
const char *NameStr = Name.c_str ();
284
+
285
+ // Look through loaded crates for symbols.
286
+
287
+ for (DenseSet<DynamicLibrary*>::iterator I = crates.begin (),
288
+ E = crates.end (); I != E; ++I) {
289
+ void *Ptr = (*I)->getAddressOfSymbol (NameStr);
290
+
291
+ if (Ptr) return Ptr;
292
+ }
293
+
294
+ // Fallback to using any symbols LLVM has loaded (generally
295
+ // from the main program).
296
+
279
297
void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol (NameStr);
280
298
if (Ptr) return Ptr;
281
299
@@ -293,11 +311,34 @@ RustMCJITMemoryManager::~RustMCJITMemoryManager() {
293
311
}
294
312
295
313
extern " C" void *
296
- LLVMRustJIT (void * __morestack,
297
- LLVMPassManagerRef PMR,
298
- LLVMModuleRef M,
299
- CodeGenOpt::Level OptLevel,
300
- bool EnableSegmentedStacks) {
314
+ LLVMRustPrepareJIT (void * __morestack) {
315
+ // An execution engine will take ownership of this later
316
+ // and clean it up for us.
317
+
318
+ return (void *) new RustMCJITMemoryManager (__morestack);
319
+ }
320
+
321
+ extern " C" bool
322
+ LLVMRustLoadCrate (void * mem, const char * crate) {
323
+ RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem;
324
+ std::string Err;
325
+
326
+ assert (manager);
327
+
328
+ if (!manager->loadCrate (crate, &Err)) {
329
+ LLVMRustError = Err.c_str ();
330
+ return false ;
331
+ }
332
+
333
+ return true ;
334
+ }
335
+
336
+ extern " C" void *
337
+ LLVMRustExecuteJIT (void * mem,
338
+ LLVMPassManagerRef PMR,
339
+ LLVMModuleRef M,
340
+ CodeGenOpt::Level OptLevel,
341
+ bool EnableSegmentedStacks) {
301
342
302
343
InitializeNativeTarget ();
303
344
InitializeNativeTargetAsmPrinter ();
@@ -308,6 +349,9 @@ LLVMRustJIT(void* __morestack,
308
349
Options.NoFramePointerElim = true ;
309
350
Options.EnableSegmentedStacks = EnableSegmentedStacks;
310
351
PassManager *PM = unwrap<PassManager>(PMR);
352
+ RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem;
353
+
354
+ assert (MM);
311
355
312
356
PM->add (createBasicAliasAnalysisPass ());
313
357
PM->add (createInstructionCombiningPass ());
@@ -318,7 +362,6 @@ LLVMRustJIT(void* __morestack,
318
362
PM->add (createPromoteMemoryToRegisterPass ());
319
363
PM->run (*unwrap (M));
320
364
321
- RustMCJITMemoryManager* MM = new RustMCJITMemoryManager (__morestack);
322
365
ExecutionEngine* EE = EngineBuilder (unwrap (M))
323
366
.setTargetOptions (Options)
324
367
.setJITMemoryManager (MM)
0 commit comments