blob: 6c67298b43d420abec910899e35c8045bdce3a81 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 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 */
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070016
17#ifndef ART_SRC_COMPILER_H_
18#define ART_SRC_COMPILER_H_
19
Elliott Hughese5448b52012-01-18 16:44:06 -080020#include <map>
Elliott Hughes8add92d2012-01-18 18:18:43 -080021#include <set>
22#include <string>
Elliott Hughese5448b52012-01-18 16:44:06 -080023
Brian Carlstrom0755ec52012-01-11 15:19:46 -080024#include "compiled_class.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070025#include "compiled_method.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -070026#include "constants.h"
Ian Rogersa3760aa2011-11-14 14:32:37 -080027#include "dex_cache.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070028#include "dex_file.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -070029#include "jni_compiler.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070030#include "oat_file.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070031#include "object.h"
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070032#include "runtime.h"
Ian Rogers0571d352011-11-03 19:51:38 -070033
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070034namespace art {
35
36class Compiler {
37 public:
Brian Carlstromaded5f72011-10-07 17:15:04 -070038 // Create a compiler targeting the requested "instruction_set".
Brian Carlstromae826982011-11-09 01:33:42 -080039 // "image" should be true if image specific optimizations should be
40 // enabled. "image_classes" lets the compiler know what classes it
41 // can assume will be in the image, with NULL implying all available
42 // classes.
43 explicit Compiler(InstructionSet instruction_set,
44 bool image,
45 const std::set<std::string>* image_classes);
Brian Carlstrom3320cf42011-10-04 14:58:28 -070046
47 ~Compiler();
Ian Rogers2c8f6532011-09-02 17:16:34 -070048
Jesse Wilson254db0f2011-11-16 16:44:11 -050049 void CompileAll(const ClassLoader* class_loader,
Brian Carlstromae826982011-11-09 01:33:42 -080050 const std::vector<const DexFile*>& dex_files);
Brian Carlstrom8a487412011-08-29 20:08:52 -070051
52 // Compile a single Method
Brian Carlstrom3320cf42011-10-04 14:58:28 -070053 void CompileOne(const Method* method);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070054
Brian Carlstrom3320cf42011-10-04 14:58:28 -070055 InstructionSet GetInstructionSet() const {
56 return instruction_set_;
57 }
58
Brian Carlstromaded5f72011-10-07 17:15:04 -070059 bool IsImage() const {
60 return image_;
61 }
62
Brian Carlstrome24fa612011-09-29 00:53:55 -070063 // Stub to throw AbstractMethodError
Brian Carlstrome24fa612011-09-29 00:53:55 -070064 static ByteArray* CreateAbstractMethodErrorStub(InstructionSet instruction_set);
65
Brian Carlstrom3320cf42011-10-04 14:58:28 -070066
Ian Rogersad25ac52011-10-04 19:13:33 -070067 // Generate the trampoline that's invoked by unresolved direct methods
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070068 static ByteArray* CreateResolutionStub(InstructionSet instruction_set,
69 Runtime::TrampolineType type);
Ian Rogersad25ac52011-10-04 19:13:33 -070070
Elliott Hughes8add92d2012-01-18 18:18:43 -080071 static ByteArray* CreateJniDlsymLookupStub(InstructionSet instruction_set);
Ian Rogers169c9a72011-11-13 20:13:17 -080072
Brian Carlstrom0755ec52012-01-11 15:19:46 -080073 // A class is uniquely located by its DexFile and the class_defs_ table index into that DexFile
74 typedef std::pair<const DexFile*, uint32_t> ClassReference;
Elliott Hughes8add92d2012-01-18 18:18:43 -080075
Brian Carlstrom0755ec52012-01-11 15:19:46 -080076 CompiledClass* GetCompiledClass(ClassReference ref) const;
Ian Rogers0571d352011-11-03 19:51:38 -070077
Brian Carlstrom0755ec52012-01-11 15:19:46 -080078 // A method is uniquely located by its DexFile and the method_ids_ table index into that DexFile
79 typedef std::pair<const DexFile*, uint32_t> MethodReference;
Elliott Hughes8add92d2012-01-18 18:18:43 -080080
Ian Rogers0571d352011-11-03 19:51:38 -070081 CompiledMethod* GetCompiledMethod(MethodReference ref) const;
Brian Carlstrom0755ec52012-01-11 15:19:46 -080082
Ian Rogers0571d352011-11-03 19:51:38 -070083 const CompiledInvokeStub* FindInvokeStub(bool is_static, const char* shorty) const;
Brian Carlstrom3320cf42011-10-04 14:58:28 -070084
Ian Rogers28ad40d2011-10-27 15:19:26 -070085 // Callbacks from OAT/ART compiler to see what runtime checks must be generated
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080086 bool CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, uint32_t type_idx) const;
Ian Rogersa3760aa2011-11-14 14:32:37 -080087 bool CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache, uint32_t string_idx) const {
Brian Carlstromae826982011-11-09 01:33:42 -080088 // TODO: Add support for loading strings referenced by image_classes_
89 // See also Compiler::ResolveDexFile
90 return IsImage() && image_classes_ == NULL && dex_cache->GetResolvedString(string_idx) != NULL;
Ian Rogers28ad40d2011-10-27 15:19:26 -070091 }
Ian Rogersa3760aa2011-11-14 14:32:37 -080092 bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache,
93 const DexFile& dex_file, uint32_t type_idx) const {
Brian Carlstromae826982011-11-09 01:33:42 -080094 Class* resolved_class = dex_cache->GetResolvedType(type_idx);
Ian Rogers28ad40d2011-10-27 15:19:26 -070095 // We should never ask whether a type needs access checks to raise a verification error,
96 // all other cases where this following test could fail should have been rewritten by the
Ian Rogersa3760aa2011-11-14 14:32:37 -080097 // verifier to verification errors. Also need to handle a lack of knowledge at compile time.
98#ifndef NDEBUG
Brian Carlstromae826982011-11-09 01:33:42 -080099 const DexFile::MethodId& method_id = dex_file.GetMethodId(referrer_idx);
100 Class* referrer_class = dex_cache->GetResolvedType(method_id.class_idx_);
Ian Rogersa3760aa2011-11-14 14:32:37 -0800101 DCHECK(resolved_class == NULL || referrer_class == NULL ||
102 referrer_class->CanAccess(resolved_class));
103#endif
Ian Rogers28ad40d2011-10-27 15:19:26 -0700104 return resolved_class != NULL;
105 }
Ian Rogers0571d352011-11-03 19:51:38 -0700106
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700107 private:
Brian Carlstromae826982011-11-09 01:33:42 -0800108
109 // Checks if class specified by type_idx is one of the image_classes_
110 bool IsImageClass(const std::string& descriptor) const;
111
112 void PreCompile(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files);
113 void PostCompile(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files);
114
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700115 // Attempt to resolve all type, methods, fields, and strings
116 // referenced from code in the dex file following PathClassLoader
117 // ordering semantics.
Brian Carlstromae826982011-11-09 01:33:42 -0800118 void Resolve(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700119 void ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
120
Brian Carlstromae826982011-11-09 01:33:42 -0800121 void Verify(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files);
jeffhao98eacac2011-09-14 16:11:53 -0700122 void VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
123
Brian Carlstromae826982011-11-09 01:33:42 -0800124 void InitializeClassesWithoutClinit(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files);
Brian Carlstroma5a97a22011-09-15 14:08:49 -0700125 void InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file);
126
Brian Carlstromae826982011-11-09 01:33:42 -0800127 void Compile(const ClassLoader* class_loader,
128 const std::vector<const DexFile*>& dex_files);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700129 void CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
Ian Rogers0571d352011-11-03 19:51:38 -0700130 void CompileClass(const DexFile::ClassDef& class_def, const ClassLoader* class_loader,
131 const DexFile& dex_file);
Ian Rogersa3760aa2011-11-14 14:32:37 -0800132 void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, uint32_t method_idx,
133 const ClassLoader* class_loader, const DexFile& dex_file);
Brian Carlstrom83db7722011-08-26 17:32:56 -0700134
Brian Carlstrome7d856b2012-01-11 18:10:55 -0800135 void SetGcMaps(const ClassLoader* class_loader, const std::vector<const DexFile*>& dex_files);
136 void SetGcMapsDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
137 void SetGcMapsMethod(const DexFile& dex_file, Method* method);
138
Brian Carlstrom83db7722011-08-26 17:32:56 -0700139 // After compiling, walk all the DexCaches and set the code and
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700140 // method pointers of CodeAndDirectMethods entries in the DexCaches.
Brian Carlstromae826982011-11-09 01:33:42 -0800141 void SetCodeAndDirectMethods(const std::vector<const DexFile*>& dex_files);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700142 void SetCodeAndDirectMethodsDexFile(const DexFile& dex_file);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700143
Ian Rogers0571d352011-11-03 19:51:38 -0700144 void InsertInvokeStub(bool is_static, const char* shorty,
145 const CompiledInvokeStub* compiled_invoke_stub);
146
Ian Rogers2c8f6532011-09-02 17:16:34 -0700147 InstructionSet instruction_set_;
148 JniCompiler jni_compiler_;
149
Elliott Hughes8add92d2012-01-18 18:18:43 -0800150 typedef std::map<const ClassReference, CompiledClass*> ClassTable;
Brian Carlstrom0755ec52012-01-11 15:19:46 -0800151 // All class references that this compiler has compiled
152 ClassTable compiled_classes_;
153
Elliott Hughes8add92d2012-01-18 18:18:43 -0800154 typedef std::map<const MethodReference, CompiledMethod*> MethodTable;
Ian Rogers0571d352011-11-03 19:51:38 -0700155 // All method references that this compiler has compiled
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700156 MethodTable compiled_methods_;
157
Elliott Hughese5448b52012-01-18 16:44:06 -0800158 typedef std::map<std::string, const CompiledInvokeStub*> InvokeStubTable;
Ian Rogers0571d352011-11-03 19:51:38 -0700159 // Invocation stubs created to allow invocation of the compiled methods
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700160 InvokeStubTable compiled_invoke_stubs_;
161
Brian Carlstromaded5f72011-10-07 17:15:04 -0700162 bool image_;
163
Elliott Hughesbb551fa2012-01-25 16:35:29 -0800164 size_t dex_file_count_;
165 size_t class_count_;
166 size_t abstract_method_count_;
167 size_t native_method_count_;
168 size_t regular_method_count_;
169 size_t instruction_count_;
170 uint64_t start_ns_;
171
Brian Carlstromae826982011-11-09 01:33:42 -0800172 const std::set<std::string>* image_classes_;
173
Ian Rogers2c8f6532011-09-02 17:16:34 -0700174 DISALLOW_COPY_AND_ASSIGN(Compiler);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700175};
176
Elliott Hughes8add92d2012-01-18 18:18:43 -0800177inline bool operator<(const Compiler::ClassReference& lhs, const Compiler::ClassReference& rhs) {
178 if (lhs.second < rhs.second) {
179 return true;
180 } else if (lhs.second > rhs.second) {
181 return false;
182 } else {
183 return (lhs.first < rhs.first);
184 }
185}
186
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700187} // namespace art
188
189#endif // ART_SRC_COMPILER_H_