blob: c09e2c288b389c4007deaf8f615dc452431c9ffc [file] [log] [blame]
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_COMPILER_H_
4#define ART_SRC_COMPILER_H_
5
Brian Carlstrom3320cf42011-10-04 14:58:28 -07006#include "compiled_method.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -07007#include "constants.h"
Ian Rogersa3760aa2011-11-14 14:32:37 -08008#include "dex_cache.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -07009#include "dex_file.h"
Ian Rogers2c8f6532011-09-02 17:16:34 -070010#include "jni_compiler.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070011#include "oat_file.h"
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070012#include "object.h"
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070013#include "runtime.h"
Brian Carlstrom3320cf42011-10-04 14:58:28 -070014#include "unordered_map.h"
Ian Rogersd6b1f612011-09-27 13:38:14 -070015
Ian Rogers0571d352011-11-03 19:51:38 -070016#include <string>
17
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070018namespace art {
19
20class Compiler {
21 public:
Brian Carlstromaded5f72011-10-07 17:15:04 -070022 // Create a compiler targeting the requested "instruction_set".
23 // "image" should be true if image specific optimizations should be enabled.
24 explicit Compiler(InstructionSet instruction_set, bool image);
Brian Carlstrom3320cf42011-10-04 14:58:28 -070025
26 ~Compiler();
Ian Rogers2c8f6532011-09-02 17:16:34 -070027
Brian Carlstrom8a487412011-08-29 20:08:52 -070028 // Compile all Methods of all the Classes of all the DexFiles that are part of a ClassLoader.
29 void CompileAll(const ClassLoader* class_loader);
30
31 // Compile a single Method
Brian Carlstrom3320cf42011-10-04 14:58:28 -070032 void CompileOne(const Method* method);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070033
Brian Carlstrom3320cf42011-10-04 14:58:28 -070034 InstructionSet GetInstructionSet() const {
35 return instruction_set_;
36 }
37
Brian Carlstromaded5f72011-10-07 17:15:04 -070038 bool IsImage() const {
39 return image_;
40 }
41
42 void SetVerbose(bool verbose) {
43 verbose_ = verbose;
44 }
45
Brian Carlstrom16192862011-09-12 17:50:06 -070046 bool IsVerbose() const {
47 return verbose_;
48 }
49
Brian Carlstrome24fa612011-09-29 00:53:55 -070050 // Stub to throw AbstractMethodError
Brian Carlstrome24fa612011-09-29 00:53:55 -070051 static ByteArray* CreateAbstractMethodErrorStub(InstructionSet instruction_set);
52
Brian Carlstrom3320cf42011-10-04 14:58:28 -070053
Ian Rogersad25ac52011-10-04 19:13:33 -070054 // Generate the trampoline that's invoked by unresolved direct methods
Ian Rogers1cb0a1d2011-10-06 15:24:35 -070055 static ByteArray* CreateResolutionStub(InstructionSet instruction_set,
56 Runtime::TrampolineType type);
Ian Rogersad25ac52011-10-04 19:13:33 -070057
Ian Rogers169c9a72011-11-13 20:13:17 -080058 static ByteArray* CreateJniDlysmLookupStub(InstructionSet instruction_set);
59
Ian Rogers0571d352011-11-03 19:51:38 -070060 // A method is uniquely located by its DexFile and index into the method_id table of that dex file
61 typedef std::pair<const DexFile*, uint32_t> MethodReference;
62
63 CompiledMethod* GetCompiledMethod(MethodReference ref) const;
64 const CompiledInvokeStub* FindInvokeStub(bool is_static, const char* shorty) const;
Brian Carlstrom3320cf42011-10-04 14:58:28 -070065
Ian Rogers28ad40d2011-10-27 15:19:26 -070066 // Callbacks from OAT/ART compiler to see what runtime checks must be generated
Ian Rogersa3760aa2011-11-14 14:32:37 -080067 bool CanAssumeTypeIsPresentInDexCache(const DexCache* dex_cache, uint32_t type_idx) const {
68 return IsImage() && dex_cache->GetResolvedTypes()->Get(type_idx) != NULL;
Ian Rogers28ad40d2011-10-27 15:19:26 -070069 }
Ian Rogersa3760aa2011-11-14 14:32:37 -080070 bool CanAssumeStringIsPresentInDexCache(const DexCache* dex_cache, uint32_t string_idx) const {
71 return IsImage() && dex_cache->GetStrings()->Get(string_idx) != NULL;
Ian Rogers28ad40d2011-10-27 15:19:26 -070072 }
Ian Rogersa3760aa2011-11-14 14:32:37 -080073 bool CanAccessTypeWithoutChecks(uint32_t referrer_idx, const DexCache* dex_cache,
74 const DexFile& dex_file, uint32_t type_idx) const {
75 Class* resolved_class = dex_cache->GetResolvedTypes()->Get(type_idx);
Ian Rogers28ad40d2011-10-27 15:19:26 -070076 // We should never ask whether a type needs access checks to raise a verification error,
77 // all other cases where this following test could fail should have been rewritten by the
Ian Rogersa3760aa2011-11-14 14:32:37 -080078 // verifier to verification errors. Also need to handle a lack of knowledge at compile time.
79#ifndef NDEBUG
80 Class* referrer_class = dex_cache->GetResolvedTypes()
81 ->Get(dex_file.GetMethodId(referrer_idx).class_idx_);
82 DCHECK(resolved_class == NULL || referrer_class == NULL ||
83 referrer_class->CanAccess(resolved_class));
84#endif
Ian Rogers28ad40d2011-10-27 15:19:26 -070085 return resolved_class != NULL;
86 }
Ian Rogers0571d352011-11-03 19:51:38 -070087
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -070088 private:
89 // Attempt to resolve all type, methods, fields, and strings
90 // referenced from code in the dex file following PathClassLoader
91 // ordering semantics.
92 void Resolve(const ClassLoader* class_loader);
93 void ResolveDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
94
jeffhao98eacac2011-09-14 16:11:53 -070095 void Verify(const ClassLoader* class_loader);
96 void VerifyDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
97
Brian Carlstroma5a97a22011-09-15 14:08:49 -070098 void InitializeClassesWithoutClinit(const ClassLoader* class_loader);
99 void InitializeClassesWithoutClinit(const ClassLoader* class_loader, const DexFile& dex_file);
100
Brian Carlstrom83db7722011-08-26 17:32:56 -0700101 void Compile(const ClassLoader* class_loader);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700102 void CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
Ian Rogers0571d352011-11-03 19:51:38 -0700103 void CompileClass(const DexFile::ClassDef& class_def, const ClassLoader* class_loader,
104 const DexFile& dex_file);
Ian Rogersa3760aa2011-11-14 14:32:37 -0800105 void CompileMethod(const DexFile::CodeItem* code_item, uint32_t access_flags, uint32_t method_idx,
106 const ClassLoader* class_loader, const DexFile& dex_file);
Brian Carlstrom83db7722011-08-26 17:32:56 -0700107
108 // After compiling, walk all the DexCaches and set the code and
Brian Carlstrom9cc262e2011-08-28 12:45:30 -0700109 // method pointers of CodeAndDirectMethods entries in the DexCaches.
110 void SetCodeAndDirectMethods(const ClassLoader* class_loader);
Brian Carlstrom8a487412011-08-29 20:08:52 -0700111 void SetCodeAndDirectMethodsDexFile(const DexFile& dex_file);
Ian Rogers2c8f6532011-09-02 17:16:34 -0700112
Ian Rogers0571d352011-11-03 19:51:38 -0700113 void InsertInvokeStub(bool is_static, const char* shorty,
114 const CompiledInvokeStub* compiled_invoke_stub);
115
Ian Rogers2c8f6532011-09-02 17:16:34 -0700116 InstructionSet instruction_set_;
117 JniCompiler jni_compiler_;
118
Ian Rogers0571d352011-11-03 19:51:38 -0700119 struct MethodReferenceHash {
120 size_t operator()(const MethodReference id) const {
121 size_t dex = reinterpret_cast<size_t>(id.first);
122 DCHECK_NE(dex, static_cast<size_t>(0));
123 dex += 33; // dex is an aligned pointer, get some non-zero low bits
124 size_t idx = id.second;
125 if (idx == 0) { // special case of a method index of 0
126 return dex * 5381;
127 } else {
128 return dex * idx;
129 }
130 }
131 };
132 typedef std::tr1::unordered_map<const MethodReference, CompiledMethod*, MethodReferenceHash> MethodTable;
133 // All method references that this compiler has compiled
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700134 MethodTable compiled_methods_;
135
Ian Rogers0571d352011-11-03 19:51:38 -0700136 typedef std::tr1::unordered_map<std::string, const CompiledInvokeStub*> InvokeStubTable;
137 // Invocation stubs created to allow invocation of the compiled methods
Brian Carlstrom3320cf42011-10-04 14:58:28 -0700138 InvokeStubTable compiled_invoke_stubs_;
139
Brian Carlstromaded5f72011-10-07 17:15:04 -0700140 bool image_;
141
Brian Carlstrom16192862011-09-12 17:50:06 -0700142 bool verbose_;
143
Ian Rogers2c8f6532011-09-02 17:16:34 -0700144 DISALLOW_COPY_AND_ASSIGN(Compiler);
Brian Carlstrom9ea1cb12011-08-24 23:18:18 -0700145};
146
147} // namespace art
148
149#endif // ART_SRC_COMPILER_H_