JNI compiler.
Change-Id: Ia9a52cced70b8c44d1354e3342ad27f212c8d993
diff --git a/src/compiler.cc b/src/compiler.cc
index b7583d9..4664987 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -985,7 +985,11 @@
#endif
if ((access_flags & kAccNative) != 0) {
+#if defined(ART_USE_LLVM_COMPILER)
+ compiled_method = compiler_llvm_->CompileNativeMethod(oat_compilation_unit.get());
+#else
compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file);
+#endif
CHECK(compiled_method != NULL);
} else if ((access_flags & kAccAbstract) != 0) {
} else {
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 6099841..1489ec4 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -18,6 +18,7 @@
#include "compiler.h"
#include "ir_builder.h"
+#include "jni_compiler.h"
#include "method_compiler.h"
#include "oat_compilation_unit.h"
#include "upcall_compiler.h"
@@ -92,6 +93,16 @@
}
+CompiledMethod* CompilerLLVM::CompileNativeMethod(OatCompilationUnit* oat_compilation_unit) {
+ MutexLock GUARD(compiler_lock_);
+
+ UniquePtr<JniCompiler> jni_compiler(
+ new JniCompiler(insn_set_, *compiler_, oat_compilation_unit));
+
+ return jni_compiler->Compile();
+}
+
+
CompiledInvokeStub* CompilerLLVM::CreateInvokeStub(bool is_static,
char const *shorty) {
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index 13dc063..29d32a5 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -81,6 +81,8 @@
CompiledMethod* CompileDexMethod(OatCompilationUnit* oat_compilation_unit);
+ CompiledMethod* CompileNativeMethod(OatCompilationUnit* oat_compilation_unit);
+
CompiledInvokeStub* CreateInvokeStub(bool is_static, char const *shorty);
private:
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
new file mode 100644
index 0000000..f97e4fe
--- /dev/null
+++ b/src/compiler_llvm/jni_compiler.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "jni_compiler.h"
+
+#include "class_linker.h"
+#include "compiled_method.h"
+#include "compiler.h"
+#include "compiler_llvm.h"
+#include "ir_builder.h"
+#include "logging.h"
+#include "oat_compilation_unit.h"
+#include "object.h"
+#include "runtime.h"
+#include "utils_llvm.h"
+
+#include <llvm/DerivedTypes.h>
+#include <llvm/Function.h>
+#include <llvm/Type.h>
+
+namespace art {
+namespace compiler_llvm {
+
+
+JniCompiler::JniCompiler(InstructionSet insn_set,
+ Compiler const& compiler,
+ OatCompilationUnit* oat_compilation_unit)
+: insn_set_(insn_set), compiler_(&compiler),
+ compiler_llvm_(compiler_->GetCompilerLLVM()),
+ module_(compiler_llvm_->GetModule()),
+ context_(compiler_llvm_->GetLLVMContext()),
+ irb_(*compiler_llvm_->GetIRBuilder()),
+ oat_compilation_unit_(oat_compilation_unit),
+ access_flags_(oat_compilation_unit->access_flags_),
+ method_idx_(oat_compilation_unit->method_idx_),
+ class_linker_(oat_compilation_unit->class_linker_),
+ class_loader_(oat_compilation_unit->class_loader_),
+ dex_cache_(oat_compilation_unit->dex_cache_),
+ dex_file_(oat_compilation_unit->dex_file_),
+ method_(dex_cache_->GetResolvedMethod(method_idx_)) {
+
+ // Check: Ensure that the method is resolved
+ CHECK_NE(method_, static_cast<art::Method*>(NULL));
+
+ // Check: Ensure that JNI compiler will only get "native" method
+ CHECK((access_flags_ & kAccNative) != 0);
+}
+
+
+CompiledMethod* JniCompiler::Compile() {
+ CreateFunction();
+
+ return new CompiledMethod(insn_set_, func_);
+}
+
+
+void JniCompiler::CreateFunction() {
+ // LLVM function name
+ std::string func_name(LLVMLongName(method_));
+
+ // Get function type
+ llvm::FunctionType* func_type =
+ GetFunctionType(method_idx_, method_->IsStatic());
+
+ // Create function
+ func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
+ func_name, module_);
+}
+
+
+llvm::FunctionType* JniCompiler::GetFunctionType(uint32_t method_idx,
+ bool is_static) {
+ // Get method signature
+ DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
+
+ uint32_t shorty_size;
+ char const* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
+ CHECK_GE(shorty_size, 1u);
+
+ // Get return type
+ llvm::Type* ret_type = irb_.getJType(shorty[0], kAccurate);
+
+ // Get argument type
+ std::vector<llvm::Type*> args_type;
+
+ args_type.push_back(irb_.getJObjectTy()); // method object pointer
+
+ if (!is_static) {
+ args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer
+ }
+
+ for (uint32_t i = 1; i < shorty_size; ++i) {
+ args_type.push_back(irb_.getJType(shorty[i], kAccurate));
+ }
+
+ return llvm::FunctionType::get(ret_type, args_type, false);
+}
+
+
+} // namespace compiler_llvm
+} // namespace art
diff --git a/src/compiler_llvm/jni_compiler.h b/src/compiler_llvm/jni_compiler.h
new file mode 100644
index 0000000..4d7763e
--- /dev/null
+++ b/src/compiler_llvm/jni_compiler.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_JNI_COMPILER_H_
+#define ART_SRC_COMPILER_LLVM_JNI_COMPILER_H_
+
+#include "constants.h"
+
+#include <stdint.h>
+
+namespace art {
+ class ClassLinker;
+ class ClassLoader;
+ class CompiledMethod;
+ class Compiler;
+ class DexCache;
+ class DexFile;
+ class Method;
+ class OatCompilationUnit;
+}
+
+namespace llvm {
+ class Function;
+ class FunctionType;
+ class LLVMContext;
+ class Module;
+}
+
+namespace art {
+namespace compiler_llvm {
+
+class CompilerLLVM;
+class IRBuilder;
+
+class JniCompiler {
+ public:
+ JniCompiler(InstructionSet insn_set,
+ Compiler const& compiler,
+ OatCompilationUnit* oat_compilation_unit);
+
+ CompiledMethod* Compile();
+
+ private:
+ void CreateFunction();
+
+ llvm::FunctionType* GetFunctionType(uint32_t method_idx,
+ bool is_static);
+
+ private:
+ InstructionSet insn_set_;
+ Compiler const* compiler_;
+ CompilerLLVM* compiler_llvm_;
+
+ llvm::Module* module_;
+ llvm::LLVMContext* context_;
+ IRBuilder& irb_;
+
+ OatCompilationUnit* oat_compilation_unit_;
+
+ uint32_t access_flags_;
+ uint32_t method_idx_;
+ ClassLinker * class_linker_;
+ ClassLoader const* class_loader_;
+ DexCache const* dex_cache_;
+ DexFile const* dex_file_;
+ Method* method_;
+
+ llvm::Function* func_;
+};
+
+
+} // namespace compiler_llvm
+} // namespace art
+
+
+#endif // ART_SRC_COMPILER_LLVM_JNI_COMPILER_H_