blob: ca0a4dac3eabdd71bc67b30d3a605ead6d123c47 [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 Liaoc4c98812012-03-10 21:55:51 -080019#include "class_linker.h"
Logan Chien8b977d32012-02-21 19:14:55 +080020#include "compilation_unit.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080021#include "compiled_method.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080022#include "compiler.h"
Shih-wei Liaoc4c98812012-03-10 21:55:51 -080023#include "dex_cache.h"
Logan Chien0f0899a2012-03-23 10:48:18 +080024#include "elf_image.h"
Logan Chienf7015fd2012-03-18 01:19:37 +080025#include "elf_loader.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080026#include "ir_builder.h"
Logan Chien88894ee2012-02-13 16:42:22 +080027#include "jni_compiler.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080028#include "method_compiler.h"
Logan Chien4dd96f52012-02-29 01:26:58 +080029#include "oat_compilation_unit.h"
Logan Chien0c717dd2012-03-28 18:31:07 +080030#include "oat_file.h"
Logan Chien7f767612012-03-01 18:54:49 +080031#include "stl_util.h"
Logan Chienf04364f2012-02-10 12:01:39 +080032#include "upcall_compiler.h"
Shih-wei Liaod1fec812012-02-13 09:51:10 -080033
Logan Chiendd7cf5b2012-03-01 12:55:19 +080034#include <llvm/LinkAllPasses.h>
35#include <llvm/LinkAllVMCore.h>
Logan Chien4c17dff2012-03-02 20:15:46 +080036#include <llvm/Support/CommandLine.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
Logan Chien4c17dff2012-03-02 20:15:46 +080045// NOTE: Although EnableARMLongCalls is defined in llvm/lib/Target/ARM/
46// ARMISelLowering.cpp, however, it is not in the llvm namespace.
Shih-wei Liao17765722012-04-17 16:42:19 -070047extern llvm::cl::opt<bool> EnableARMLongCalls;
48
49// ReserveR9 is defined in llvm/lib/Target/ARM/ARMSubtarget.cpp
50extern llvm::cl::opt<bool> ReserveR9;
Logan Chien4c17dff2012-03-02 20:15:46 +080051
Logan Chien8b977d32012-02-21 19:14:55 +080052
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080053namespace {
Logan Chien8b977d32012-02-21 19:14:55 +080054
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080055pthread_once_t llvm_initialized = PTHREAD_ONCE_INIT;
56
57void InitializeLLVM() {
Logan Chien013b6f22012-03-02 17:20:33 +080058 // NOTE: Uncomment following line to show the time consumption of LLVM passes
59 //llvm::TimePassesIsEnabled = true;
60
TDYa127d668a062012-04-13 12:36:57 -070061 // Enable -arm-reserve-r9
62 ReserveR9 = true;
63
Logan Chien8b977d32012-02-21 19:14:55 +080064 // Initialize LLVM target, MC subsystem, asm printer, and asm parser
65 llvm::InitializeAllTargets();
66 llvm::InitializeAllTargetMCs();
67 llvm::InitializeAllAsmPrinters();
68 llvm::InitializeAllAsmParsers();
69 // TODO: Maybe we don't have to initialize "all" targets.
70
Logan Chien4c17dff2012-03-02 20:15:46 +080071 // Enable -arm-long-calls
Shih-wei Liao17765722012-04-17 16:42:19 -070072 EnableARMLongCalls = false;
Logan Chien4c17dff2012-03-02 20:15:46 +080073
Logan Chiendd7cf5b2012-03-01 12:55:19 +080074 // Initialize LLVM optimization passes
75 llvm::PassRegistry &registry = *llvm::PassRegistry::getPassRegistry();
76
77 llvm::initializeCore(registry);
78 llvm::initializeScalarOpts(registry);
79 llvm::initializeIPO(registry);
80 llvm::initializeAnalysis(registry);
81 llvm::initializeIPA(registry);
82 llvm::initializeTransformUtils(registry);
83 llvm::initializeInstCombine(registry);
84 llvm::initializeInstrumentation(registry);
85 llvm::initializeTarget(registry);
86
Logan Chien8b977d32012-02-21 19:14:55 +080087 // Initialize LLVM internal data structure for multithreading
88 llvm::llvm_start_multithreaded();
89}
90
Logan Chienf1306552012-03-16 11:17:53 +080091// The Guard to Shutdown LLVM
Logan Chienaeb53032012-03-18 02:29:38 +080092// llvm::llvm_shutdown_obj llvm_guard;
93// TODO: We are commenting out this line because this will cause SEGV from
94// time to time.
95// Two reasons: (1) the order of the destruction of static objects, or
96// (2) dlopen/dlclose side-effect on static objects.
Shih-wei Liaofc34adb2012-03-07 08:51:44 -080097
98} // anonymous namespace
99
100
101namespace art {
102namespace compiler_llvm {
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800103
104
Logan Chiene75a8cc2012-02-24 12:26:43 +0800105llvm::Module* makeLLVMModuleContents(llvm::Module* module);
Logan Chien42e0e152012-01-13 15:42:36 +0800106
107
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800108CompilerLLVM::CompilerLLVM(Compiler* compiler, InstructionSet insn_set)
Shih-wei Liao5b8b1ed2012-02-23 23:48:21 -0800109 : compiler_(compiler), compiler_lock_("llvm_compiler_lock"),
Logan Chien7f767612012-03-01 18:54:49 +0800110 insn_set_(insn_set), curr_cunit_(NULL) {
Shih-wei Liaofc34adb2012-03-07 08:51:44 -0800111
112
113 // Initialize LLVM libraries
114 pthread_once(&llvm_initialized, InitializeLLVM);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800115}
116
117
118CompilerLLVM::~CompilerLLVM() {
Logan Chien7f767612012-03-01 18:54:49 +0800119 STLDeleteElements(&cunits_);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800120}
121
122
Logan Chience119062012-03-02 11:57:34 +0800123void CompilerLLVM::EnsureCompilationUnit() {
Logan Chience119062012-03-02 11:57:34 +0800124 compiler_lock_.AssertHeld();
Logan Chien7f767612012-03-01 18:54:49 +0800125
126 if (curr_cunit_ != NULL) {
127 return;
Logan Chien8b977d32012-02-21 19:14:55 +0800128 }
Logan Chien7f767612012-03-01 18:54:49 +0800129
130 // Allocate compilation unit
131 size_t cunit_idx = cunits_.size();
Logan Chien6546ec52012-03-17 20:08:29 +0800132 curr_cunit_ = new CompilationUnit(insn_set_, cunit_idx);
Logan Chien7f767612012-03-01 18:54:49 +0800133
Logan Chien7f767612012-03-01 18:54:49 +0800134 // Register compilation unit
135 cunits_.push_back(curr_cunit_);
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800136}
137
138
Logan Chien7f767612012-03-01 18:54:49 +0800139void CompilerLLVM::MaterializeRemainder() {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700140 compiler_lock_.Lock();
141 // Localize
142 CompilationUnit* cunit = curr_cunit_;
143 // Reset the curr_cuit_
144 curr_cunit_ = NULL;
145 compiler_lock_.Unlock();
146
147 if (cunit != NULL) {
148 Materialize(cunit);
Logan Chien7f767612012-03-01 18:54:49 +0800149 }
150}
Logan Chien8b977d32012-02-21 19:14:55 +0800151
Logan Chien8b977d32012-02-21 19:14:55 +0800152
Logan Chien7f767612012-03-01 18:54:49 +0800153void CompilerLLVM::MaterializeIfThresholdReached() {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700154 compiler_lock_.Lock();
155 // Localize
156 CompilationUnit* cunit = curr_cunit_;
157
Logan Chien7f767612012-03-01 18:54:49 +0800158 if (curr_cunit_ != NULL && curr_cunit_->IsMaterializeThresholdReached()) {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700159 // Delete the compilation unit
160 curr_cunit_ = NULL;
161 } else {
162 // Reset cunit such that Materialize() won't be invoked
163 cunit = NULL;
164 }
165
166 compiler_lock_.Unlock();
167
168 if (cunit != NULL) {
169 Materialize(cunit);
Logan Chien7f767612012-03-01 18:54:49 +0800170 }
171}
172
173
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700174void CompilerLLVM::Materialize(CompilationUnit* cunit) {
175 DCHECK(cunit != NULL);
176 DCHECK(!cunit->IsMaterialized());
Logan Chien7f767612012-03-01 18:54:49 +0800177
178 // Write bitcode to file when filename is set
179 if (IsBitcodeFileNameAvailable()) {
Shih-wei Liaodbd00342012-04-20 14:27:29 -0700180 const size_t cunit_idx = cunits_.size();
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700181 cunit->WriteBitcodeToFile(
Shih-wei Liaodbd00342012-04-20 14:27:29 -0700182 StringPrintf("%s-%zu", bitcode_filename_.c_str(), cunit_idx));
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800183 }
184
Logan Chien8b977d32012-02-21 19:14:55 +0800185 // Materialize the llvm::Module into ELF object file
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700186 cunit->Materialize();
Logan Chien8b977d32012-02-21 19:14:55 +0800187
Logan Chienf7015fd2012-03-18 01:19:37 +0800188 // Load ELF image when automatic ELF loading is enabled
189 if (IsAutoElfLoadingEnabled()) {
Shih-wei Liao766b0bf2012-04-20 15:27:44 -0700190 LoadElfFromCompilationUnit(cunit);
Logan Chienf7015fd2012-03-18 01:19:37 +0800191 }
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800192}
193
194
Logan Chienf7015fd2012-03-18 01:19:37 +0800195void CompilerLLVM::EnableAutoElfLoading() {
196 MutexLock GUARD(compiler_lock_);
197
198 if (IsAutoElfLoadingEnabled()) {
199 // If there is an existing ELF loader, then do nothing.
200 // Because the existing ELF loader may have returned some code address
201 // already. If we replace the existing ELF loader with
202 // elf_loader_.reset(...), then it is possible to have some dangling
203 // pointer.
204 return;
205 }
206
207 // Create ELF loader and load the materialized CompilationUnit
208 elf_loader_.reset(new ElfLoader());
209
210 for (size_t i = 0; i < cunits_.size(); ++i) {
211 if (cunits_[i]->IsMaterialized()) {
212 LoadElfFromCompilationUnit(cunits_[i]);
213 }
214 }
215}
216
217
218void CompilerLLVM::LoadElfFromCompilationUnit(const CompilationUnit* cunit) {
Logan Chien80cd4742012-04-23 00:14:45 +0800219 MutexLock GUARD(compiler_lock_);
Logan Chienf7015fd2012-03-18 01:19:37 +0800220 DCHECK(cunit->IsMaterialized()) << cunit->GetElfIndex();
221
Logan Chien0c717dd2012-03-28 18:31:07 +0800222 if (!elf_loader_->LoadElfAt(cunit->GetElfIndex(),
223 cunit->GetElfImage(),
224 OatFile::kRelocAll)) {
Logan Chienf7015fd2012-03-18 01:19:37 +0800225 LOG(ERROR) << "Failed to load ELF from compilation unit "
226 << cunit->GetElfIndex();
227 }
228}
229
230
Logan Chien937105a2012-04-02 02:37:37 +0800231const void* CompilerLLVM::GetMethodCodeAddr(const CompiledMethod* cm) const {
232 return elf_loader_->GetMethodCodeAddr(cm->GetElfIndex(),
233 cm->GetElfFuncIndex());
Logan Chienf7015fd2012-03-18 01:19:37 +0800234}
235
236
237const Method::InvokeStub* CompilerLLVM::
Logan Chien937105a2012-04-02 02:37:37 +0800238GetMethodInvokeStubAddr(const CompiledInvokeStub* cm) const {
239 return elf_loader_->GetMethodInvokeStubAddr(cm->GetElfIndex(),
240 cm->GetElfFuncIndex());
Logan Chienf7015fd2012-03-18 01:19:37 +0800241}
242
243
Logan Chiendf576142012-03-20 17:36:32 +0800244std::vector<ElfImage> CompilerLLVM::GetElfImages() const {
245 std::vector<ElfImage> result;
246
247 for (size_t i = 0; i < cunits_.size(); ++i) {
248 result.push_back(cunits_[i]->GetElfImage());
249 }
250
251 return result;
252}
253
254
Logan Chien7f767612012-03-01 18:54:49 +0800255CompiledMethod* CompilerLLVM::
256CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800257 MutexLock GUARD(compiler_lock_);
258
Logan Chience119062012-03-02 11:57:34 +0800259 EnsureCompilationUnit();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800260
Logan Chien8ba2fc52012-04-23 09:10:46 +0800261 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
262
Logan Chien8b977d32012-02-21 19:14:55 +0800263 UniquePtr<MethodCompiler> method_compiler(
Logan Chien7f767612012-03-01 18:54:49 +0800264 new MethodCompiler(curr_cunit_, compiler_, oat_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800265
Logan Chien7f767612012-03-01 18:54:49 +0800266 return method_compiler->Compile();
Shih-wei Liaod1fec812012-02-13 09:51:10 -0800267}
Logan Chien83426162011-12-09 09:29:50 +0800268
269
Logan Chien7f767612012-03-01 18:54:49 +0800270CompiledMethod* CompilerLLVM::
271CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
Logan Chien88894ee2012-02-13 16:42:22 +0800272 MutexLock GUARD(compiler_lock_);
273
Logan Chience119062012-03-02 11:57:34 +0800274 EnsureCompilationUnit();
Logan Chien88894ee2012-02-13 16:42:22 +0800275
Logan Chien8ba2fc52012-04-23 09:10:46 +0800276 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
277
Logan Chien8b977d32012-02-21 19:14:55 +0800278 UniquePtr<JniCompiler> jni_compiler(
Logan Chien7f767612012-03-01 18:54:49 +0800279 new JniCompiler(curr_cunit_, *compiler_, oat_compilation_unit));
Logan Chien8b977d32012-02-21 19:14:55 +0800280
Logan Chien7f767612012-03-01 18:54:49 +0800281 return jni_compiler->Compile();
Logan Chien88894ee2012-02-13 16:42:22 +0800282}
283
284
Logan Chienf04364f2012-02-10 12:01:39 +0800285CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
286 char const *shorty) {
Logan Chienf04364f2012-02-10 12:01:39 +0800287 MutexLock GUARD(compiler_lock_);
288
Logan Chience119062012-03-02 11:57:34 +0800289 EnsureCompilationUnit();
Logan Chienf04364f2012-02-10 12:01:39 +0800290
Logan Chien8ba2fc52012-04-23 09:10:46 +0800291 MutexLock GUARD_CUNIT(curr_cunit_->cunit_lock_);
292
Logan Chien8b977d32012-02-21 19:14:55 +0800293 UniquePtr<UpcallCompiler> upcall_compiler(
Logan Chien7f767612012-03-01 18:54:49 +0800294 new UpcallCompiler(curr_cunit_, *compiler_));
Logan Chien8b977d32012-02-21 19:14:55 +0800295
Logan Chien7f767612012-03-01 18:54:49 +0800296 return upcall_compiler->CreateStub(is_static, shorty);
Logan Chienf04364f2012-02-10 12:01:39 +0800297}
298
Logan Chien83426162011-12-09 09:29:50 +0800299} // namespace compiler_llvm
300} // namespace art
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800301
Logan Chien106b2a02012-03-18 04:41:38 +0800302inline static art::compiler_llvm::CompilerLLVM* ContextOf(art::Compiler& compiler) {
303 void *compiler_context = compiler.GetCompilerContext();
304 CHECK(compiler_context != NULL);
305 return reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler_context);
306}
307
308inline static const art::compiler_llvm::CompilerLLVM* ContextOf(const art::Compiler& compiler) {
309 void *compiler_context = compiler.GetCompilerContext();
310 CHECK(compiler_context != NULL);
311 return reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler_context);
312}
313
314extern "C" void ArtInitCompilerContext(art::Compiler& compiler) {
315 CHECK(compiler.GetCompilerContext() == NULL);
316
317 art::compiler_llvm::CompilerLLVM* compiler_llvm =
318 new art::compiler_llvm::CompilerLLVM(&compiler,
319 compiler.GetInstructionSet());
320
321 compiler.SetCompilerContext(compiler_llvm);
322}
323
Elliott Hughes3fa1b7e2012-03-13 17:06:22 -0700324extern "C" art::CompiledMethod* ArtCompileMethod(art::Compiler& compiler,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800325 const art::DexFile::CodeItem* code_item,
326 uint32_t access_flags, uint32_t method_idx,
327 const art::ClassLoader* class_loader,
328 const art::DexFile& dex_file)
329{
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800330 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
331 art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
332
333 art::OatCompilationUnit oat_compilation_unit(
334 class_loader, class_linker, dex_file, *dex_cache, code_item,
335 method_idx, access_flags);
TDYa1270200d072012-04-17 20:55:08 -0700336 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
337 art::CompiledMethod* result = compiler_llvm->CompileDexMethod(&oat_compilation_unit);
338 compiler_llvm->MaterializeIfThresholdReached();
339 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800340}
341
342extern "C" art::CompiledMethod* ArtJniCompileMethod(art::Compiler& compiler,
343 uint32_t access_flags, uint32_t method_idx,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800344 const art::DexFile& dex_file) {
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800345 art::ClassLinker *class_linker = art::Runtime::Current()->GetClassLinker();
346 art::DexCache *dex_cache = class_linker->FindDexCache(dex_file);
347
348 art::OatCompilationUnit oat_compilation_unit(
Shih-wei Liaob1ab7df2012-03-29 13:53:46 -0700349 NULL, class_linker, dex_file, *dex_cache, NULL,
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800350 method_idx, access_flags);
351
Logan Chien106b2a02012-03-18 04:41:38 +0800352 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
Elliott Hughes6f4976c2012-03-13 21:19:01 -0700353 art::CompiledMethod* result = compiler_llvm->CompileNativeMethod(&oat_compilation_unit);
354 compiler_llvm->MaterializeIfThresholdReached();
Elliott Hughes13b835a2012-03-13 19:45:22 -0700355 return result;
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800356}
357
358extern "C" art::CompiledInvokeStub* ArtCreateInvokeStub(art::Compiler& compiler, bool is_static,
359 const char* shorty, uint32_t shorty_len) {
TDYa1270200d072012-04-17 20:55:08 -0700360 art::compiler_llvm::CompilerLLVM* compiler_llvm = ContextOf(compiler);
361 art::CompiledInvokeStub* result = compiler_llvm->CreateInvokeStub(is_static, shorty);
362 compiler_llvm->MaterializeIfThresholdReached();
363 return result;
Logan Chien106b2a02012-03-18 04:41:38 +0800364}
365
Logan Chien106b2a02012-03-18 04:41:38 +0800366extern "C" void compilerLLVMSetBitcodeFileName(art::Compiler& compiler,
367 std::string const& filename) {
368 ContextOf(compiler)->SetBitcodeFileName(filename);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800369}
370
371extern "C" void compilerLLVMMaterializeRemainder(art::Compiler& compiler) {
Logan Chien106b2a02012-03-18 04:41:38 +0800372 ContextOf(compiler)->MaterializeRemainder();
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800373}
374
Logan Chienf7015fd2012-03-18 01:19:37 +0800375extern "C" void compilerLLVMEnableAutoElfLoading(art::Compiler& compiler) {
376 art::compiler_llvm::CompilerLLVM* compiler_llvm =
377 reinterpret_cast<art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
378 return compiler_llvm->EnableAutoElfLoading();
379}
380
381extern "C" const void* compilerLLVMGetMethodCodeAddr(const art::Compiler& compiler,
382 const art::CompiledMethod* cm,
Logan Chien937105a2012-04-02 02:37:37 +0800383 const art::Method*) {
Logan Chienf7015fd2012-03-18 01:19:37 +0800384 const art::compiler_llvm::CompilerLLVM* compiler_llvm =
385 reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
Logan Chien937105a2012-04-02 02:37:37 +0800386 return compiler_llvm->GetMethodCodeAddr(cm);
Logan Chienf7015fd2012-03-18 01:19:37 +0800387}
388
389extern "C" const art::Method::InvokeStub* compilerLLVMGetMethodInvokeStubAddr(const art::Compiler& compiler,
390 const art::CompiledInvokeStub* cm,
Logan Chien937105a2012-04-02 02:37:37 +0800391 const art::Method*) {
Logan Chienf7015fd2012-03-18 01:19:37 +0800392 const art::compiler_llvm::CompilerLLVM* compiler_llvm =
393 reinterpret_cast<const art::compiler_llvm::CompilerLLVM*>(compiler.GetCompilerContext());
Logan Chien937105a2012-04-02 02:37:37 +0800394 return compiler_llvm->GetMethodInvokeStubAddr(cm);
Logan Chienf7015fd2012-03-18 01:19:37 +0800395}
396
Logan Chiendf576142012-03-20 17:36:32 +0800397extern "C" std::vector<art::ElfImage> compilerLLVMGetElfImages(const art::Compiler& compiler) {
398 return ContextOf(compiler)->GetElfImages();
399}
400
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800401extern "C" void compilerLLVMDispose(art::Compiler& compiler) {
Logan Chien106b2a02012-03-18 04:41:38 +0800402 delete ContextOf(compiler);
Shih-wei Liaoc4c98812012-03-10 21:55:51 -0800403}