summaryrefslogtreecommitdiff
path: root/src/compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler.cc')
-rw-r--r--src/compiler.cc46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/compiler.cc b/src/compiler.cc
index dadfc40513..5389127300 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -307,6 +307,9 @@ Compiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_cou
compiled_classes_lock_("compiled classes lock"),
compiled_methods_lock_("compiled method lock"),
compiled_invoke_stubs_lock_("compiled invoke stubs lock"),
+#if defined(ART_USE_LLVM_COMPILER)
+ compiled_proxy_stubs_lock_("compiled proxy stubs lock"),
+#endif
image_(image),
thread_count_(thread_count),
support_debugging_(support_debugging),
@@ -350,6 +353,8 @@ Compiler::Compiler(InstructionSet instruction_set, bool image, size_t thread_cou
create_invoke_stub_ = FindFunction<CreateInvokeStubFn>(compiler_so_name, compiler_library_, "ArtCreateInvokeStub");
#if defined(ART_USE_LLVM_COMPILER)
+ create_proxy_stub_ = FindFunction<CreateProxyStubFn>(
+ compiler_so_name, compiler_library_, "ArtCreateProxyStub");
compiler_enable_auto_elf_loading_ = FindFunction<CompilerEnableAutoElfLoadingFn>(
compiler_so_name, compiler_library_, "compilerLLVMEnableAutoElfLoading");
compiler_get_method_code_addr_ = FindFunction<CompilerGetMethodCodeAddrFn>(
@@ -378,6 +383,10 @@ Compiler::~Compiler() {
STLDeleteValues(&compiled_invoke_stubs_);
}
{
+ MutexLock mu(compiled_proxy_stubs_lock_);
+ STLDeleteValues(&compiled_proxy_stubs_);
+ }
+ {
MutexLock mu(compiled_methods_lock_);
STLDeleteElements(&code_to_patch_);
}
@@ -1505,6 +1514,18 @@ void Compiler::CompileMethod(const DexFile::CodeItem* code_item, uint32_t access
CHECK(compiled_invoke_stub != NULL);
InsertInvokeStub(key, compiled_invoke_stub);
}
+
+#if defined(ART_USE_LLVM_COMPILER)
+ if (!is_static) {
+ const CompiledInvokeStub* compiled_proxy_stub = FindProxyStub(shorty);
+ if (compiled_proxy_stub == NULL) {
+ compiled_proxy_stub = (*create_proxy_stub_)(*this, shorty, shorty_len);
+ CHECK(compiled_proxy_stub != NULL);
+ InsertProxyStub(shorty, compiled_proxy_stub);
+ }
+ }
+#endif
+
CHECK(!Thread::Current()->IsExceptionPending()) << PrettyMethod(method_idx, dex_file);
}
@@ -1536,6 +1557,31 @@ void Compiler::InsertInvokeStub(const std::string& key,
}
}
+#if defined(ART_USE_LLVM_COMPILER)
+const CompiledInvokeStub* Compiler::FindProxyStub(const char* shorty) const {
+ MutexLock mu(compiled_proxy_stubs_lock_);
+ ProxyStubTable::const_iterator it = compiled_proxy_stubs_.find(shorty);
+ if (it == compiled_proxy_stubs_.end()) {
+ return NULL;
+ } else {
+ DCHECK(it->second != NULL);
+ return it->second;
+ }
+}
+
+void Compiler::InsertProxyStub(const char* shorty,
+ const CompiledInvokeStub* compiled_proxy_stub) {
+ MutexLock mu(compiled_proxy_stubs_lock_);
+ InvokeStubTable::iterator it = compiled_proxy_stubs_.find(shorty);
+ if (it != compiled_proxy_stubs_.end()) {
+ // Someone else won the race.
+ delete compiled_proxy_stub;
+ } else {
+ compiled_proxy_stubs_.Put(shorty, compiled_proxy_stub);
+ }
+}
+#endif
+
CompiledClass* Compiler::GetCompiledClass(ClassReference ref) const {
MutexLock mu(compiled_classes_lock_);
ClassTable::const_iterator it = compiled_classes_.find(ref);