blob: f97e4fea5e6eb2224394f4de14642b517ec15d31 [file] [log] [blame]
Logan Chien88894ee2012-02-13 16:42:22 +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 "jni_compiler.h"
18
19#include "class_linker.h"
20#include "compiled_method.h"
21#include "compiler.h"
22#include "compiler_llvm.h"
23#include "ir_builder.h"
24#include "logging.h"
25#include "oat_compilation_unit.h"
26#include "object.h"
27#include "runtime.h"
28#include "utils_llvm.h"
29
30#include <llvm/DerivedTypes.h>
31#include <llvm/Function.h>
32#include <llvm/Type.h>
33
34namespace art {
35namespace compiler_llvm {
36
37
38JniCompiler::JniCompiler(InstructionSet insn_set,
39 Compiler const& compiler,
40 OatCompilationUnit* oat_compilation_unit)
41: insn_set_(insn_set), compiler_(&compiler),
42 compiler_llvm_(compiler_->GetCompilerLLVM()),
43 module_(compiler_llvm_->GetModule()),
44 context_(compiler_llvm_->GetLLVMContext()),
45 irb_(*compiler_llvm_->GetIRBuilder()),
46 oat_compilation_unit_(oat_compilation_unit),
47 access_flags_(oat_compilation_unit->access_flags_),
48 method_idx_(oat_compilation_unit->method_idx_),
49 class_linker_(oat_compilation_unit->class_linker_),
50 class_loader_(oat_compilation_unit->class_loader_),
51 dex_cache_(oat_compilation_unit->dex_cache_),
52 dex_file_(oat_compilation_unit->dex_file_),
53 method_(dex_cache_->GetResolvedMethod(method_idx_)) {
54
55 // Check: Ensure that the method is resolved
56 CHECK_NE(method_, static_cast<art::Method*>(NULL));
57
58 // Check: Ensure that JNI compiler will only get "native" method
59 CHECK((access_flags_ & kAccNative) != 0);
60}
61
62
63CompiledMethod* JniCompiler::Compile() {
64 CreateFunction();
65
66 return new CompiledMethod(insn_set_, func_);
67}
68
69
70void JniCompiler::CreateFunction() {
71 // LLVM function name
72 std::string func_name(LLVMLongName(method_));
73
74 // Get function type
75 llvm::FunctionType* func_type =
76 GetFunctionType(method_idx_, method_->IsStatic());
77
78 // Create function
79 func_ = llvm::Function::Create(func_type, llvm::Function::ExternalLinkage,
80 func_name, module_);
81}
82
83
84llvm::FunctionType* JniCompiler::GetFunctionType(uint32_t method_idx,
85 bool is_static) {
86 // Get method signature
87 DexFile::MethodId const& method_id = dex_file_->GetMethodId(method_idx);
88
89 uint32_t shorty_size;
90 char const* shorty = dex_file_->GetMethodShorty(method_id, &shorty_size);
91 CHECK_GE(shorty_size, 1u);
92
93 // Get return type
94 llvm::Type* ret_type = irb_.getJType(shorty[0], kAccurate);
95
96 // Get argument type
97 std::vector<llvm::Type*> args_type;
98
99 args_type.push_back(irb_.getJObjectTy()); // method object pointer
100
101 if (!is_static) {
102 args_type.push_back(irb_.getJType('L', kAccurate)); // "this" object pointer
103 }
104
105 for (uint32_t i = 1; i < shorty_size; ++i) {
106 args_type.push_back(irb_.getJType(shorty[i], kAccurate));
107 }
108
109 return llvm::FunctionType::get(ret_type, args_type, false);
110}
111
112
113} // namespace compiler_llvm
114} // namespace art