blob: 6c8188ef6f1cf0fc73d4541f6dc99560168c67bf [file] [log] [blame]
Shih-wei Liaod1fec812012-02-13 09:51:10 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "compiler_llvm.h"
18
Shih-wei Liao26e93072012-05-30 19:13:08 -070019#include "backend_options.h"
Shih-wei Liaoc4c98812012-03-10 21:55:51 -080020#include "class_linker.h"
Logan Chien8b977d32012-02-21 19:14:55 +080021#include "compilation_unit.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080022#include "compiled_method.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080023#include "compiler.h"
Shih-wei Liaoc4c98812012-03-10 21:55:51 -080024#include "dex_cache.h"
Logan Chien0f0899a2012-03-23 10:48:18 +080025#include "elf_image.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080026#include "elf_loader.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080027#include "ir_builder.h"
Logan Chien88894ee2012-02-13 16:42:22 +080028#include "jni_compiler.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080029#include "method_compiler.h"
Logan Chien4dd96f52012-02-29 01:26:58 +080030#include "oat_compilation_unit.h"
Logan Chien0c717dd2012-03-28 18:31:07 +080031#include "oat_file.h"
Logan Chien7f767612012-03-01 18:54:49 +080032#include "stl_util.h"
TDYa127eead4ac2012-06-03 07:15:25 -070033#include "stub_compiler.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080034
Logan Chiendd7cf5b2012-03-01 12:55:19 +080035#include <llvm/LinkAllPasses.h>
36#include <llvm/LinkAllVMCore.h>
Logan Chien013b6f22012-03-02 17:20:33 +080037#include <llvm/Support/ManagedStatic.h>
Logan Chien8b977d32012-02-21 19:14:55 +080038#include <llvm/Support/TargetSelect.h>
39#include <llvm/Support/Threading.h>
40
Logan Chien013b6f22012-03-02 17:20:33 +080041namespace llvm {
42 extern bool TimePassesIsEnabled;
43}
44
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080045namespace {
Logan Chien8b977d32012-02-21 19:14:55 +080046
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080047pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;
48
49void InitializeLLVM() {
Logan Chienc3f8fa52012-05-11 11:23:39 +080050 // Initialize LLVM internal data structure for multithreading
51 llvm::llvm_start_multithreaded();
52
Logan Chien013b6f22012-03-02 17:20:33 +080053 // NOTE: Uncomment following line to show the time consumption of LLVM passes
54 //llvm::TimePassesIsEnabled = true;
55
Shih-wei Liao26e93072012-05-30 19:13:08 -070056 // Initialize LLVM target-specific options.
57 art::compiler_llvm::InitialBackendOptions();
Logan Chienc3f8fa52012-05-11 11:23:39 +080058
Logan Chien8b977d32012-02-21 19:14:55 +080059 // Initialize LLVM target, MC subsystem, asm printer, and asm parser
60 llvm::InitializeAllTargets();
61 llvm::InitializeAllTargetMCs();
62 llvm::InitializeAllAsmPrinters();
63 llvm::InitializeAllAsmParsers();
64 // TODO: Maybe we don't have to initialize "all" targets.
65
Logan Chiendd7cf5b2012-03-01 12:55:19 +080066 // Initialize LLVM optimization passes
67 llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();
68
69 llvm::initializeCore(registry);
70 llvm::initializeScalarOpts(registry);
71 llvm::initializeIPO(registry);
72 llvm::initializeAnalysis(registry);
73 llvm::initializeIPA(registry);
74 llvm::initializeTransformUtils(registry);
75 llvm::initializeInstCombine(registry);
76 llvm::initializeInstrumentation(registry);
77 llvm::initializeTarget(registry);
Logan Chien8b977d32012-02-21 19:14:55 +080078}
79
Logan Chienf1306552012-03-16 11:17:53 +080080// The Guard to Shutdown LLVM
Logan Chienaeb53032012-03-18 02:29:38 +080081// llvm::llvm_shutdown_obj llvm_guard;
82// TODO: We are commenting out this line because this will cause SEGV from
83// time to time.
84// Two reasons: (1) the order of the destruction of static objects, or
85// (2) dlopen/dlclose side-effect on static objects.
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080086
87} // anonymous namespace
88
89
90namespace art {
91namespace compiler_llvm {
Shih-wei Liaod1fec812012-02-13 09:51:10 -080092
93
Logan Chiene75a8cc2012-02-24 12:26:43 +080094llvm::Module* makeLLVMModuleContents(llvm::Module* module);
Logan Chien42e0e152012-01-13 15:42:36 +080095
96
Shih-wei Liaod1fec812012-02-13 09:51:10 -080097CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -080098 : compiler_(compiler), compiler_lock_("llvm_compiler_lock"),
Logan Chien7f767612012-03-01 18:54:49 +080099 insn_set_(insn_set), curr_cunit_(NULL) {
Shih-wei Liaofc34adb2012-03-07 08:51:44 -0800100
101
102 // Initialize LLVM libraries
103 pthread_once(&llvm_initialized, InitializeLLVM);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800104}
105
106
107CompilerLLVM::~CompilerLLVM() {
Logan Chien7f767612012-03-01 18:54:49 +0800108 STLDeleteElements(&cunits_);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800109}
110
111
Logan Chience119062012-03-02 11:57:34 +0800112void CompilerLLVM::EnsureCompilationUnit() {
Logan Chience119062012-03-02 11:57:34 +0800113 compiler_lock_.AssertHeld();
Logan Chien7f767612012-03-01 18:54:49 +0800114
115 if (curr_cunit_ != NULL) {
116 return;
Logan Chien8b977d32012-02-21 19:14:55 +0800117 }
Logan Chien7f767612012-03-01 18:54:49 +0800118
119 // Allocate compilation unit
120 size_t cunit_idx = cunits_.size();
Logan Chien6546ec52012-03-17 20:08:29 +0800121 curr_cunit_ = new CompilationUnit(insn_set_, cunit_idx);
Logan Chien7f767612012-03-01 18:54:49 +0800122
Logan Chien7f767612012-03-01 18:54:49 +0800123 // Register compilation unit
124 cunits_.push_back(curr_cunit_);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800125}
126
127
Logan Chien7f767612012-03-01 18:54:49 +0800128void CompilerLLVM::MaterializeRemainder() {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700129 compiler_lock_.Lock();
130 // Localize
131 CompilationUnit* cunit = curr_cunit_;
132 // Reset the curr_cuit_
133 curr_cunit_ = NULL;
134 compiler_lock_.Unlock();
135
136 if (cunit != NULL) {
137 Materialize(cunit);
Logan Chien7f767612012-03-01 18:54:49 +0800138 }
139}
Logan Chien8b977d32012-02-21 19:14:55 +0800140
Logan Chien8b977d32012-02-21 19:14:55 +0800141
Logan Chien7f767612012-03-01 18:54:49 +0800142void CompilerLLVM::MaterializeIfThresholdReached() {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700143 compiler_lock_.Lock();
144 // Localize
145 CompilationUnit* cunit = curr_cunit_;
146
Logan Chien7f767612012-03-01 18:54:49 +0800147 if (curr_cunit_ != NULL && curr_cunit_->IsMaterializeThresholdReached()) {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700148 // Delete the compilation unit
149 curr_cunit_ = NULL;
150 } else {
151 // Reset cunit such that Materialize() won't be invoked
152 cunit = NULL;
153 }
154
155 compiler_lock_.Unlock();
156
157 if (cunit != NULL) {
158 Materialize(cunit);
Logan Chien7f767612012-03-01 18:54:49 +0800159 }
160}
161
162
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700163void CompilerLLVM::Materialize(CompilationUnit* cunit) {
164 DCHECK(cunit != NULL);
165 DCHECK(!cunit->IsMaterialized());
Logan Chien7f767612012-03-01 18:54:49 +0800166
167 // Write bitcode to file when filename is set
168 if (IsBitcodeFileNameAvailable()) {
Shih-wei Liaodbd00342012-04-20 14:27:29 -0700169 const size_t cunit_idx = cunits_.size();
TDYa127f15b0ab2012-05-11 21:01:36 -0700170 cunit->SetBitcodeFileName(
Shih-wei Liaodbd00342012-04-20 14:27:29 -0700171 StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit_idx));
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800172 }
173
Logan Chien8b977d32012-02-21 19:14:55 +0800174 // Materialize the llvm::Module into ELF object file
Logan Chien08e1ba32012-05-08 15:08:51 +0800175 cunit->Materialize(compiler_->GetThreadCount());
Logan Chien8b977d32012-02-21 19:14:55 +0800176
Logan Chienf7015fd2012-03-18 01:19:37 +0800177 // Load ELF image when automatic ELF loading is enabled
178 if (IsAutoElfLoadingEnabled()) {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700179 LoadElfFromCompilationUnit(cunit);
Logan Chienf7015fd2012-03-18 01:19:37 +0800180 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800181}
182
183
Logan Chienf7015fd2012-03-18 01:19:37 +0800184void CompilerLLVM::EnableAutoElfLoading() {
185 MutexLock GUARD(compiler_lock_);
186
187 if (IsAutoElfLoadingEnabled()) {
188 // If there is an existing ELF loader, then do nothing.
189 // Because the existing ELF loader may have returned some code address
190 // already. If we replace the existing ELF loader with
191 // elf_loader_.reset(...), then it is possible to have some dangling
192 // pointer.
193 return;
194 }
195
196 // Create ELF loader and load the materialized CompilationUnit
197 elf_loader_.reset(new ElfLoader());
198
199 for (size_t i = 0; i < cunits_.size(); ++i) {
200 if (cunits_[i]->IsMaterialized()) {
201 LoadElfFromCompilationUnit(cunits_[i]);
202 }
203 }
204}
205
206
207void CompilerLLVM::LoadElfFromCompilationUnit(const CompilationUnit* cunit) {
Logan Chien80cd4742012-04-23 00:14:45 +0800208 MutexLock GUARD(compiler_lock_);
Logan Chienf7015fd2012-03-18 01:19:37 +0800209 DCHECK(cunit->IsMaterialized()) << cunit->GetElfIndex();
210
Logan Chien0c717dd2012-03-28 18:31:07 +0800211 if (!elf_loader_->LoadElfAt(cunit->GetElfIndex(),
212 cunit->GetElfImage(),
213 OatFile::kRelocAll)) {
Logan Chienf7015fd2012-03-18 01:19:37 +0800214 LOG(ERROR) << "Failed to load ELF from compilation unit "
215 << cunit->GetElfIndex();
216 }
217}
218
219
Logan Chien937105a2012-04-02 02:37:37 +0800220const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm) const {
221 return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(),
222 cm->GetElfFuncIndex());
Logan Chienf7015fd2012-03-18 01:19:37 +0800223}
224
225
226const Method::InvokeStub* CompilerLLVM::
Logan Chien937105a2012-04-02 02:37:37 +0800227GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const {
Logan Chien7a2a23a2012-06-06 11:01:00 +0800228 return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(),
229 cm->GetElfFuncIndex());
Logan Chienf7015fd2012-03-18 01:19:37 +0800230}
231
232
Logan Chiendf576142012-03-20 17:36:32 +0800233std::vector<ElfImage> CompilerLLVM::GetElfImages() const {
234 std::vector<ElfImage> result;
235
236 for (size_t i = 0; i < cunits_.size(); ++i) {
237 result.push_back(cunits_[i]->GetElfImage());
238 }
239
240 return result;
241}
242
243
Logan Chien7f767612012-03-01 18:54:49 +0800244CompiledMethod* CompilerLLVM::
245CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800246 MutexLock GUARD(compiler_lock_);
247
Logan Chience119062012-03-02 11:57:34 +0800248 EnsureCompilationUnit();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800249
Logan Chien8ba2fc52012-04-23 09:10:46 +0800250 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
251
Logan Chien8b977d32012-02-21 19:14:55 +0800252 UniquePtr<MethodCompiler> method_compiler(
Logan Chien7f767612012-03-01 18:54:49 +0800253 new MethodCompiler(curr_cunit_, compiler_, oat_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800254
Logan Chien7f767612012-03-01 18:54:49 +0800255 return method_compiler->Compile();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800256}
Logan Chien83426162011-12-09 09:29:50 +0800257
258
Logan Chien7f767612012-03-01 18:54:49 +0800259CompiledMethod* CompilerLLVM::
260CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
Logan Chien88894ee2012-02-13 16:42:22 +0800261 MutexLock GUARD(compiler_lock_);
262
Logan Chience119062012-03-02 11:57:34 +0800263 EnsureCompilationUnit();
Logan Chien88894ee2012-02-13 16:42:22 +0800264
Logan Chien8ba2fc52012-04-23 09:10:46 +0800265 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
266
Logan Chien8b977d32012-02-21 19:14:55 +0800267 UniquePtr<JniCompiler> jni_compiler(
Logan Chien7f767612012-03-01 18:54:49 +0800268 new JniCompiler(curr_cunit_, *compiler_, oat_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800269
Logan Chien7f767612012-03-01 18:54:49 +0800270 return jni_compiler->Compile();
Logan Chien88894ee2012-02-13 16:42:22 +0800271}
272
273
Logan Chienf04364f2012-02-10 12:01:39 +0800274CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
275 char const *shorty) {
Logan Chienf04364f2012-02-10 12:01:39 +0800276 MutexLock GUARD(compiler_lock_);
277
Logan Chience119062012-03-02 11:57:34 +0800278 EnsureCompilationUnit();
Logan Chienf04364f2012-02-10 12:01:39 +0800279
Logan Chien8ba2fc52012-04-23 09:10:46 +0800280 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
281
TDYa127eead4ac2012-06-03 07:15:25 -0700282 UniquePtr<StubCompiler> stub_compiler(
283 new StubCompiler(curr_cunit_, *compiler_));
Logan Chien8b977d32012-02-21 19:14:55 +0800284
Logan Chien7a2a23a2012-06-06 11:01:00 +0800285 return stub_compiler->CreateInvokeStub(is_static, shorty);
286}
TDYa127eead4ac2012-06-03 07:15:25 -0700287
TDYa127eead4ac2012-06-03 07:15:25 -0700288
Logan Chien7a2a23a2012-06-06 11:01:00 +0800289CompiledInvokeStub* CompilerLLVM::CreateProxyStub(char const *shorty) {
290 MutexLock GUARD(compiler_lock_);
291
292 EnsureCompilationUnit();
293
294 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
295
296 UniquePtr<StubCompiler> stub_compiler(
297 new StubCompiler(curr_cunit_, *compiler_));
298
299 return stub_compiler->CreateProxyStub(shorty);
Logan Chienf04364f2012-02-10 12:01:39 +0800300}
301
Logan Chien83426162011-12-09 09:29:50 +0800302} // namespace compiler_llvm
303} // namespace art
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800304
Logan Chien106b2a02012-03-18 04:41:38 +0800305inline static art::compiler_llvm::CompilerLLVM* ContextOf(art::Compiler& compiler) {
306 void *compiler_context = compiler.GetCompilerContext();
307 CHECK(compiler_context != NULL);
308 return reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler_context);
309}
310
311inline static const art::compiler_llvm::CompilerLLVM* ContextOf(const art::Compiler& compiler) {
312 void *compiler_context = compiler.GetCompilerContext();
313 CHECK(compiler_context != NULL);
314 return reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler_context);
315}
316
317extern "C" void ArtInitCompilerContext(art::Compiler& compiler) {
318 CHECK(compiler.GetCompilerContext() == NULL);
319
320 art::compiler_llvm::CompilerLLVM* compiler_llvm =
321 new art::compiler_llvm::CompilerLLVM(&compiler,
322 compiler.GetInstructionSet());
323
324 compiler.SetCompilerContext(compiler_llvm);
325}
326
Elliott Hughes3fa1b7e2012-03-13 17:06:22 -0700327extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800328 const art::DexFile::CodeItem* code_item,
329 uint32_t access_flags, uint32_t method_idx,
330 const art::ClassLoader* class_loader,
331 const art::DexFile& dex_file)
332{
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800333 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
334 art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
335
336 art::OatCompilationUnit oat_compilation_unit(
337 class_loader, class_linker, dex_file, *dex_cache, code_item,
338 method_idx, access_flags);
TDYa1270200d072012-04-17 20:55:08 -0700339 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
340 art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit);
341 compiler_llvm->MaterializeIfThresholdReached();
342 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800343}
344
345extern "C" art::CompiledMethod* ArtJniCompileMethod(art::Compiler& compiler,
346 uint32_t access_flags, uint32_t method_idx,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800347 const art::DexFile& dex_file) {
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800348 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
349 art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
350
351 art::OatCompilationUnit oat_compilation_unit(
Shih-wei Liaob1ab7df2012-03-29 13:53:46 -0700352 NULL, class_linker, dex_file, *dex_cache, NULL,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800353 method_idx, access_flags);
354
Logan Chien106b2a02012-03-18 04:41:38 +0800355 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
Elliott Hughes6f4976c2012-03-13 21:19:01 -0700356 art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
357 compiler_llvm->MaterializeIfThresholdReached();
Elliott Hughes13b835a2012-03-13 19:45:22 -0700358 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800359}
360
Logan Chien7a2a23a2012-06-06 11:01:00 +0800361extern "C" art::CompiledInvokeStub* ArtCreateInvokeStub(art::Compiler& compiler,
362 bool is_static,
363 const char* shorty,
364 uint32_t shorty_len) {
TDYa1270200d072012-04-17 20:55:08 -0700365 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
366 art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
367 compiler_llvm->MaterializeIfThresholdReached();
368 return result;
Logan Chien106b2a02012-03-18 04:41:38 +0800369}
370
Logan Chien7a2a23a2012-06-06 11:01:00 +0800371extern "C" art::CompiledInvokeStub* ArtCreateProxyStub(art::Compiler& compiler,
372 const char* shorty,
373 uint32_t shorty_len) {
374 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
375 art::CompiledInvokeStub* result = compiler_llvm->CreateProxyStub(shorty);
376 compiler_llvm->MaterializeIfThresholdReached();
377 return result;
378}
379
Logan Chien106b2a02012-03-18 04:41:38 +0800380extern "C" void compilerLLVMSetBitcodeFileName(art::Compiler& compiler,
381 std::string const& filename) {
382 ContextOf(compiler)->SetBitcodeFileName(filename);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800383}
384
385extern "C" void compilerLLVMMaterializeRemainder(art::Compiler& compiler) {
Logan Chien106b2a02012-03-18 04:41:38 +0800386 ContextOf(compiler)->MaterializeRemainder();
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800387}
388
Logan Chienf7015fd2012-03-18 01:19:37 +0800389extern "C" void compilerLLVMEnableAutoElfLoading(art::Compiler& compiler) {
390 art::compiler_llvm::CompilerLLVM* compiler_llvm =
391 reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
392 return compiler_llvm->EnableAutoElfLoading();
393}
394
395extern "C" const void* compilerLLVMGetMethodCodeAddr(const art::Compiler& compiler,
396 const art::CompiledMethod* cm,
Logan Chien937105a2012-04-02 02:37:37 +0800397 const art::Method*) {
Logan Chienf7015fd2012-03-18 01:19:37 +0800398 const art::compiler_llvm::CompilerLLVM* compiler_llvm =
399 reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
Logan Chien937105a2012-04-02 02:37:37 +0800400 return compiler_llvm->GetMethodCodeAddr(cm);
Logan Chienf7015fd2012-03-18 01:19:37 +0800401}
402
403extern "C" const art::Method::InvokeStub* compilerLLVMGetMethodInvokeStubAddr(const art::Compiler& compiler,
404 const art::CompiledInvokeStub* cm,
Logan Chien937105a2012-04-02 02:37:37 +0800405 const art::Method*) {
Logan Chienf7015fd2012-03-18 01:19:37 +0800406 const art::compiler_llvm::CompilerLLVM* compiler_llvm =
407 reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
Logan Chien937105a2012-04-02 02:37:37 +0800408 return compiler_llvm->GetMethodInvokeStubAddr(cm);
Logan Chienf7015fd2012-03-18 01:19:37 +0800409}
410
Logan Chiendf576142012-03-20 17:36:32 +0800411extern "C" std::vector<art::ElfImage> compilerLLVMGetElfImages(const art::Compiler& compiler) {
412 return ContextOf(compiler)->GetElfImages();
413}
414
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800415extern "C" void compilerLLVMDispose(art::Compiler& compiler) {
Logan Chien106b2a02012-03-18 04:41:38 +0800416 delete ContextOf(compiler);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800417}