[llvm] Make the 'llvm_types' hashtable per-domain to fix memory leaks.
[mono.git] / mono / mini / mini-llvm.h
1 /*
2  * Handle the differences between the llvm backend beeing embedded
3  * or loaded at runtime.
4  */
5 #ifdef MONO_LLVM_LOADED
6
7 int mono_llvm_load (const char* bpath) MONO_INTERNAL;
8
9 #ifdef MONO_LLVM_IN_MINI
10
11 #ifdef __MACH__
12 #include <mach-o/dyld.h>
13 #endif
14
15 typedef void (*MonoLLVMVoidFunc)(void);
16 typedef void (*MonoLLVMCFGFunc)(MonoCompile *cfg);
17 typedef void (*MonoLLVMEmitCallFunc)(MonoCompile *cfg, MonoCallInst *call);
18 typedef void (*MonoLLVMCreateAotFunc)(const char *got_symbol);
19 typedef void (*MonoLLVMEmitAotFunc)(const char *filename, int got_size);
20 typedef void (*MonoLLVMFreeDomainFunc)(MonoDomain *domain);
21
22 static MonoLLVMVoidFunc mono_llvm_init_fptr;
23 static MonoLLVMVoidFunc mono_llvm_cleanup_fptr;
24 static MonoLLVMCFGFunc mono_llvm_emit_method_fptr;
25 static MonoLLVMEmitCallFunc mono_llvm_emit_call_fptr;
26 static MonoLLVMCreateAotFunc mono_llvm_create_aot_module_fptr;
27 static MonoLLVMEmitAotFunc mono_llvm_emit_aot_module_fptr;
28 static MonoLLVMCFGFunc mono_llvm_check_method_supported_fptr;
29 static MonoLLVMFreeDomainFunc mono_llvm_free_domain_info_fptr;
30
31 void
32 mono_llvm_init (void)
33 {
34         mono_llvm_init_fptr ();
35 }
36
37 void
38 mono_llvm_cleanup (void)
39 {
40         mono_llvm_cleanup_fptr ();
41 }
42
43 void
44 mono_llvm_emit_method (MonoCompile *cfg)
45 {
46         mono_llvm_emit_method_fptr (cfg);
47 }
48
49 void
50 mono_llvm_emit_call (MonoCompile *cfg, MonoCallInst *call)
51 {
52         mono_llvm_emit_call_fptr (cfg, call);
53 }
54
55 void
56 mono_llvm_create_aot_module (const char *got_symbol)
57 {
58         g_assert (mono_llvm_create_aot_module_fptr);
59         mono_llvm_create_aot_module_fptr (got_symbol);
60 }
61
62 void
63 mono_llvm_emit_aot_module (const char *filename, int got_size)
64 {
65         g_assert (mono_llvm_emit_aot_module_fptr);
66         mono_llvm_emit_aot_module_fptr (filename, got_size);
67 }
68
69 void
70 mono_llvm_check_method_supported (MonoCompile *cfg)
71 {
72         mono_llvm_check_method_supported_fptr (cfg);
73 }
74
75 void
76 mono_llvm_free_domain_info (MonoDomain *domain)
77 {
78         mono_llvm_free_domain_info_fptr (domain);
79 }
80
81 static MonoDl*
82 try_llvm_load (char *dir, char **err)
83 {
84         gpointer iter;
85         MonoDl *llvm_lib;
86         char *path;
87         iter = NULL;
88         *err = NULL;
89         while ((path = mono_dl_build_path (dir, "mono-llvm", &iter))) {
90                 g_free (*err);
91                 llvm_lib = mono_dl_open (path, MONO_DL_LAZY, err);
92                 g_free (path);
93                 if (llvm_lib)
94                         return llvm_lib;
95         }
96         return NULL;
97 }
98
99 int
100 mono_llvm_load (const char* bpath)
101 {
102         MonoDl *llvm_lib = NULL;
103         char *err;
104         char buf [4096];
105         int binl;
106         binl = readlink ("/proc/self/exe", buf, sizeof (buf)-1);
107 #ifdef __MACH__
108         if (binl == -1) {
109                 uint32_t bsize = sizeof (buf);
110                 if (_NSGetExecutablePath (buf, &bsize) == 0) {
111                         binl = strlen (buf);
112                 }
113         }
114 #endif
115         if (binl != -1) {
116                 char *base;
117                 char *resolvedname, *name;
118                 buf [binl] = 0;
119                 resolvedname = mono_path_resolve_symlinks (buf);
120                 base = g_path_get_dirname (resolvedname);
121                 name = g_strdup_printf ("%s/.libs", base);
122                 err = NULL;
123                 llvm_lib = try_llvm_load (name, &err);
124                 g_free (name);
125                 if (!llvm_lib) {
126                         char *newbase = g_path_get_dirname (base);
127                         name = g_strdup_printf ("%s/lib", newbase);
128                         err = NULL;
129                         llvm_lib = try_llvm_load (name, &err);
130                         g_free (name);
131                 }
132 #ifdef __MACH__
133                 if (!llvm_lib) {
134                         char *newbase = g_path_get_dirname (base);
135                         name = g_strdup_printf ("%s/Libraries", newbase);
136                         err = NULL;
137                         llvm_lib = try_llvm_load (name, &err);
138                         g_free (name);
139                 }
140 #endif
141                 g_free (base);
142                 g_free (resolvedname);
143         }
144         if (!llvm_lib) {
145                 llvm_lib = try_llvm_load (NULL, &err);
146                 if (!llvm_lib) {
147                         g_warning ("llvm load failed: %s\n", err);
148                         g_free (err);
149                         return FALSE;
150                 }
151         }
152         err = mono_dl_symbol (llvm_lib, "mono_llvm_init", (void**)&mono_llvm_init_fptr);
153         if (err) goto symbol_error;
154         err = mono_dl_symbol (llvm_lib, "mono_llvm_cleanup", (void**)&mono_llvm_cleanup_fptr);
155         if (err) goto symbol_error;
156         err = mono_dl_symbol (llvm_lib, "mono_llvm_emit_method", (void**)&mono_llvm_emit_method_fptr);
157         if (err) goto symbol_error;
158         err = mono_dl_symbol (llvm_lib, "mono_llvm_emit_call", (void**)&mono_llvm_emit_call_fptr);
159         if (err) goto symbol_error;
160         err = mono_dl_symbol (llvm_lib, "mono_llvm_create_aot_module", (void**)&mono_llvm_create_aot_module_fptr);
161         if (err) goto symbol_error;
162         err = mono_dl_symbol (llvm_lib, "mono_llvm_emit_aot_module", (void**)&mono_llvm_emit_aot_module_fptr);
163         if (err) goto symbol_error;
164         err = mono_dl_symbol (llvm_lib, "mono_llvm_check_method_supported", (void**)&mono_llvm_check_method_supported_fptr);
165         if (err) goto symbol_error;
166         err = mono_dl_symbol (llvm_lib, "mono_llvm_free_domain_info", (void**)&mono_llvm_free_domain_info_fptr);
167         if (err) goto symbol_error;
168         return TRUE;
169 symbol_error:
170         g_warning ("llvm symbol load failed: %s\n", err);
171         g_free (err);
172         return FALSE;
173 }
174
175 #endif
176
177 #else
178 #define mono_llvm_load(bpath) TRUE
179 #endif /* MONO_LLVM_LOADED */
180