Move the JNI compilers under compiler.
Change-Id: Id1d40f35be191758906b96b56b74a83ab0dfb88e
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index efa7d97..45f9931 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -22,7 +22,7 @@
#include "compiled_method.h"
#include "compiler/driver/compiler_driver.h"
#include "ir_builder.h"
-#include "jni_compiler.h"
+#include "compiler/jni/portable/jni_compiler.h"
#include "llvm_compilation_unit.h"
#include "oat_compilation_unit.h"
#include "oat_file.h"
diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc
deleted file mode 100644
index 8b5f1be..0000000
--- a/src/compiler_llvm/jni_compiler.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * 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 "base/logging.h"
-#include "class_linker.h"
-#include "compiled_method.h"
-#include "compiler/driver/compiler_driver.h"
-#include "compiler_llvm.h"
-#include "ir_builder.h"
-#include "llvm_compilation_unit.h"
-#include "mirror/abstract_method.h"
-#include "oat_compilation_unit.h"
-#include "runtime.h"
-#include "runtime_support_func.h"
-#include "stack.h"
-#include "thread.h"
-#include "utils_llvm.h"
-
-#include <llvm/BasicBlock.h>
-#include <llvm/DerivedTypes.h>
-#include <llvm/Function.h>
-#include <llvm/ADT/SmallVector.h>
-#include <llvm/Type.h>
-
-namespace art {
-namespace compiler_llvm {
-
-using namespace runtime_support;
-
-JniCompiler::JniCompiler(LlvmCompilationUnit* cunit,
- const CompilerDriver& driver,
- OatCompilationUnit* oat_compilation_unit)
-: cunit_(cunit), driver_(&driver), module_(cunit_->GetModule()),
- context_(cunit_->GetLLVMContext()), irb_(*cunit_->GetIRBuilder()),
- oat_compilation_unit_(oat_compilation_unit),
- access_flags_(oat_compilation_unit->access_flags_),
- method_idx_(oat_compilation_unit->method_idx_),
- dex_file_(oat_compilation_unit->dex_file_),
- func_(NULL), elf_func_idx_(0) {
-
- // Check: Ensure that JNI compiler will only get "native" method
- CHECK((access_flags_ & kAccNative) != 0);
-}
-
-
-CompiledMethod* JniCompiler::Compile() {
- const bool is_static = (access_flags_ & kAccStatic) != 0;
- const bool is_synchronized = (access_flags_ & kAccSynchronized) != 0;
- DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx_);
- char const return_shorty = dex_file_->GetMethodShorty(method_id)[0];
- llvm::Value* this_object_or_class_object;
-
- CreateFunction();
-
- // Set argument name
- llvm::Function::arg_iterator arg_begin(func_->arg_begin());
- llvm::Function::arg_iterator arg_end(func_->arg_end());
- llvm::Function::arg_iterator arg_iter(arg_begin);
-
- DCHECK_NE(arg_iter, arg_end);
- arg_iter->setName("method");
- llvm::Value* method_object_addr = arg_iter++;
-
- if (!is_static) {
- // Non-static, the second argument is "this object"
- this_object_or_class_object = arg_iter++;
- } else {
- // Load class object
- this_object_or_class_object =
- irb_.LoadFromObjectOffset(method_object_addr,
- mirror::AbstractMethod::DeclaringClassOffset().Int32Value(),
- irb_.getJObjectTy(),
- kTBAAConstJObject);
- }
- // Actual argument (ignore method and this object)
- arg_begin = arg_iter;
-
- // Count the number of Object* arguments
- uint32_t sirt_size = 1;
- // "this" object pointer for non-static
- // "class" object pointer for static
- for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
-#if !defined(NDEBUG)
- arg_iter->setName(StringPrintf("a%u", i));
-#endif
- if (arg_iter->getType() == irb_.getJObjectTy()) {
- ++sirt_size;
- }
- }
-
- // Shadow stack
- llvm::StructType* shadow_frame_type = irb_.getShadowFrameTy(sirt_size);
- llvm::AllocaInst* shadow_frame_ = irb_.CreateAlloca(shadow_frame_type);
-
- // Store the dex pc
- irb_.StoreToObjectOffset(shadow_frame_,
- ShadowFrame::DexPCOffset(),
- irb_.getInt32(DexFile::kDexNoIndex),
- kTBAAShadowFrame);
-
- // Push the shadow frame
- llvm::Value* shadow_frame_upcast = irb_.CreateConstGEP2_32(shadow_frame_, 0, 0);
- llvm::Value* old_shadow_frame =
- irb_.Runtime().EmitPushShadowFrame(shadow_frame_upcast, method_object_addr, sirt_size);
-
- // Get JNIEnv
- llvm::Value* jni_env_object_addr =
- irb_.Runtime().EmitLoadFromThreadOffset(Thread::JniEnvOffset().Int32Value(),
- irb_.getJObjectTy(),
- kTBAARuntimeInfo);
-
- // Get callee code_addr
- llvm::Value* code_addr =
- irb_.LoadFromObjectOffset(method_object_addr,
- mirror::AbstractMethod::NativeMethodOffset().Int32Value(),
- GetFunctionType(method_idx_, is_static, true)->getPointerTo(),
- kTBAARuntimeInfo);
-
- // Load actual parameters
- std::vector<llvm::Value*> args;
-
- // The 1st parameter: JNIEnv*
- args.push_back(jni_env_object_addr);
-
- // Variables for GetElementPtr
- llvm::Value* gep_index[] = {
- irb_.getInt32(0), // No displacement for shadow frame pointer
- irb_.getInt32(1), // SIRT
- NULL,
- };
-
- size_t sirt_member_index = 0;
-
- // Store the "this object or class object" to SIRT
- gep_index[2] = irb_.getInt32(sirt_member_index++);
- llvm::Value* sirt_field_addr = irb_.CreateBitCast(irb_.CreateGEP(shadow_frame_, gep_index),
- irb_.getJObjectTy()->getPointerTo());
- irb_.CreateStore(this_object_or_class_object, sirt_field_addr, kTBAAShadowFrame);
- // Push the "this object or class object" to out args
- this_object_or_class_object = irb_.CreateBitCast(sirt_field_addr, irb_.getJObjectTy());
- args.push_back(this_object_or_class_object);
- // Store arguments to SIRT, and push back to args
- for (arg_iter = arg_begin; arg_iter != arg_end; ++arg_iter) {
- if (arg_iter->getType() == irb_.getJObjectTy()) {
- // Store the reference type arguments to SIRT
- gep_index[2] = irb_.getInt32(sirt_member_index++);
- llvm::Value* sirt_field_addr = irb_.CreateBitCast(irb_.CreateGEP(shadow_frame_, gep_index),
- irb_.getJObjectTy()->getPointerTo());
- irb_.CreateStore(arg_iter, sirt_field_addr, kTBAAShadowFrame);
- // Note null is placed in the SIRT but the jobject passed to the native code must be null
- // (not a pointer into the SIRT as with regular references).
- llvm::Value* equal_null = irb_.CreateICmpEQ(arg_iter, irb_.getJNull());
- llvm::Value* arg =
- irb_.CreateSelect(equal_null,
- irb_.getJNull(),
- irb_.CreateBitCast(sirt_field_addr, irb_.getJObjectTy()));
- args.push_back(arg);
- } else {
- args.push_back(arg_iter);
- }
- }
-
- llvm::Value* saved_local_ref_cookie;
- { // JniMethodStart
- RuntimeId func_id = is_synchronized ? JniMethodStartSynchronized
- : JniMethodStart;
- llvm::SmallVector<llvm::Value*, 2> args;
- if (is_synchronized) {
- args.push_back(this_object_or_class_object);
- }
- args.push_back(irb_.Runtime().EmitGetCurrentThread());
- saved_local_ref_cookie =
- irb_.CreateCall(irb_.GetRuntime(func_id), args);
- }
-
- // Call!!!
- llvm::Value* retval = irb_.CreateCall(code_addr, args);
-
- { // JniMethodEnd
- bool is_return_ref = return_shorty == 'L';
- RuntimeId func_id =
- is_return_ref ? (is_synchronized ? JniMethodEndWithReferenceSynchronized
- : JniMethodEndWithReference)
- : (is_synchronized ? JniMethodEndSynchronized
- : JniMethodEnd);
- llvm::SmallVector<llvm::Value*, 4> args;
- if (is_return_ref) {
- args.push_back(retval);
- }
- args.push_back(saved_local_ref_cookie);
- if (is_synchronized) {
- args.push_back(this_object_or_class_object);
- }
- args.push_back(irb_.Runtime().EmitGetCurrentThread());
-
- llvm::Value* decoded_jobject =
- irb_.CreateCall(irb_.GetRuntime(func_id), args);
-
- // Return decoded jobject if return reference.
- if (is_return_ref) {
- retval = decoded_jobject;
- }
- }
-
- // Pop the shadow frame
- irb_.Runtime().EmitPopShadowFrame(old_shadow_frame);
-
- // Return!
- if (return_shorty != 'V') {
- irb_.CreateRet(retval);
- } else {
- irb_.CreateRetVoid();
- }
-
- // Verify the generated bitcode
- VERIFY_LLVM_FUNCTION(*func_);
-
- cunit_->Materialize();
-
- return new CompiledMethod(cunit_->GetInstructionSet(),
- cunit_->GetCompiledCode());
-}
-
-
-void JniCompiler::CreateFunction() {
- // LLVM function name
- std::string func_name(ElfFuncName(cunit_->GetIndex()));
-
- const bool is_static = (access_flags_ & kAccStatic) != 0;
-
- // Get function type
- llvm::FunctionType* func_type =
- GetFunctionType(method_idx_, is_static, false);
-
- // Create function
- func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
- func_name, module_);
-
- // Create basic block
- llvm::BasicBlock* basic_block = llvm::BasicBlock::Create(*context_, "B0", func_);
-
- // Set insert point
- irb_.SetInsertPoint(basic_block);
-}
-
-
-llvm::FunctionType* JniCompiler::GetFunctionType(uint32_t method_idx,
- bool is_static, bool is_native_function) {
- // Get method signature
- DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
-
- uint32_t shorty_size;
- const char* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
- CHECK_GE(shorty_size, 1u);
-
- // Get return type
- llvm::Type* ret_type = irb_.getJType(shorty[0]);
-
- // Get argument type
- std::vector<llvm::Type*> args_type;
-
- args_type.push_back(irb_.getJObjectTy()); // method object pointer
-
- if (!is_static || is_native_function) {
- // "this" object pointer for non-static
- // "class" object pointer for static naitve
- args_type.push_back(irb_.getJType('L'));
- }
-
- for (uint32_t i = 1; i < shorty_size; ++i) {
- args_type.push_back(irb_.getJType(shorty[i]));
- }
-
- 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
deleted file mode 100644
index 071229c..0000000
--- a/src/compiler_llvm/jni_compiler.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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 <stdint.h>
-
-namespace art {
- class ClassLinker;
- class CompiledMethod;
- class CompilerDriver;
- class DexFile;
- class OatCompilationUnit;
- namespace mirror {
- class AbstractMethod;
- class ClassLoader;
- class DexCache;
- } // namespace mirror
-} // namespace art
-
-namespace llvm {
- class AllocaInst;
- class Function;
- class FunctionType;
- class BasicBlock;
- class LLVMContext;
- class Module;
- class Type;
- class Value;
-} // namespace llvm
-
-namespace art {
-namespace compiler_llvm {
-
-class LlvmCompilationUnit;
-class IRBuilder;
-
-class JniCompiler {
- public:
- JniCompiler(LlvmCompilationUnit* cunit,
- const CompilerDriver& driver,
- OatCompilationUnit* oat_compilation_unit);
-
- CompiledMethod* Compile();
-
- private:
- void CreateFunction();
-
- llvm::FunctionType* GetFunctionType(uint32_t method_idx,
- bool is_static, bool is_target_function);
-
- private:
- LlvmCompilationUnit* cunit_;
- const CompilerDriver* const driver_;
-
- llvm::Module* module_;
- llvm::LLVMContext* context_;
- IRBuilder& irb_;
-
- OatCompilationUnit* oat_compilation_unit_;
-
- uint32_t access_flags_;
- uint32_t method_idx_;
- const DexFile* dex_file_;
-
- llvm::Function* func_;
- uint16_t elf_func_idx_;
-};
-
-
-} // namespace compiler_llvm
-} // namespace art
-
-
-#endif // ART_SRC_COMPILER_LLVM_JNI_COMPILER_H_