blob: 20960d209ba522b591e15b31017ce1d37a46ce19 [file] [log] [blame]
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: cshapiro@google.com (Carl Shapiro)
3
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07004#include "class_linker.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07005
6#include <vector>
7#include <utility>
8
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07009#include "casts.h"
10#include "dex_file.h"
11#include "dex_verifier.h"
12#include "heap.h"
13#include "logging.h"
14#include "monitor.h"
15#include "object.h"
16#include "raw_dex_file.h"
17#include "scoped_ptr.h"
18#include "thread.h"
19#include "utils.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070020
21namespace art {
22
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070023ClassLinker* ClassLinker::Create(std::vector<RawDexFile*> boot_class_path) {
Carl Shapiro61e019d2011-07-14 16:53:09 -070024 scoped_ptr<ClassLinker> class_linker(new ClassLinker);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070025 class_linker->Init(boot_class_path);
Carl Shapiro61e019d2011-07-14 16:53:09 -070026 // TODO: check for failure during initialization
27 return class_linker.release();
28}
29
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070030void ClassLinker::Init(std::vector<RawDexFile*> boot_class_path) {
31
32 // setup boot_class_path_ so that object_array_class_ can be properly initialized
33 for (size_t i = 0; i != boot_class_path.size(); ++i) {
34 AppendToBootClassPath(boot_class_path[i]);
35 }
36
Brian Carlstroma0808032011-07-18 00:39:23 -070037 // Allocate and partially initialize the Class, Object, Field, Method classes.
Brian Carlstrom934486c2011-07-12 23:42:50 -070038 // Initialization will be completed when the definitions are loaded.
Carl Shapiro69759ea2011-07-21 18:13:35 -070039 java_lang_Class_ = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(Class)));
Brian Carlstroma331b3c2011-07-18 17:47:56 -070040 CHECK(java_lang_Class_ != NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070041 java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
Brian Carlstroma0808032011-07-18 00:39:23 -070042 java_lang_Class_->object_size_ = sizeof(Class);
43 java_lang_Class_->klass_ = java_lang_Class_;
44
45 java_lang_Object_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070046 CHECK(java_lang_Object_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070047 java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
48
49 java_lang_Class_->super_class_ = java_lang_Object_;
50
51 java_lang_ref_Field_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070052 CHECK(java_lang_ref_Field_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070053 java_lang_ref_Field_->descriptor_ = "Ljava/lang/ref/Field;";
54
55 java_lang_ref_Method_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070056 CHECK(java_lang_ref_Method_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070057 java_lang_ref_Method_->descriptor_ = "Ljava/lang/Method;";
Carl Shapiro565f5072011-07-10 13:39:43 -070058
Brian Carlstroma331b3c2011-07-18 17:47:56 -070059 java_lang_Cloneable_ = AllocClass(NULL);
60 CHECK(java_lang_Cloneable_ != NULL);
61 java_lang_Cloneable_->descriptor_ = "Ljava/lang/Cloneable;";
Brian Carlstroma0808032011-07-18 00:39:23 -070062
Brian Carlstroma331b3c2011-07-18 17:47:56 -070063 java_io_Serializable_ = AllocClass(NULL);
64 CHECK(java_io_Serializable_ != NULL);
65 java_io_Serializable_->descriptor_ = "Ljava/io/Serializable;";
66
67 java_lang_String_ = AllocClass(NULL);
68 CHECK(java_lang_String_ != NULL);
69 java_lang_String_->descriptor_ = "Ljava/lang/String;";
70
71 // Allocate and initialize the primitive type classes.
72 primitive_byte_ = CreatePrimitiveClass("B");
73 primitive_char_ = CreatePrimitiveClass("C");
74 primitive_double_ = CreatePrimitiveClass("D");
75 primitive_float_ = CreatePrimitiveClass("F");
76 primitive_int_ = CreatePrimitiveClass("I");
77 primitive_long_ = CreatePrimitiveClass("J");
78 primitive_short_ = CreatePrimitiveClass("S");
79 primitive_boolean_ = CreatePrimitiveClass("Z");
80 primitive_void_ = CreatePrimitiveClass("V");
81
82 char_array_class_ = FindSystemClass("[C");
83 CHECK(char_array_class_ != NULL);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070084
85 object_array_class_ = FindSystemClass("[Ljava/lang/Object;");
86 CHECK(object_array_class_ != NULL);
87}
88
89DexFile* ClassLinker::AllocDexFile() {
90 return down_cast<DexFile*>(Heap::AllocObjectArray(object_array_class_, DexFile::kMax));
Brian Carlstroma0808032011-07-18 00:39:23 -070091}
92
93Class* ClassLinker::AllocClass(DexFile* dex_file) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070094 Class* klass = down_cast<Class*>(Heap::AllocObject(java_lang_Class_));
Brian Carlstroma0808032011-07-18 00:39:23 -070095 klass->dex_file_ = dex_file;
96 return klass;
97}
98
99StaticField* ClassLinker::AllocStaticField() {
Carl Shapiro69759ea2011-07-21 18:13:35 -0700100 return down_cast<StaticField*>(Heap::AllocObject(java_lang_ref_Field_,
101 sizeof(StaticField)));
Brian Carlstroma0808032011-07-18 00:39:23 -0700102}
103
104InstanceField* ClassLinker::AllocInstanceField() {
Carl Shapiro69759ea2011-07-21 18:13:35 -0700105 return down_cast<InstanceField*>(Heap::AllocObject(java_lang_ref_Field_,
106 sizeof(InstanceField)));
Brian Carlstroma0808032011-07-18 00:39:23 -0700107}
108
109Method* ClassLinker::AllocMethod() {
Carl Shapiro69759ea2011-07-21 18:13:35 -0700110 return down_cast<Method*>(Heap::AllocObject(java_lang_ref_Method_,
111 sizeof(Method)));
Carl Shapiro565f5072011-07-10 13:39:43 -0700112}
113
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700114ObjectArray* ClassLinker::AllocObjectArray(size_t length) {
115 return Heap::AllocObjectArray(object_array_class_, length);
116}
117
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700118Class* ClassLinker::FindClass(const StringPiece& descriptor,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700119 Object* class_loader,
120 const RawDexFile* raw_dex_file) {
Carl Shapirob5573532011-07-12 18:22:59 -0700121 Thread* self = Thread::Current();
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700122 DCHECK(self != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700123 CHECK(!self->IsExceptionPending());
124 // Find the class in the loaded classes table.
125 Class* klass = LookupClass(descriptor, class_loader);
126 if (klass == NULL) {
127 // Class is not yet loaded.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700128 if (descriptor[0] == '[') {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700129 return CreateArrayClass(descriptor, class_loader, raw_dex_file);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700130 }
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700131 ClassPathEntry pair;
132 if (raw_dex_file == NULL) {
133 pair = FindInBootClassPath(descriptor);
134 } else {
135 pair.first = raw_dex_file;
136 pair.second = raw_dex_file->FindClassDef(descriptor);
137 }
138 if (pair.second == NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700139 LG << "Class " << descriptor << " not found"; // TODO: NoClassDefFoundError
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700140 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700141 }
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700142 const RawDexFile* raw_dex_file = pair.first;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700143 const RawDexFile::ClassDef* class_def = pair.second;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700144 DexFile* dex_file = FindDexFile(raw_dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700145 // Load the class from the dex file.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700146 if (descriptor == "Ljava/lang/Object;") {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700147 klass = java_lang_Object_;
148 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700149 klass->object_size_ = sizeof(Object);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700150 char_array_class_->super_class_idx_ = class_def->class_idx_;
151 } else if (descriptor == "Ljava/lang/Class;") {
Carl Shapiro565f5072011-07-10 13:39:43 -0700152 klass = java_lang_Class_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700153 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700154 klass->object_size_ = sizeof(Class);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700155 } else if (descriptor == "Ljava/lang/ref/Field;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700156 klass = java_lang_ref_Field_;
157 klass->dex_file_ = dex_file;
158 klass->object_size_ = sizeof(Field);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700159 } else if (descriptor == "Ljava/lang/ref/Method;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700160 klass = java_lang_ref_Method_;
161 klass->dex_file_ = dex_file;
162 klass->object_size_ = sizeof(Method);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700163 } else if (descriptor == "Ljava/lang/Cloneable;") {
164 klass = java_lang_Cloneable_;
165 klass->dex_file_ = dex_file;
166 } else if (descriptor == "Ljava/io/Serializable;") {
167 klass = java_io_Serializable_;
168 klass->dex_file_ = dex_file;
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700169 } else if (descriptor == "Ljava/lang/String;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700170 klass = java_lang_String_;
171 klass->dex_file_ = dex_file;
172 klass->object_size_ = sizeof(String);
Carl Shapiro565f5072011-07-10 13:39:43 -0700173 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -0700174 klass = AllocClass(dex_file);
Carl Shapiro565f5072011-07-10 13:39:43 -0700175 }
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700176 LoadClass(*raw_dex_file, *class_def, klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700177 // Check for a pending exception during load
178 if (self->IsExceptionPending()) {
179 // TODO: free native allocations in klass
180 return NULL;
181 }
182 {
183 ObjectLock lock(klass);
Carl Shapirob5573532011-07-12 18:22:59 -0700184 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700185 // Add the newly loaded class to the loaded classes table.
186 bool success = InsertClass(klass);
187 if (!success) {
188 // We may fail to insert if we raced with another thread.
189 klass->clinit_thread_id_ = 0;
190 // TODO: free native allocations in klass
191 klass = LookupClass(descriptor, class_loader);
192 CHECK(klass != NULL);
193 } else {
194 // Link the class.
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700195 if (!LinkClass(klass, raw_dex_file)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700196 // Linking failed.
197 // TODO: CHECK(self->IsExceptionPending());
198 lock.NotifyAll();
199 return NULL;
200 }
201 }
202 }
203 }
204 // Link the class if it has not already been linked.
205 if (!klass->IsLinked() && !klass->IsErroneous()) {
206 ObjectLock lock(klass);
207 // Check for circular dependencies between classes.
Carl Shapirob5573532011-07-12 18:22:59 -0700208 if (!klass->IsLinked() && klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700209 LG << "Recursive link"; // TODO: ClassCircularityError
210 return NULL;
211 }
212 // Wait for the pending initialization to complete.
213 while (!klass->IsLinked() && !klass->IsErroneous()) {
214 lock.Wait();
215 }
216 }
217 if (klass->IsErroneous()) {
218 LG << "EarlierClassFailure"; // TODO: EarlierClassFailure
219 return NULL;
220 }
221 // Return the loaded class. No exceptions should be pending.
222 CHECK(!self->IsExceptionPending());
223 return klass;
224}
225
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700226void ClassLinker::LoadClass(const RawDexFile& raw_dex_file,
227 const RawDexFile::ClassDef& class_def,
228 Class* klass) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700229 CHECK(klass != NULL);
230 CHECK(klass->dex_file_ != NULL);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700231 const byte* class_data = raw_dex_file.GetClassData(class_def);
232 RawDexFile::ClassDataHeader header = raw_dex_file.ReadClassDataHeader(&class_data);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700233
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700234 const char* descriptor = raw_dex_file.GetClassDescriptor(class_def);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700235 CHECK(descriptor != NULL);
236
237 klass->klass_ = java_lang_Class_;
238 klass->descriptor_.set(descriptor);
239 klass->descriptor_alloc_ = NULL;
240 klass->access_flags_ = class_def.access_flags_;
241 klass->class_loader_ = NULL; // TODO
242 klass->primitive_type_ = Class::kPrimNot;
243 klass->status_ = Class::kStatusIdx;
244
245 klass->super_class_ = NULL;
246 klass->super_class_idx_ = class_def.superclass_idx_;
247
Carl Shapiro69759ea2011-07-21 18:13:35 -0700248 klass->num_static_fields_ = header.static_fields_size_;
249 klass->num_instance_fields_ = header.instance_fields_size_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700250 klass->num_direct_methods_ = header.direct_methods_size_;
251 klass->num_virtual_methods_ = header.virtual_methods_size_;
252
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700253 klass->source_file_ = raw_dex_file.dexGetSourceFile(class_def);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700254
255 // Load class interfaces.
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700256 LoadInterfaces(raw_dex_file, class_def, klass);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700257
258 // Load static fields.
Carl Shapiro69759ea2011-07-21 18:13:35 -0700259 if (klass->NumStaticFields() != 0) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700260 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700261 klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700262 uint32_t last_idx = 0;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700263 for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700264 RawDexFile::Field raw_field;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700265 raw_dex_file.dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700266 StaticField* sfield = AllocStaticField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700267 klass->sfields_[i] = sfield;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700268 LoadField(raw_dex_file, raw_field, klass, sfield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700269 }
270 }
271
272 // Load instance fields.
273 if (klass->NumInstanceFields() != 0) {
274 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700275 klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700276 uint32_t last_idx = 0;
277 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
278 RawDexFile::Field raw_field;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700279 raw_dex_file.dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700280 InstanceField* ifield = AllocInstanceField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700281 klass->ifields_[i] = ifield;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700282 LoadField(raw_dex_file, raw_field, klass, ifield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700283 }
284 }
285
286 // Load direct methods.
287 if (klass->NumDirectMethods() != 0) {
288 // TODO: append direct methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700289 klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700290 uint32_t last_idx = 0;
291 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
292 RawDexFile::Method raw_method;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700293 raw_dex_file.dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700294 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700295 klass->direct_methods_[i] = meth;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700296 LoadMethod(raw_dex_file, raw_method, klass, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700297 // TODO: register maps
298 }
299 }
300
301 // Load virtual methods.
302 if (klass->NumVirtualMethods() != 0) {
303 // TODO: append virtual methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700304 klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700305 uint32_t last_idx = 0;
306 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
307 RawDexFile::Method raw_method;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700308 raw_dex_file.dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700309 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700310 klass->virtual_methods_[i] = meth;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700311 LoadMethod(raw_dex_file, raw_method, klass, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700312 // TODO: register maps
313 }
314 }
Brian Carlstrom934486c2011-07-12 23:42:50 -0700315}
316
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700317void ClassLinker::LoadInterfaces(const RawDexFile& raw_dex_file,
318 const RawDexFile::ClassDef& class_def,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700319 Class* klass) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700320 const RawDexFile::TypeList* list = raw_dex_file.GetInterfacesList(class_def);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700321 if (list != NULL) {
322 klass->interface_count_ = list->Size();
323 // TODO: allocate the interfaces array on the object heap.
324 klass->interfaces_ = new Class*[list->Size()]();
325 for (size_t i = 0; i < list->Size(); ++i) {
326 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
327 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
328 }
329 }
330}
331
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700332void ClassLinker::LoadField(const RawDexFile& raw_dex_file,
333 const RawDexFile::Field& src,
334 Class* klass,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700335 Field* dst) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700336 const RawDexFile::FieldId& field_id = raw_dex_file.GetFieldId(src.field_idx_);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700337 dst->klass_ = klass;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700338 dst->name_ = raw_dex_file.dexStringById(field_id.name_idx_);
339 dst->signature_ = raw_dex_file.dexStringByTypeIdx(field_id.type_idx_);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700340 dst->access_flags_ = src.access_flags_;
341}
342
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700343void ClassLinker::LoadMethod(const RawDexFile& raw_dex_file,
344 const RawDexFile::Method& src,
345 Class* klass,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700346 Method* dst) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700347 const RawDexFile::MethodId& method_id = raw_dex_file.GetMethodId(src.method_idx_);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700348 dst->klass_ = klass;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700349 dst->name_.set(raw_dex_file.dexStringById(method_id.name_idx_));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700350 dst->proto_idx_ = method_id.proto_idx_;
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700351 dst->shorty_.set(raw_dex_file.GetShorty(method_id.proto_idx_));
Brian Carlstrom934486c2011-07-12 23:42:50 -0700352 dst->access_flags_ = src.access_flags_;
353
354 // TODO: check for finalize method
355
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700356 const RawDexFile::CodeItem* code_item = raw_dex_file.GetCodeItem(src);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700357 if (code_item != NULL) {
358 dst->num_registers_ = code_item->registers_size_;
359 dst->num_ins_ = code_item->ins_size_;
360 dst->num_outs_ = code_item->outs_size_;
361 dst->insns_ = code_item->insns_;
362 } else {
363 uint16_t num_args = dst->NumArgRegisters();
364 if (!dst->IsStatic()) {
365 ++num_args;
366 }
367 dst->num_registers_ = dst->num_ins_ + num_args;
368 // TODO: native methods
369 }
370}
371
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700372ClassLinker::ClassPathEntry ClassLinker::FindInBootClassPath(const StringPiece& descriptor) {
373 for (size_t i = 0; i != boot_class_path_.size(); ++i) {
374 RawDexFile* raw_dex_file = boot_class_path_[i];
375 const RawDexFile::ClassDef* class_def = raw_dex_file->FindClassDef(descriptor);
Brian Carlstroma0808032011-07-18 00:39:23 -0700376 if (class_def != NULL) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700377 return ClassPathEntry(raw_dex_file, class_def);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700378 }
379 }
Brian Carlstroma0808032011-07-18 00:39:23 -0700380 return ClassPathEntry(NULL, NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700381}
382
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700383void ClassLinker::AppendToBootClassPath(RawDexFile* raw_dex_file) {
384 boot_class_path_.push_back(raw_dex_file);
385 RegisterDexFile(raw_dex_file);
386}
387
388void ClassLinker::RegisterDexFile(RawDexFile* raw_dex_file) {
389 raw_dex_files_.push_back(raw_dex_file);
390 DexFile* dex_file = AllocDexFile();
391 CHECK(dex_file != NULL);
392 dex_file->Init(AllocObjectArray(raw_dex_file->NumStringIds()),
393 AllocObjectArray(raw_dex_file->NumTypeIds()),
394 AllocObjectArray(raw_dex_file->NumMethodIds()),
395 AllocObjectArray(raw_dex_file->NumFieldIds()));
396 dex_files_.push_back(dex_file);
397}
398
399const RawDexFile* ClassLinker::FindRawDexFile(const DexFile* dex_file) const {
400 CHECK(dex_file != NULL);
401 for (size_t i = 0; i != dex_files_.size(); ++i) {
402 if (dex_files_[i] == dex_file) {
403 return raw_dex_files_[i];
404 }
405 }
406 CHECK(false) << "Could not find RawDexFile";
407 return NULL;
408}
409
410DexFile* ClassLinker::FindDexFile(const RawDexFile* raw_dex_file) const {
411 CHECK(raw_dex_file != NULL);
412 for (size_t i = 0; i != raw_dex_files_.size(); ++i) {
413 if (raw_dex_files_[i] == raw_dex_file) {
414 return dex_files_[i];
415 }
416 }
417 CHECK(false) << "Could not find DexFile";
418 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700419}
420
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700421Class* ClassLinker::CreatePrimitiveClass(const StringPiece& descriptor) {
Brian Carlstroma0808032011-07-18 00:39:23 -0700422 Class* klass = AllocClass(NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -0700423 CHECK(klass != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -0700424 klass->super_class_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700425 klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
426 klass->descriptor_ = descriptor;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700427 klass->descriptor_alloc_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700428 klass->status_ = Class::kStatusInitialized;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700429 bool success = InsertClass(klass);
430 CHECK(success);
Carl Shapiro565f5072011-07-10 13:39:43 -0700431 return klass;
432}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700433
Brian Carlstrombe977852011-07-19 14:54:54 -0700434// Create an array class (i.e. the class object for the array, not the
435// array itself). "descriptor" looks like "[C" or "[[[[B" or
436// "[Ljava/lang/String;".
437//
438// If "descriptor" refers to an array of primitives, look up the
439// primitive type's internally-generated class object.
440//
441// "loader" is the class loader of the class that's referring to us. It's
442// used to ensure that we're looking for the element type in the right
443// context. It does NOT become the class loader for the array class; that
444// always comes from the base element class.
445//
446// Returns NULL with an exception raised on failure.
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700447Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor,
448 Object* class_loader,
449 const RawDexFile* raw_dex_file)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700450{
451 CHECK(descriptor[0] == '[');
452 DCHECK(java_lang_Class_ != NULL);
453 DCHECK(java_lang_Object_ != NULL);
454
Brian Carlstrombe977852011-07-19 14:54:54 -0700455 // Identify the underlying element class and the array dimension depth.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700456 Class* component_type_ = NULL;
457 int array_rank;
458 if (descriptor[1] == '[') {
Brian Carlstrombe977852011-07-19 14:54:54 -0700459 // array of arrays; keep descriptor and grab stuff from parent
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700460 Class* outer = FindClass(descriptor.substr(1), class_loader, raw_dex_file);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700461 if (outer != NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700462 // want the base class, not "outer", in our component_type_
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700463 component_type_ = outer->component_type_;
464 array_rank = outer->array_rank_ + 1;
465 } else {
Brian Carlstrombe977852011-07-19 14:54:54 -0700466 DCHECK(component_type_ == NULL); // make sure we fail
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700467 }
468 } else {
469 array_rank = 1;
470 if (descriptor[1] == 'L') {
Brian Carlstrombe977852011-07-19 14:54:54 -0700471 // array of objects; strip off "[" and look up descriptor.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700472 const StringPiece subDescriptor = descriptor.substr(1);
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700473 component_type_ = FindClass(subDescriptor, class_loader, raw_dex_file);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700474 } else {
Brian Carlstrombe977852011-07-19 14:54:54 -0700475 // array of a primitive type
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700476 component_type_ = FindPrimitiveClass(descriptor[1]);
477 }
478 }
479
480 if (component_type_ == NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700481 // failed
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700482 DCHECK(Thread::Current()->IsExceptionPending());
483 return NULL;
484 }
485
Brian Carlstrombe977852011-07-19 14:54:54 -0700486 // See if the component type is already loaded. Array classes are
487 // always associated with the class loader of their underlying
488 // element type -- an array of Strings goes with the loader for
489 // java/lang/String -- so we need to look for it there. (The
490 // caller should have checked for the existence of the class
491 // before calling here, but they did so with *their* class loader,
492 // not the component type's loader.)
493 //
494 // If we find it, the caller adds "loader" to the class' initiating
495 // loader list, which should prevent us from going through this again.
496 //
497 // This call is unnecessary if "loader" and "component_type_->class_loader_"
498 // are the same, because our caller (FindClass) just did the
499 // lookup. (Even if we get this wrong we still have correct behavior,
500 // because we effectively do this lookup again when we add the new
501 // class to the hash table --- necessary because of possible races with
502 // other threads.)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700503 if (class_loader != component_type_->class_loader_) {
504 Class* new_class = LookupClass(descriptor, component_type_->class_loader_);
505 if (new_class != NULL) {
506 return new_class;
507 }
508 }
509
Brian Carlstrombe977852011-07-19 14:54:54 -0700510 // Fill out the fields in the Class.
511 //
512 // It is possible to execute some methods against arrays, because
513 // all arrays are subclasses of java_lang_Object_, so we need to set
514 // up a vtable. We can just point at the one in java_lang_Object_.
515 //
516 // Array classes are simple enough that we don't need to do a full
517 // link step.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700518 Class* new_class = AllocClass(NULL);
519 if (new_class == NULL) {
520 return NULL;
521 }
522 new_class->descriptor_alloc_ = new std::string(descriptor.data(),
523 descriptor.size());
524 new_class->descriptor_.set(new_class->descriptor_alloc_->data(),
525 new_class->descriptor_alloc_->size());
526 new_class->super_class_ = java_lang_Object_;
527 new_class->vtable_count_ = java_lang_Object_->vtable_count_;
528 new_class->vtable_ = java_lang_Object_->vtable_;
529 new_class->primitive_type_ = Class::kPrimNot;
530 new_class->component_type_ = component_type_;
531 new_class->class_loader_ = component_type_->class_loader_;
532 new_class->array_rank_ = array_rank;
533 new_class->status_ = Class::kStatusInitialized;
Brian Carlstrombe977852011-07-19 14:54:54 -0700534 // don't need to set new_class->object_size_
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700535
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700536
Brian Carlstrombe977852011-07-19 14:54:54 -0700537 // All arrays have java/lang/Cloneable and java/io/Serializable as
538 // interfaces. We need to set that up here, so that stuff like
539 // "instanceof" works right.
540 //
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700541 // Note: The GC could run during the call to FindSystemClass,
Brian Carlstrombe977852011-07-19 14:54:54 -0700542 // so we need to make sure the class object is GC-valid while we're in
543 // there. Do this by clearing the interface list so the GC will just
544 // think that the entries are null.
545 //
546 // TODO?
547 // We may want to create a single, global copy of "interfaces" and
548 // "iftable" somewhere near the start and just point to those (and
549 // remember not to free them for arrays).
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700550 new_class->interface_count_ = 2;
551 new_class->interfaces_ = new Class*[2];
552 memset(new_class->interfaces_, 0, sizeof(Class*) * 2);
553 new_class->interfaces_[0] = java_lang_Cloneable_;
554 new_class->interfaces_[1] = java_io_Serializable_;
Brian Carlstrombe977852011-07-19 14:54:54 -0700555
556 // We assume that Cloneable/Serializable don't have superinterfaces --
557 // normally we'd have to crawl up and explicitly list all of the
558 // supers as well. These interfaces don't have any methods, so we
559 // don't have to worry about the ifviPool either.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700560 new_class->iftable_count_ = 2;
561 new_class->iftable_ = new InterfaceEntry[2];
562 memset(new_class->iftable_, 0, sizeof(InterfaceEntry) * 2);
563 new_class->iftable_[0].SetClass(new_class->interfaces_[0]);
564 new_class->iftable_[1].SetClass(new_class->interfaces_[1]);
565
Brian Carlstrombe977852011-07-19 14:54:54 -0700566 // Inherit access flags from the component type. Arrays can't be
567 // used as a superclass or interface, so we want to add "final"
568 // and remove "interface".
569 //
570 // Don't inherit any non-standard flags (e.g., kAccFinal)
571 // from component_type_. We assume that the array class does not
572 // override finalize().
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700573 new_class->access_flags_ = ((new_class->component_type_->access_flags_ &
574 ~kAccInterface) | kAccFinal) & kAccJavaFlagsMask;
575
576 if (InsertClass(new_class)) {
577 return new_class;
578 }
Brian Carlstrombe977852011-07-19 14:54:54 -0700579 // Another thread must have loaded the class after we
580 // started but before we finished. Abandon what we've
581 // done.
582 //
583 // (Yes, this happens.)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700584
Brian Carlstrombe977852011-07-19 14:54:54 -0700585 // Grab the winning class.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700586 Class* other_class = LookupClass(descriptor, component_type_->class_loader_);
587 DCHECK(other_class != NULL);
588 return other_class;
589}
590
591Class* ClassLinker::FindPrimitiveClass(char type) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700592 switch (type) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700593 case 'B':
Carl Shapiro565f5072011-07-10 13:39:43 -0700594 CHECK(primitive_byte_ != NULL);
595 return primitive_byte_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700596 case 'C':
Carl Shapiro565f5072011-07-10 13:39:43 -0700597 CHECK(primitive_char_ != NULL);
598 return primitive_char_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700599 case 'D':
Carl Shapiro565f5072011-07-10 13:39:43 -0700600 CHECK(primitive_double_ != NULL);
601 return primitive_double_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700602 case 'F':
Carl Shapiro565f5072011-07-10 13:39:43 -0700603 CHECK(primitive_float_ != NULL);
604 return primitive_float_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700605 case 'I':
Carl Shapiro565f5072011-07-10 13:39:43 -0700606 CHECK(primitive_int_ != NULL);
607 return primitive_int_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700608 case 'J':
Carl Shapiro565f5072011-07-10 13:39:43 -0700609 CHECK(primitive_long_ != NULL);
610 return primitive_long_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700611 case 'S':
Carl Shapiro565f5072011-07-10 13:39:43 -0700612 CHECK(primitive_short_ != NULL);
613 return primitive_short_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700614 case 'Z':
Carl Shapiro565f5072011-07-10 13:39:43 -0700615 CHECK(primitive_boolean_ != NULL);
616 return primitive_boolean_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700617 case 'V':
Carl Shapiro565f5072011-07-10 13:39:43 -0700618 CHECK(primitive_void_ != NULL);
619 return primitive_void_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700620 case 'L':
621 case '[':
622 LOG(ERROR) << "Not a primitive type " << static_cast<int>(type);
Carl Shapiro565f5072011-07-10 13:39:43 -0700623 default:
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700624 LOG(ERROR) << "Unknown primitive type " << static_cast<int>(type);
Carl Shapiro565f5072011-07-10 13:39:43 -0700625 };
626 return NULL; // Not reachable.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700627}
628
629bool ClassLinker::InsertClass(Class* klass) {
630 // TODO: acquire classes_lock_
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700631 const StringPiece& key = klass->GetDescriptor();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700632 bool success = classes_.insert(std::make_pair(key, klass)).second;
633 // TODO: release classes_lock_
634 return success;
635}
636
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700637Class* ClassLinker::LookupClass(const StringPiece& descriptor, Object* class_loader) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700638 // TODO: acquire classes_lock_
639 Table::iterator it = classes_.find(descriptor);
640 // TODO: release classes_lock_
641 if (it == classes_.end()) {
642 return NULL;
643 } else {
644 return (*it).second;
645 }
646}
647
648bool ClassLinker::InitializeClass(Class* klass) {
649 CHECK(klass->GetStatus() == Class::kStatusResolved ||
650 klass->GetStatus() == Class::kStatusError);
651
Carl Shapirob5573532011-07-12 18:22:59 -0700652 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700653
654 {
655 ObjectLock lock(klass);
656
657 if (klass->GetStatus() < Class::kStatusVerified) {
658 if (klass->IsErroneous()) {
659 LG << "re-initializing failed class"; // TODO: throw
660 return false;
661 }
662
663 CHECK(klass->GetStatus() == Class::kStatusResolved);
664
665 klass->status_ = Class::kStatusVerifying;
666 if (!DexVerify::VerifyClass(klass)) {
667 LG << "Verification failed"; // TODO: ThrowVerifyError
668 Object* exception = self->GetException();
Carl Shapiro69759ea2011-07-21 18:13:35 -0700669 size_t field_offset = OFFSETOF_MEMBER(Class, verify_error_class_);
670 klass->SetFieldObject(field_offset, exception->GetClass());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700671 klass->SetStatus(Class::kStatusError);
672 return false;
673 }
674
675 klass->SetStatus(Class::kStatusVerified);
676 }
677
678 if (klass->status_ == Class::kStatusInitialized) {
679 return true;
680 }
681
682 while (klass->status_ == Class::kStatusInitializing) {
683 // we caught somebody else in the act; was it us?
Carl Shapirob5573532011-07-12 18:22:59 -0700684 if (klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700685 LG << "recursive <clinit>";
686 return true;
687 }
688
689 CHECK(!self->IsExceptionPending());
690
691 lock.Wait(); // TODO: check for interruption
692
693 // When we wake up, repeat the test for init-in-progress. If
694 // there's an exception pending (only possible if
695 // "interruptShouldThrow" was set), bail out.
696 if (self->IsExceptionPending()) {
697 CHECK(false);
698 LG << "Exception in initialization."; // TODO: ExceptionInInitializerError
699 klass->SetStatus(Class::kStatusError);
700 return false;
701 }
702 if (klass->GetStatus() == Class::kStatusInitializing) {
703 continue;
704 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700705 DCHECK(klass->GetStatus() == Class::kStatusInitialized ||
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700706 klass->GetStatus() == Class::kStatusError);
707 if (klass->IsErroneous()) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700708 // The caller wants an exception, but it was thrown in a
709 // different thread. Synthesize one here.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700710 LG << "<clinit> failed"; // TODO: throw UnsatisfiedLinkError
711 return false;
712 }
713 return true; // otherwise, initialized
714 }
715
716 // see if we failed previously
717 if (klass->IsErroneous()) {
718 // might be wise to unlock before throwing; depends on which class
719 // it is that we have locked
720
721 // TODO: throwEarlierClassFailure(klass);
722 return false;
723 }
724
725 if (!ValidateSuperClassDescriptors(klass)) {
726 klass->SetStatus(Class::kStatusError);
727 return false;
728 }
729
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700730 DCHECK(klass->status_ < Class::kStatusInitializing);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700731
Carl Shapirob5573532011-07-12 18:22:59 -0700732 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700733 klass->status_ = Class::kStatusInitializing;
734 }
735
736 if (!InitializeSuperClass(klass)) {
737 return false;
738 }
739
740 InitializeStaticFields(klass);
741
742 Method* clinit = klass->FindDirectMethodLocally("<clinit>", "()V");
743 if (clinit != NULL) {
744 } else {
745 // JValue unused;
746 // TODO: dvmCallMethod(self, method, NULL, &unused);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700747 //CHECK(!"unimplemented");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700748 }
749
750 {
751 ObjectLock lock(klass);
752
753 if (self->IsExceptionPending()) {
754 klass->SetStatus(Class::kStatusError);
755 } else {
756 klass->SetStatus(Class::kStatusInitialized);
757 }
758 lock.NotifyAll();
759 }
760
761 return true;
762}
763
764bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
765 if (klass->IsInterface()) {
766 return true;
767 }
768 // begin with the methods local to the superclass
769 if (klass->HasSuperClass() &&
770 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
771 const Class* super = klass->GetSuperClass();
772 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
773 const Method* method = klass->GetVirtualMethod(i);
774 if (method != super->GetVirtualMethod(i) &&
775 !HasSameMethodDescriptorClasses(method, super, klass)) {
776 LG << "Classes resolve differently in superclass";
777 return false;
778 }
779 }
780 }
781 for (size_t i = 0; i < klass->iftable_count_; ++i) {
782 const InterfaceEntry* iftable = &klass->iftable_[i];
783 Class* interface = iftable->GetClass();
784 if (klass->GetClassLoader() != interface->GetClassLoader()) {
785 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
786 uint32_t vtable_index = iftable->method_index_array_[j];
787 const Method* method = klass->GetVirtualMethod(vtable_index);
788 if (!HasSameMethodDescriptorClasses(method, interface,
789 method->GetClass())) {
790 LG << "Classes resolve differently in interface"; // TODO: LinkageError
791 return false;
792 }
793 }
794 }
795 }
796 return true;
797}
798
799bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700800 const Class* klass1,
801 const Class* klass2) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700802 const RawDexFile* raw = FindRawDexFile(method->GetClass()->GetDexFile());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700803 const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
804 RawDexFile::ParameterIterator *it;
805 for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
806 const char* descriptor = it->GetDescriptor();
807 if (descriptor == NULL) {
808 break;
809 }
810 if (descriptor[0] == 'L' || descriptor[0] == '[') {
811 // Found a non-primitive type.
812 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
813 return false;
814 }
815 }
816 }
817 // Check the return type
818 const char* descriptor = raw->GetReturnTypeDescriptor(proto_id);
819 if (descriptor[0] == 'L' || descriptor[0] == '[') {
820 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
821 return false;
822 }
823 }
824 return true;
825}
826
827// Returns true if classes referenced by the descriptor are the
828// same classes in klass1 as they are in klass2.
829bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700830 const Class* klass1,
831 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700832 CHECK(descriptor != NULL);
833 CHECK(klass1 != NULL);
834 CHECK(klass2 != NULL);
835#if 0
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700836 Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700837 // TODO: found1 == NULL
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700838 Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700839 // TODO: found2 == NULL
840 // TODO: lookup found1 in initiating loader list
841 if (found1 == NULL || found2 == NULL) {
Carl Shapirob5573532011-07-12 18:22:59 -0700842 Thread::Current()->ClearException();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700843 if (found1 == found2) {
844 return true;
845 } else {
846 return false;
847 }
848 }
849#endif
850 return true;
851}
852
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700853bool ClassLinker::HasSameArgumentTypes(const Method* m1, const Method* m2) const {
854 const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile());
855 const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile());
856 const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_);
857 const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_);
858
859 // TODO: compare ProtoId objects for equality and exit early
860 const RawDexFile::TypeList* type_list1 = raw1->GetProtoParameters(proto1);
861 const RawDexFile::TypeList* type_list2 = raw2->GetProtoParameters(proto2);
862 size_t arity1 = (type_list1 == NULL) ? 0 : type_list1->Size();
863 size_t arity2 = (type_list2 == NULL) ? 0 : type_list2->Size();
864 if (arity1 != arity2) {
865 return false;
866 }
867
868 for (size_t i = 0; i < arity1; ++i) {
869 uint32_t type_idx1 = type_list1->GetTypeItem(i).type_idx_;
870 uint32_t type_idx2 = type_list2->GetTypeItem(i).type_idx_;
871 const char* type1 = raw1->dexStringByTypeIdx(type_idx1);
872 const char* type2 = raw2->dexStringByTypeIdx(type_idx2);
873 if (strcmp(type1, type2) != 0) {
874 return false;
875 }
876 }
877
878 return true;
879}
880
881bool ClassLinker::HasSameReturnType(const Method* m1, const Method* m2) const {
882 const RawDexFile* raw1 = FindRawDexFile(m1->GetClass()->GetDexFile());
883 const RawDexFile* raw2 = FindRawDexFile(m2->GetClass()->GetDexFile());
884 const RawDexFile::ProtoId& proto1 = raw1->GetProtoId(m1->proto_idx_);
885 const RawDexFile::ProtoId& proto2 = raw2->GetProtoId(m2->proto_idx_);
886 const char* type1 = raw1->dexStringByTypeIdx(proto1.return_type_idx_);
887 const char* type2 = raw2->dexStringByTypeIdx(proto2.return_type_idx_);
888 return (strcmp(type1, type2) == 0);
889}
890
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700891bool ClassLinker::InitializeSuperClass(Class* klass) {
892 CHECK(klass != NULL);
893 // TODO: assert klass lock is acquired
894 if (!klass->IsInterface() && klass->HasSuperClass()) {
895 Class* super_class = klass->GetSuperClass();
896 if (super_class->GetStatus() != Class::kStatusInitialized) {
897 CHECK(!super_class->IsInterface());
898 klass->MonitorExit();
899 bool super_initialized = InitializeClass(super_class);
900 klass->MonitorEnter();
901 // TODO: check for a pending exception
902 if (!super_initialized) {
903 klass->SetStatus(Class::kStatusError);
904 klass->NotifyAll();
905 return false;
906 }
907 }
908 }
909 return true;
910}
911
912void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700913 size_t num_static_fields = klass->NumStaticFields();
914 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700915 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700916 }
917 DexFile* dex_file = klass->GetDexFile();
918 if (dex_file == NULL) {
919 return;
920 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700921 const StringPiece& descriptor = klass->GetDescriptor();
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700922 const RawDexFile* raw = FindRawDexFile(dex_file);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700923 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
924 CHECK(class_def != NULL);
925 const byte* addr = raw->GetEncodedArray(*class_def);
926 size_t array_size = DecodeUnsignedLeb128(&addr);
927 for (size_t i = 0; i < array_size; ++i) {
928 StaticField* field = klass->GetStaticField(i);
929 JValue value;
930 RawDexFile::ValueType type = raw->ReadEncodedValue(&addr, &value);
931 switch (type) {
932 case RawDexFile::kByte:
933 field->SetByte(value.b);
934 break;
935 case RawDexFile::kShort:
936 field->SetShort(value.s);
937 break;
938 case RawDexFile::kChar:
939 field->SetChar(value.c);
940 break;
941 case RawDexFile::kInt:
942 field->SetInt(value.i);
943 break;
944 case RawDexFile::kLong:
945 field->SetLong(value.j);
946 break;
947 case RawDexFile::kFloat:
948 field->SetFloat(value.f);
949 break;
950 case RawDexFile::kDouble:
951 field->SetDouble(value.d);
952 break;
953 case RawDexFile::kString: {
954 uint32_t string_idx = value.i;
955 String* resolved = ResolveString(klass, string_idx);
956 field->SetObject(resolved);
957 break;
958 }
959 case RawDexFile::kBoolean:
960 field->SetBoolean(value.z);
961 break;
962 case RawDexFile::kNull:
963 field->SetObject(value.l);
964 break;
965 default:
Carl Shapiro606258b2011-07-09 16:09:09 -0700966 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700967 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700968 }
969}
970
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700971bool ClassLinker::LinkClass(Class* klass, const RawDexFile* raw_dex_file) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700972 CHECK(klass->status_ == Class::kStatusIdx ||
973 klass->status_ == Class::kStatusLoaded);
974 if (klass->status_ == Class::kStatusIdx) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700975 if (!LinkInterfaces(klass, raw_dex_file)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700976 return false;
977 }
978 }
979 if (!LinkSuperClass(klass)) {
980 return false;
981 }
982 if (!LinkMethods(klass)) {
983 return false;
984 }
985 if (!LinkInstanceFields(klass)) {
986 return false;
987 }
988 CreateReferenceOffsets(klass);
989 CHECK_EQ(klass->status_, Class::kStatusLoaded);
990 klass->status_ = Class::kStatusResolved;
991 return true;
992}
993
Brian Carlstrom578bbdc2011-07-21 14:07:47 -0700994bool ClassLinker::LinkInterfaces(Class* klass, const RawDexFile* raw_dex_file) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700995 scoped_array<uint32_t> interfaces_idx;
996 // TODO: store interfaces_idx in the Class object
997 // TODO: move this outside of link interfaces
998 if (klass->interface_count_ > 0) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700999 size_t length = klass->interface_count_ * sizeof(klass->interfaces_[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001000 interfaces_idx.reset(new uint32_t[klass->interface_count_]);
Carl Shapiro565f5072011-07-10 13:39:43 -07001001 memcpy(interfaces_idx.get(), klass->interfaces_, length);
1002 memset(klass->interfaces_, 0xFF, length);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001003 }
1004 // Mark the class as loaded.
1005 klass->status_ = Class::kStatusLoaded;
1006 if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001007 Class* super_class = ResolveClass(klass, klass->super_class_idx_, raw_dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001008 if (super_class == NULL) {
1009 LG << "Failed to resolve superclass";
1010 return false;
1011 }
1012 klass->super_class_ = super_class; // TODO: write barrier
1013 }
1014 if (klass->interface_count_ > 0) {
1015 for (size_t i = 0; i < klass->interface_count_; ++i) {
1016 uint32_t idx = interfaces_idx[i];
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001017 klass->interfaces_[i] = ResolveClass(klass, idx, raw_dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001018 if (klass->interfaces_[i] == NULL) {
1019 LG << "Failed to resolve interface";
1020 return false;
1021 }
1022 // Verify
1023 if (!klass->CanAccess(klass->interfaces_[i])) {
1024 LG << "Inaccessible interface";
1025 return false;
1026 }
1027 }
1028 }
1029 return true;
1030}
1031
1032bool ClassLinker::LinkSuperClass(Class* klass) {
1033 CHECK(!klass->IsPrimitive());
1034 const Class* super = klass->GetSuperClass();
1035 if (klass->GetDescriptor() == "Ljava/lang/Object;") {
1036 if (super != NULL) {
1037 LG << "Superclass must not be defined"; // TODO: ClassFormatError
1038 return false;
1039 }
1040 // TODO: clear finalize attribute
1041 return true;
1042 }
1043 if (super == NULL) {
1044 LG << "No superclass defined"; // TODO: LinkageError
1045 return false;
1046 }
1047 // Verify
1048 if (super->IsFinal()) {
1049 LG << "Superclass is declared final"; // TODO: IncompatibleClassChangeError
1050 return false;
1051 }
1052 if (super->IsInterface()) {
1053 LG << "Superclass is an interface"; // TODO: IncompatibleClassChangeError
1054 return false;
1055 }
1056 if (!klass->CanAccess(super)) {
1057 LG << "Superclass is inaccessible"; // TODO: IllegalAccessError
1058 return false;
1059 }
1060 return true;
1061}
1062
1063// Populate the class vtable and itable.
1064bool ClassLinker::LinkMethods(Class* klass) {
1065 if (klass->IsInterface()) {
1066 // No vtable.
1067 size_t count = klass->NumVirtualMethods();
1068 if (!IsUint(16, count)) {
1069 LG << "Too many methods on interface"; // TODO: VirtualMachineError
1070 return false;
1071 }
Carl Shapiro565f5072011-07-10 13:39:43 -07001072 for (size_t i = 0; i < count; ++i) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001073 klass->GetVirtualMethod(i)->method_index_ = i;
1074 }
1075 } else {
1076 // Link virtual method tables
1077 LinkVirtualMethods(klass);
1078
1079 // Link interface method tables
1080 LinkInterfaceMethods(klass);
1081
1082 // Insert stubs.
1083 LinkAbstractMethods(klass);
1084 }
1085 return true;
1086}
1087
1088bool ClassLinker::LinkVirtualMethods(Class* klass) {
1089 uint32_t max_count = klass->NumVirtualMethods();
1090 if (klass->GetSuperClass() != NULL) {
1091 max_count += klass->GetSuperClass()->NumVirtualMethods();
1092 } else {
1093 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
1094 }
1095 // TODO: do not assign to the vtable field until it is fully constructed.
1096 // TODO: make this a vector<Method*> instead?
1097 klass->vtable_ = new Method*[max_count];
1098 if (klass->HasSuperClass()) {
1099 memcpy(klass->vtable_,
1100 klass->GetSuperClass()->vtable_,
1101 klass->GetSuperClass()->vtable_count_ * sizeof(Method*));
1102 size_t actual_count = klass->GetSuperClass()->vtable_count_;
1103 // See if any of our virtual methods override the superclass.
1104 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1105 Method* local_method = klass->GetVirtualMethod(i);
1106 size_t j = 0;
1107 for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
1108 const Method* super_method = klass->vtable_[j];
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001109 if (HasSameNameAndPrototype(local_method, super_method)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001110 // Verify
1111 if (super_method->IsFinal()) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001112 LG << "Method overrides final method"; // TODO: VirtualMachineError
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001113 return false;
1114 }
1115 klass->vtable_[j] = local_method;
1116 local_method->method_index_ = j;
1117 break;
1118 }
1119 }
1120 if (j == klass->GetSuperClass()->vtable_count_) {
1121 // Not overriding, append.
1122 klass->vtable_[actual_count] = local_method;
1123 local_method->method_index_ = actual_count;
1124 actual_count += 1;
1125 }
1126 }
1127 if (!IsUint(16, actual_count)) {
1128 LG << "Too many methods defined on class"; // TODO: VirtualMachineError
1129 return false;
1130 }
1131 CHECK_LE(actual_count, max_count);
1132 if (actual_count < max_count) {
1133 Method** new_vtable = new Method*[actual_count];
1134 memcpy(new_vtable, klass->vtable_, actual_count * sizeof(Method*));
Carl Shapiro565f5072011-07-10 13:39:43 -07001135 delete[] klass->vtable_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001136 klass->vtable_ = new_vtable;
1137 LG << "shrunk vtable: "
1138 << "was " << max_count << ", "
1139 << "now " << actual_count;
1140 }
1141 klass->vtable_count_ = actual_count;
1142 } else {
1143 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
1144 if (!IsUint(16, klass->NumVirtualMethods())) {
1145 LG << "Too many methods"; // TODO: VirtualMachineError
1146 return false;
1147 }
1148 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1149 klass->vtable_[i] = klass->GetVirtualMethod(i);
1150 klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
1151 }
1152 klass->vtable_count_ = klass->NumVirtualMethods();
1153 }
1154 return true;
1155}
1156
1157bool ClassLinker::LinkInterfaceMethods(Class* klass) {
1158 int pool_offset = 0;
1159 int pool_size = 0;
1160 int miranda_count = 0;
1161 int miranda_alloc = 0;
1162 size_t super_ifcount;
1163 if (klass->HasSuperClass()) {
1164 super_ifcount = klass->GetSuperClass()->iftable_count_;
1165 } else {
1166 super_ifcount = 0;
1167 }
1168 size_t ifCount = super_ifcount;
1169 ifCount += klass->interface_count_;
1170 for (size_t i = 0; i < klass->interface_count_; i++) {
1171 ifCount += klass->interfaces_[i]->iftable_count_;
1172 }
1173 if (ifCount == 0) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001174 DCHECK(klass->iftable_count_ == 0);
1175 DCHECK(klass->iftable_ == NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001176 return true;
1177 }
1178 klass->iftable_ = new InterfaceEntry[ifCount * sizeof(InterfaceEntry)];
1179 memset(klass->iftable_, 0x00, sizeof(InterfaceEntry) * ifCount);
1180 if (super_ifcount != 0) {
1181 memcpy(klass->iftable_, klass->GetSuperClass()->iftable_,
1182 sizeof(InterfaceEntry) * super_ifcount);
1183 }
1184 // Flatten the interface inheritance hierarchy.
1185 size_t idx = super_ifcount;
1186 for (size_t i = 0; i < klass->interface_count_; i++) {
1187 Class* interf = klass->interfaces_[i];
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001188 DCHECK(interf != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001189 if (!interf->IsInterface()) {
1190 LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
1191 return false;
1192 }
1193 klass->iftable_[idx++].SetClass(interf);
1194 for (size_t j = 0; j < interf->iftable_count_; j++) {
1195 klass->iftable_[idx++].SetClass(interf->iftable_[j].GetClass());
1196 }
1197 }
1198 CHECK_EQ(idx, ifCount);
1199 klass->iftable_count_ = ifCount;
1200 if (klass->IsInterface() || super_ifcount == ifCount) {
1201 return true;
1202 }
1203 for (size_t i = super_ifcount; i < ifCount; i++) {
1204 pool_size += klass->iftable_[i].GetClass()->NumVirtualMethods();
1205 }
1206 if (pool_size == 0) {
1207 return true;
1208 }
1209 klass->ifvi_pool_count_ = pool_size;
1210 klass->ifvi_pool_ = new uint32_t[pool_size];
1211 std::vector<Method*> miranda_list;
1212 for (size_t i = super_ifcount; i < ifCount; ++i) {
1213 klass->iftable_[i].method_index_array_ = klass->ifvi_pool_ + pool_offset;
1214 Class* interface = klass->iftable_[i].GetClass();
1215 pool_offset += interface->NumVirtualMethods(); // end here
1216 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
1217 Method* interface_method = interface->GetVirtualMethod(j);
1218 int k; // must be signed
1219 for (k = klass->vtable_count_ - 1; k >= 0; --k) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001220 if (HasSameNameAndPrototype(interface_method, klass->vtable_[k])) {
Carl Shapiro565f5072011-07-10 13:39:43 -07001221 if (!klass->vtable_[k]->IsPublic()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001222 LG << "Implementation not public";
1223 return false;
1224 }
1225 klass->iftable_[i].method_index_array_[j] = k;
1226 break;
1227 }
1228 }
1229 if (k < 0) {
1230 if (miranda_count == miranda_alloc) {
1231 miranda_alloc += 8;
1232 if (miranda_list.empty()) {
1233 miranda_list.resize(miranda_alloc);
1234 } else {
1235 miranda_list.resize(miranda_alloc);
1236 }
1237 }
1238 int mir;
1239 for (mir = 0; mir < miranda_count; mir++) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001240 if (HasSameNameAndPrototype(miranda_list[mir], interface_method)) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001241 break;
1242 }
1243 }
1244 // point the interface table at a phantom slot index
1245 klass->iftable_[i].method_index_array_[j] = klass->vtable_count_ + mir;
1246 if (mir == miranda_count) {
1247 miranda_list[miranda_count++] = interface_method;
1248 }
1249 }
1250 }
1251 }
1252 if (miranda_count != 0) {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001253 int oldMethodCount = klass->NumVirtualMethods();
1254 int newMethodCount = oldMethodCount + miranda_count;
1255 Method** newVirtualMethods = new Method*[newMethodCount];
1256 if (klass->virtual_methods_ != NULL) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001257 memcpy(newVirtualMethods,
1258 klass->virtual_methods_,
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001259 klass->NumVirtualMethods() * sizeof(Method*));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001260 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001261 klass->virtual_methods_ = newVirtualMethods;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001262 klass->num_virtual_methods_ = newMethodCount;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001263
1264 CHECK(klass->vtable_ != NULL);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001265 int oldVtableCount = klass->vtable_count_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001266 klass->vtable_count_ += miranda_count;
1267
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001268 for (int i = 0; i < miranda_count; i++) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001269 Method* meth = AllocMethod();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001270 memcpy(meth, miranda_list[i], sizeof(Method));
1271 meth->klass_ = klass;
1272 meth->access_flags_ |= kAccMiranda;
1273 meth->method_index_ = 0xFFFF & (oldVtableCount + i);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001274 klass->virtual_methods_[oldMethodCount+i] = meth;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001275 klass->vtable_[oldVtableCount + i] = meth;
1276 }
1277 }
1278 return true;
1279}
1280
1281void ClassLinker::LinkAbstractMethods(Class* klass) {
1282 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1283 Method* method = klass->GetVirtualMethod(i);
1284 if (method->IsAbstract()) {
1285 method->insns_ = reinterpret_cast<uint16_t*>(0xFFFFFFFF); // TODO: AbstractMethodError
1286 }
1287 }
1288}
1289
1290bool ClassLinker::LinkInstanceFields(Class* klass) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001291 int field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001292 if (klass->GetSuperClass() != NULL) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001293 field_offset = klass->GetSuperClass()->object_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001294 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -07001295 field_offset = OFFSETOF_MEMBER(DataObject, fields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001296 }
1297 // Move references to the front.
Carl Shapiro69759ea2011-07-21 18:13:35 -07001298 klass->num_reference_instance_fields_ = 0;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001299 size_t i = 0;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001300 for ( ; i < klass->NumInstanceFields(); i++) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001301 InstanceField* pField = klass->GetInstanceField(i);
1302 char c = pField->GetType();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001303 if (c != '[' && c != 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001304 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1305 InstanceField* refField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001306 char rc = refField->GetType();
1307 if (rc == '[' || rc == 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001308 klass->SetInstanceField(i, refField);
1309 klass->SetInstanceField(j, pField);
1310 pField = refField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001311 c = rc;
Carl Shapiro69759ea2011-07-21 18:13:35 -07001312 klass->num_reference_instance_fields_++;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001313 break;
1314 }
1315 }
1316 } else {
Carl Shapiro69759ea2011-07-21 18:13:35 -07001317 klass->num_reference_instance_fields_++;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001318 }
1319 if (c != '[' && c != 'L') {
1320 break;
1321 }
Brian Carlstroma0808032011-07-18 00:39:23 -07001322 pField->SetOffset(field_offset);
1323 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001324 }
1325
1326 // Now we want to pack all of the double-wide fields together. If
1327 // we're not aligned, though, we want to shuffle one 32-bit field
1328 // into place. If we can't find one, we'll have to pad it.
Brian Carlstroma0808032011-07-18 00:39:23 -07001329 if (i != klass->NumInstanceFields() && (field_offset & 0x04) != 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001330 InstanceField* pField = klass->GetInstanceField(i);
1331 char c = pField->GetType();
1332
1333 if (c != 'J' && c != 'D') {
1334 // The field that comes next is 32-bit, so just advance past it.
Brian Carlstrombe977852011-07-19 14:54:54 -07001335 DCHECK(c != '[');
1336 DCHECK(c != 'L');
Brian Carlstroma0808032011-07-18 00:39:23 -07001337 pField->SetOffset(field_offset);
1338 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001339 i++;
1340 } else {
1341 // Next field is 64-bit, so search for a 32-bit field we can
1342 // swap into it.
1343 bool found = false;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001344 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1345 InstanceField* singleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001346 char rc = singleField->GetType();
1347 if (rc != 'J' && rc != 'D') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001348 klass->SetInstanceField(i, singleField);
1349 klass->SetInstanceField(j, pField);
1350 pField = singleField;
Brian Carlstroma0808032011-07-18 00:39:23 -07001351 pField->SetOffset(field_offset);
1352 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001353 found = true;
1354 i++;
1355 break;
1356 }
1357 }
1358 if (!found) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001359 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001360 }
1361 }
1362 }
1363
1364 // Alignment is good, shuffle any double-wide fields forward, and
1365 // finish assigning field offsets to all fields.
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001366 DCHECK(i == klass->NumInstanceFields() || (field_offset & 0x04) == 0);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001367 for ( ; i < klass->NumInstanceFields(); i++) {
1368 InstanceField* pField = klass->GetInstanceField(i);
1369 char c = pField->GetType();
1370 if (c != 'D' && c != 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001371 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1372 InstanceField* doubleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001373 char rc = doubleField->GetType();
1374 if (rc == 'D' || rc == 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001375 klass->SetInstanceField(i, doubleField);
1376 klass->SetInstanceField(j, pField);
1377 pField = doubleField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001378 c = rc;
1379 break;
1380 }
1381 }
1382 } else {
1383 // This is a double-wide field, leave it be.
1384 }
1385
Brian Carlstroma0808032011-07-18 00:39:23 -07001386 pField->SetOffset(field_offset);
1387 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001388 if (c == 'J' || c == 'D')
Brian Carlstroma0808032011-07-18 00:39:23 -07001389 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001390 }
1391
1392#ifndef NDEBUG
Brian Carlstrombe977852011-07-19 14:54:54 -07001393 // Make sure that all reference fields appear before
1394 // non-reference fields, and all double-wide fields are aligned.
1395 bool seen_non_ref = false;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001396 for (i = 0; i < klass->NumInstanceFields(); i++) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001397 InstanceField *pField = klass->GetInstanceField(i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001398 char c = pField->GetType();
1399
1400 if (c == 'D' || c == 'J') {
Brian Carlstrombe977852011-07-19 14:54:54 -07001401 DCHECK_EQ(0U, pField->GetOffset() & 0x07);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001402 }
1403
1404 if (c != '[' && c != 'L') {
Brian Carlstrombe977852011-07-19 14:54:54 -07001405 if (!seen_non_ref) {
1406 seen_non_ref = true;
1407 DCHECK_EQ(klass->num_reference_ifields_, i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001408 }
Brian Carlstrombe977852011-07-19 14:54:54 -07001409 } else {
1410 DCHECK(!seen_non_ref);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001411 }
1412 }
Brian Carlstrombe977852011-07-19 14:54:54 -07001413 if (!seen_non_ref) {
1414 DCHECK(klass->NumInstanceFields(), klass->num_reference_ifields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001415 }
1416#endif
1417
Brian Carlstroma0808032011-07-18 00:39:23 -07001418 klass->object_size_ = field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001419 return true;
1420}
1421
1422// Set the bitmap of reference offsets, refOffsets, from the ifields
1423// list.
1424void ClassLinker::CreateReferenceOffsets(Class* klass) {
1425 uint32_t reference_offsets = 0;
1426 if (klass->HasSuperClass()) {
1427 reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
1428 }
1429 // If our superclass overflowed, we don't stand a chance.
1430 if (reference_offsets != CLASS_WALK_SUPER) {
1431 // All of the fields that contain object references are guaranteed
1432 // to be at the beginning of the ifields list.
1433 for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
1434 // Note that, per the comment on struct InstField, f->byteOffset
1435 // is the offset from the beginning of obj, not the offset into
1436 // obj->instanceData.
1437 const InstanceField* field = klass->GetInstanceField(i);
1438 size_t byte_offset = field->GetOffset();
1439 CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001440 CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001441 if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
1442 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001443 CHECK_NE(new_bit, 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001444 reference_offsets |= new_bit;
1445 } else {
1446 reference_offsets = CLASS_WALK_SUPER;
1447 break;
1448 }
1449 }
1450 klass->SetReferenceOffsets(reference_offsets);
1451 }
1452}
1453
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001454Class* ClassLinker::ResolveClass(const Class* referrer,
1455 uint32_t class_idx,
1456 const RawDexFile* raw_dex_file) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001457 DexFile* dex_file = referrer->GetDexFile();
1458 Class* resolved = dex_file->GetResolvedClass(class_idx);
1459 if (resolved != NULL) {
1460 return resolved;
1461 }
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001462 const char* descriptor = raw_dex_file->dexStringByTypeIdx(class_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001463 if (descriptor[0] != '\0' && descriptor[1] == '\0') {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001464 resolved = FindPrimitiveClass(descriptor[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001465 } else {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001466 resolved = FindClass(descriptor, referrer->GetClassLoader(), raw_dex_file);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001467 }
1468 if (resolved != NULL) {
1469 Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
1470 if (referrer->GetDexFile() != check->GetDexFile()) {
1471 if (check->GetClassLoader() != NULL) {
1472 LG << "Class resolved by unexpected DEX"; // TODO: IllegalAccessError
1473 return NULL;
1474 }
1475 }
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001476 dex_file->SetResolvedClass(class_idx, resolved);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001477 } else {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001478 DCHECK(Thread::Current()->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001479 }
1480 return resolved;
1481}
1482
1483Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
1484 /*MethodType*/ int method_type) {
1485 CHECK(false);
1486 return NULL;
1487}
1488
Carl Shapiro69759ea2011-07-21 18:13:35 -07001489String* ClassLinker::ResolveString(const Class* referring,
1490 uint32_t string_idx) {
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001491 const RawDexFile* raw = FindRawDexFile(referring->GetDexFile());
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001492 const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
1493 const char* string_data = raw->GetStringData(string_id);
Carl Shapiro69759ea2011-07-21 18:13:35 -07001494 String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_,
1495 char_array_class_,
1496 string_data);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001497 // TODO: intern the new string
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07001498 referring->GetDexFile()->SetResolvedString(string_idx, new_string);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001499 return new_string;
1500}
1501
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001502} // namespace art