blob: 6fac61071ca4918e05ebc78b94fb1cd8bcb5a23d [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
4#include "src/class_linker.h"
5
6#include <vector>
7#include <utility>
8
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07009#include "src/casts.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070010#include "src/dex_verifier.h"
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070011#include "src/heap.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070012#include "src/logging.h"
13#include "src/monitor.h"
14#include "src/object.h"
15#include "src/raw_dex_file.h"
16#include "src/scoped_ptr.h"
17#include "src/thread.h"
18#include "src/utils.h"
19
20namespace art {
21
Carl Shapiro61e019d2011-07-14 16:53:09 -070022ClassLinker* ClassLinker::Create() {
23 scoped_ptr<ClassLinker> class_linker(new ClassLinker);
24 class_linker->Init();
25 // TODO: check for failure during initialization
26 return class_linker.release();
27}
28
Carl Shapiro565f5072011-07-10 13:39:43 -070029void ClassLinker::Init() {
Brian Carlstroma0808032011-07-18 00:39:23 -070030 // Allocate and partially initialize the Class, Object, Field, Method classes.
Brian Carlstrom934486c2011-07-12 23:42:50 -070031 // Initialization will be completed when the definitions are loaded.
Carl Shapiro69759ea2011-07-21 18:13:35 -070032 java_lang_Class_ = down_cast<Class*>(Heap::AllocObject(NULL, sizeof(Class)));
Brian Carlstroma331b3c2011-07-18 17:47:56 -070033 CHECK(java_lang_Class_ != NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070034 java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
Brian Carlstroma0808032011-07-18 00:39:23 -070035 java_lang_Class_->object_size_ = sizeof(Class);
36 java_lang_Class_->klass_ = java_lang_Class_;
37
38 java_lang_Object_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070039 CHECK(java_lang_Object_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070040 java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
41
42 java_lang_Class_->super_class_ = java_lang_Object_;
43
44 java_lang_ref_Field_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070045 CHECK(java_lang_ref_Field_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070046 java_lang_ref_Field_->descriptor_ = "Ljava/lang/ref/Field;";
47
48 java_lang_ref_Method_ = AllocClass(NULL);
Brian Carlstroma331b3c2011-07-18 17:47:56 -070049 CHECK(java_lang_ref_Method_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070050 java_lang_ref_Method_->descriptor_ = "Ljava/lang/Method;";
Carl Shapiro565f5072011-07-10 13:39:43 -070051
Brian Carlstroma331b3c2011-07-18 17:47:56 -070052 java_lang_Cloneable_ = AllocClass(NULL);
53 CHECK(java_lang_Cloneable_ != NULL);
54 java_lang_Cloneable_->descriptor_ = "Ljava/lang/Cloneable;";
Brian Carlstroma0808032011-07-18 00:39:23 -070055
Brian Carlstroma331b3c2011-07-18 17:47:56 -070056 java_io_Serializable_ = AllocClass(NULL);
57 CHECK(java_io_Serializable_ != NULL);
58 java_io_Serializable_->descriptor_ = "Ljava/io/Serializable;";
59
60 java_lang_String_ = AllocClass(NULL);
61 CHECK(java_lang_String_ != NULL);
62 java_lang_String_->descriptor_ = "Ljava/lang/String;";
63
64 // Allocate and initialize the primitive type classes.
65 primitive_byte_ = CreatePrimitiveClass("B");
66 primitive_char_ = CreatePrimitiveClass("C");
67 primitive_double_ = CreatePrimitiveClass("D");
68 primitive_float_ = CreatePrimitiveClass("F");
69 primitive_int_ = CreatePrimitiveClass("I");
70 primitive_long_ = CreatePrimitiveClass("J");
71 primitive_short_ = CreatePrimitiveClass("S");
72 primitive_boolean_ = CreatePrimitiveClass("Z");
73 primitive_void_ = CreatePrimitiveClass("V");
74
75 char_array_class_ = FindSystemClass("[C");
76 CHECK(char_array_class_ != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -070077}
78
79Class* ClassLinker::AllocClass(DexFile* dex_file) {
80 Class* klass = reinterpret_cast<Class*>(Heap::AllocObject(java_lang_Class_));
81 klass->dex_file_ = dex_file;
82 return klass;
83}
84
85StaticField* ClassLinker::AllocStaticField() {
Carl Shapiro69759ea2011-07-21 18:13:35 -070086 return down_cast<StaticField*>(Heap::AllocObject(java_lang_ref_Field_,
87 sizeof(StaticField)));
Brian Carlstroma0808032011-07-18 00:39:23 -070088}
89
90InstanceField* ClassLinker::AllocInstanceField() {
Carl Shapiro69759ea2011-07-21 18:13:35 -070091 return down_cast<InstanceField*>(Heap::AllocObject(java_lang_ref_Field_,
92 sizeof(InstanceField)));
Brian Carlstroma0808032011-07-18 00:39:23 -070093}
94
95Method* ClassLinker::AllocMethod() {
Carl Shapiro69759ea2011-07-21 18:13:35 -070096 return down_cast<Method*>(Heap::AllocObject(java_lang_ref_Method_,
97 sizeof(Method)));
Carl Shapiro565f5072011-07-10 13:39:43 -070098}
99
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700100Class* ClassLinker::FindClass(const StringPiece& descriptor,
101 Object* class_loader) {
Carl Shapirob5573532011-07-12 18:22:59 -0700102 Thread* self = Thread::Current();
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700103 DCHECK(self != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700104 CHECK(!self->IsExceptionPending());
105 // Find the class in the loaded classes table.
106 Class* klass = LookupClass(descriptor, class_loader);
107 if (klass == NULL) {
108 // Class is not yet loaded.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700109 if (descriptor[0] == '[') {
110 return CreateArrayClass(descriptor, class_loader);
111 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700112 ClassPathEntry pair = FindInClassPath(descriptor);
113 if (pair.first == NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700114 LG << "Class " << descriptor << " not found"; // TODO: NoClassDefFoundError
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700115 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700116 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700117 DexFile* dex_file = pair.first;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700118 const RawDexFile::ClassDef* class_def = pair.second;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700119 // Load the class from the dex file.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700120 if (descriptor == "Ljava/lang/Object;") {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700121 klass = java_lang_Object_;
122 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700123 klass->object_size_ = sizeof(Object);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700124 char_array_class_->super_class_idx_ = class_def->class_idx_;
125 } else if (descriptor == "Ljava/lang/Class;") {
Carl Shapiro565f5072011-07-10 13:39:43 -0700126 klass = java_lang_Class_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700127 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700128 klass->object_size_ = sizeof(Class);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700129 } else if (descriptor == "Ljava/lang/ref/Field;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700130 klass = java_lang_ref_Field_;
131 klass->dex_file_ = dex_file;
132 klass->object_size_ = sizeof(Field);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700133 } else if (descriptor == "Ljava/lang/ref/Method;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700134 klass = java_lang_ref_Method_;
135 klass->dex_file_ = dex_file;
136 klass->object_size_ = sizeof(Method);
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700137 } else if (descriptor == "Ljava/lang/Cloneable;") {
138 klass = java_lang_Cloneable_;
139 klass->dex_file_ = dex_file;
140 } else if (descriptor == "Ljava/io/Serializable;") {
141 klass = java_io_Serializable_;
142 klass->dex_file_ = dex_file;
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700143 } else if (descriptor == "Ljava/lang/String;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700144 klass = java_lang_String_;
145 klass->dex_file_ = dex_file;
146 klass->object_size_ = sizeof(String);
Carl Shapiro565f5072011-07-10 13:39:43 -0700147 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -0700148 klass = AllocClass(dex_file);
Carl Shapiro565f5072011-07-10 13:39:43 -0700149 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700150 LoadClass(*class_def, klass);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700151 // Check for a pending exception during load
152 if (self->IsExceptionPending()) {
153 // TODO: free native allocations in klass
154 return NULL;
155 }
156 {
157 ObjectLock lock(klass);
Carl Shapirob5573532011-07-12 18:22:59 -0700158 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700159 // Add the newly loaded class to the loaded classes table.
160 bool success = InsertClass(klass);
161 if (!success) {
162 // We may fail to insert if we raced with another thread.
163 klass->clinit_thread_id_ = 0;
164 // TODO: free native allocations in klass
165 klass = LookupClass(descriptor, class_loader);
166 CHECK(klass != NULL);
167 } else {
168 // Link the class.
169 if (!LinkClass(klass)) {
170 // Linking failed.
171 // TODO: CHECK(self->IsExceptionPending());
172 lock.NotifyAll();
173 return NULL;
174 }
175 }
176 }
177 }
178 // Link the class if it has not already been linked.
179 if (!klass->IsLinked() && !klass->IsErroneous()) {
180 ObjectLock lock(klass);
181 // Check for circular dependencies between classes.
Carl Shapirob5573532011-07-12 18:22:59 -0700182 if (!klass->IsLinked() && klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700183 LG << "Recursive link"; // TODO: ClassCircularityError
184 return NULL;
185 }
186 // Wait for the pending initialization to complete.
187 while (!klass->IsLinked() && !klass->IsErroneous()) {
188 lock.Wait();
189 }
190 }
191 if (klass->IsErroneous()) {
192 LG << "EarlierClassFailure"; // TODO: EarlierClassFailure
193 return NULL;
194 }
195 // Return the loaded class. No exceptions should be pending.
196 CHECK(!self->IsExceptionPending());
197 return klass;
198}
199
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700200void ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700201 CHECK(klass != NULL);
202 CHECK(klass->dex_file_ != NULL);
203 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
204 const byte* class_data = raw->GetClassData(class_def);
205 RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
206
207 const char* descriptor = raw->GetClassDescriptor(class_def);
208 CHECK(descriptor != NULL);
209
210 klass->klass_ = java_lang_Class_;
211 klass->descriptor_.set(descriptor);
212 klass->descriptor_alloc_ = NULL;
213 klass->access_flags_ = class_def.access_flags_;
214 klass->class_loader_ = NULL; // TODO
215 klass->primitive_type_ = Class::kPrimNot;
216 klass->status_ = Class::kStatusIdx;
217
218 klass->super_class_ = NULL;
219 klass->super_class_idx_ = class_def.superclass_idx_;
220
Carl Shapiro69759ea2011-07-21 18:13:35 -0700221 klass->num_static_fields_ = header.static_fields_size_;
222 klass->num_instance_fields_ = header.instance_fields_size_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700223 klass->num_direct_methods_ = header.direct_methods_size_;
224 klass->num_virtual_methods_ = header.virtual_methods_size_;
225
226 klass->source_file_ = raw->dexGetSourceFile(class_def);
227
228 // Load class interfaces.
229 LoadInterfaces(class_def, klass);
230
231 // Load static fields.
Carl Shapiro69759ea2011-07-21 18:13:35 -0700232 if (klass->NumStaticFields() != 0) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700233 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700234 klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700235 uint32_t last_idx = 0;
Carl Shapiro69759ea2011-07-21 18:13:35 -0700236 for (size_t i = 0; i < klass->NumStaticFields(); ++i) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700237 RawDexFile::Field raw_field;
238 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700239 StaticField* sfield = AllocStaticField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700240 klass->sfields_[i] = sfield;
241 LoadField(klass, raw_field, sfield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700242 }
243 }
244
245 // Load instance fields.
246 if (klass->NumInstanceFields() != 0) {
247 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700248 klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700249 uint32_t last_idx = 0;
250 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
251 RawDexFile::Field raw_field;
252 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700253 InstanceField* ifield = AllocInstanceField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700254 klass->ifields_[i] = ifield;
255 LoadField(klass, raw_field, ifield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700256 }
257 }
258
259 // Load direct methods.
260 if (klass->NumDirectMethods() != 0) {
261 // TODO: append direct methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700262 klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700263 uint32_t last_idx = 0;
264 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
265 RawDexFile::Method raw_method;
266 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700267 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700268 klass->direct_methods_[i] = meth;
269 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700270 // TODO: register maps
271 }
272 }
273
274 // Load virtual methods.
275 if (klass->NumVirtualMethods() != 0) {
276 // TODO: append virtual methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700277 klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700278 uint32_t last_idx = 0;
279 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
280 RawDexFile::Method raw_method;
281 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700282 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700283 klass->virtual_methods_[i] = meth;
284 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700285 // TODO: register maps
286 }
287 }
Brian Carlstrom934486c2011-07-12 23:42:50 -0700288}
289
290void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
291 Class* klass) {
292 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
293 const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
294 if (list != NULL) {
295 klass->interface_count_ = list->Size();
296 // TODO: allocate the interfaces array on the object heap.
297 klass->interfaces_ = new Class*[list->Size()]();
298 for (size_t i = 0; i < list->Size(); ++i) {
299 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
300 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
301 }
302 }
303}
304
305void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
306 Field* dst) {
307 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
308 const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
309 dst->klass_ = klass;
310 dst->name_ = raw->dexStringById(field_id.name_idx_);
311 dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
312 dst->access_flags_ = src.access_flags_;
313}
314
315void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
316 Method* dst) {
317 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
318 const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
319 dst->klass_ = klass;
320 dst->name_.set(raw->dexStringById(method_id.name_idx_));
321 dst->proto_idx_ = method_id.proto_idx_;
322 dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
323 dst->access_flags_ = src.access_flags_;
324
325 // TODO: check for finalize method
326
327 const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
328 if (code_item != NULL) {
329 dst->num_registers_ = code_item->registers_size_;
330 dst->num_ins_ = code_item->ins_size_;
331 dst->num_outs_ = code_item->outs_size_;
332 dst->insns_ = code_item->insns_;
333 } else {
334 uint16_t num_args = dst->NumArgRegisters();
335 if (!dst->IsStatic()) {
336 ++num_args;
337 }
338 dst->num_registers_ = dst->num_ins_ + num_args;
339 // TODO: native methods
340 }
341}
342
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700343ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const StringPiece& descriptor) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700344 for (size_t i = 0; i != class_path_.size(); ++i) {
345 DexFile* dex_file = class_path_[i];
Brian Carlstroma0808032011-07-18 00:39:23 -0700346 const RawDexFile::ClassDef* class_def = dex_file->GetRaw()->FindClassDef(descriptor);
347 if (class_def != NULL) {
348 return ClassPathEntry(dex_file, class_def);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700349 }
350 }
Brian Carlstroma0808032011-07-18 00:39:23 -0700351 return ClassPathEntry(NULL, NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700352}
353
354void ClassLinker::AppendToClassPath(DexFile* dex_file) {
355 class_path_.push_back(dex_file);
356}
357
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700358Class* ClassLinker::CreatePrimitiveClass(const StringPiece& descriptor) {
Brian Carlstroma0808032011-07-18 00:39:23 -0700359 Class* klass = AllocClass(NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -0700360 CHECK(klass != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -0700361 klass->super_class_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700362 klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
363 klass->descriptor_ = descriptor;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700364 klass->descriptor_alloc_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700365 klass->status_ = Class::kStatusInitialized;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700366 bool success = InsertClass(klass);
367 CHECK(success);
Carl Shapiro565f5072011-07-10 13:39:43 -0700368 return klass;
369}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700370
Brian Carlstrombe977852011-07-19 14:54:54 -0700371// Create an array class (i.e. the class object for the array, not the
372// array itself). "descriptor" looks like "[C" or "[[[[B" or
373// "[Ljava/lang/String;".
374//
375// If "descriptor" refers to an array of primitives, look up the
376// primitive type's internally-generated class object.
377//
378// "loader" is the class loader of the class that's referring to us. It's
379// used to ensure that we're looking for the element type in the right
380// context. It does NOT become the class loader for the array class; that
381// always comes from the base element class.
382//
383// Returns NULL with an exception raised on failure.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700384Class* ClassLinker::CreateArrayClass(const StringPiece& descriptor, Object* class_loader)
385{
386 CHECK(descriptor[0] == '[');
387 DCHECK(java_lang_Class_ != NULL);
388 DCHECK(java_lang_Object_ != NULL);
389
Brian Carlstrombe977852011-07-19 14:54:54 -0700390 // Identify the underlying element class and the array dimension depth.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700391 Class* component_type_ = NULL;
392 int array_rank;
393 if (descriptor[1] == '[') {
Brian Carlstrombe977852011-07-19 14:54:54 -0700394 // array of arrays; keep descriptor and grab stuff from parent
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700395 Class* outer = FindClass(descriptor.substr(1), class_loader);
396 if (outer != NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700397 // want the base class, not "outer", in our component_type_
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700398 component_type_ = outer->component_type_;
399 array_rank = outer->array_rank_ + 1;
400 } else {
Brian Carlstrombe977852011-07-19 14:54:54 -0700401 DCHECK(component_type_ == NULL); // make sure we fail
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700402 }
403 } else {
404 array_rank = 1;
405 if (descriptor[1] == 'L') {
Brian Carlstrombe977852011-07-19 14:54:54 -0700406 // array of objects; strip off "[" and look up descriptor.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700407 const StringPiece subDescriptor = descriptor.substr(1);
408 LG << "searching for element class '" << subDescriptor << "'";
Brian Carlstrombe977852011-07-19 14:54:54 -0700409 component_type_ = FindClass(subDescriptor, class_loader); // TODO FindClassNoInit
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700410 } else {
Brian Carlstrombe977852011-07-19 14:54:54 -0700411 // array of a primitive type
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700412 component_type_ = FindPrimitiveClass(descriptor[1]);
413 }
414 }
415
416 if (component_type_ == NULL) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700417 // failed
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700418 DCHECK(Thread::Current()->IsExceptionPending());
419 return NULL;
420 }
421
Brian Carlstrombe977852011-07-19 14:54:54 -0700422 // See if the component type is already loaded. Array classes are
423 // always associated with the class loader of their underlying
424 // element type -- an array of Strings goes with the loader for
425 // java/lang/String -- so we need to look for it there. (The
426 // caller should have checked for the existence of the class
427 // before calling here, but they did so with *their* class loader,
428 // not the component type's loader.)
429 //
430 // If we find it, the caller adds "loader" to the class' initiating
431 // loader list, which should prevent us from going through this again.
432 //
433 // This call is unnecessary if "loader" and "component_type_->class_loader_"
434 // are the same, because our caller (FindClass) just did the
435 // lookup. (Even if we get this wrong we still have correct behavior,
436 // because we effectively do this lookup again when we add the new
437 // class to the hash table --- necessary because of possible races with
438 // other threads.)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700439 if (class_loader != component_type_->class_loader_) {
440 Class* new_class = LookupClass(descriptor, component_type_->class_loader_);
441 if (new_class != NULL) {
442 return new_class;
443 }
444 }
445
Brian Carlstrombe977852011-07-19 14:54:54 -0700446 // Fill out the fields in the Class.
447 //
448 // It is possible to execute some methods against arrays, because
449 // all arrays are subclasses of java_lang_Object_, so we need to set
450 // up a vtable. We can just point at the one in java_lang_Object_.
451 //
452 // Array classes are simple enough that we don't need to do a full
453 // link step.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700454 Class* new_class = AllocClass(NULL);
455 if (new_class == NULL) {
456 return NULL;
457 }
458 new_class->descriptor_alloc_ = new std::string(descriptor.data(),
459 descriptor.size());
460 new_class->descriptor_.set(new_class->descriptor_alloc_->data(),
461 new_class->descriptor_alloc_->size());
462 new_class->super_class_ = java_lang_Object_;
463 new_class->vtable_count_ = java_lang_Object_->vtable_count_;
464 new_class->vtable_ = java_lang_Object_->vtable_;
465 new_class->primitive_type_ = Class::kPrimNot;
466 new_class->component_type_ = component_type_;
467 new_class->class_loader_ = component_type_->class_loader_;
468 new_class->array_rank_ = array_rank;
469 new_class->status_ = Class::kStatusInitialized;
Brian Carlstrombe977852011-07-19 14:54:54 -0700470 // don't need to set new_class->object_size_
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700471
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700472
Brian Carlstrombe977852011-07-19 14:54:54 -0700473 // All arrays have java/lang/Cloneable and java/io/Serializable as
474 // interfaces. We need to set that up here, so that stuff like
475 // "instanceof" works right.
476 //
477 // Note: The GC could run during the call to FindSystemClassNoInit(),
478 // so we need to make sure the class object is GC-valid while we're in
479 // there. Do this by clearing the interface list so the GC will just
480 // think that the entries are null.
481 //
482 // TODO?
483 // We may want to create a single, global copy of "interfaces" and
484 // "iftable" somewhere near the start and just point to those (and
485 // remember not to free them for arrays).
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700486 new_class->interface_count_ = 2;
487 new_class->interfaces_ = new Class*[2];
488 memset(new_class->interfaces_, 0, sizeof(Class*) * 2);
489 new_class->interfaces_[0] = java_lang_Cloneable_;
490 new_class->interfaces_[1] = java_io_Serializable_;
Brian Carlstrombe977852011-07-19 14:54:54 -0700491
492 // We assume that Cloneable/Serializable don't have superinterfaces --
493 // normally we'd have to crawl up and explicitly list all of the
494 // supers as well. These interfaces don't have any methods, so we
495 // don't have to worry about the ifviPool either.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700496 new_class->iftable_count_ = 2;
497 new_class->iftable_ = new InterfaceEntry[2];
498 memset(new_class->iftable_, 0, sizeof(InterfaceEntry) * 2);
499 new_class->iftable_[0].SetClass(new_class->interfaces_[0]);
500 new_class->iftable_[1].SetClass(new_class->interfaces_[1]);
501
Brian Carlstrombe977852011-07-19 14:54:54 -0700502 // Inherit access flags from the component type. Arrays can't be
503 // used as a superclass or interface, so we want to add "final"
504 // and remove "interface".
505 //
506 // Don't inherit any non-standard flags (e.g., kAccFinal)
507 // from component_type_. We assume that the array class does not
508 // override finalize().
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700509 new_class->access_flags_ = ((new_class->component_type_->access_flags_ &
510 ~kAccInterface) | kAccFinal) & kAccJavaFlagsMask;
511
512 if (InsertClass(new_class)) {
513 return new_class;
514 }
Brian Carlstrombe977852011-07-19 14:54:54 -0700515 // Another thread must have loaded the class after we
516 // started but before we finished. Abandon what we've
517 // done.
518 //
519 // (Yes, this happens.)
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700520
Brian Carlstrombe977852011-07-19 14:54:54 -0700521 // Grab the winning class.
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700522 Class* other_class = LookupClass(descriptor, component_type_->class_loader_);
523 DCHECK(other_class != NULL);
524 return other_class;
525}
526
527Class* ClassLinker::FindPrimitiveClass(char type) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700528 switch (type) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700529 case 'B':
Carl Shapiro565f5072011-07-10 13:39:43 -0700530 CHECK(primitive_byte_ != NULL);
531 return primitive_byte_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700532 case 'C':
Carl Shapiro565f5072011-07-10 13:39:43 -0700533 CHECK(primitive_char_ != NULL);
534 return primitive_char_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700535 case 'D':
Carl Shapiro565f5072011-07-10 13:39:43 -0700536 CHECK(primitive_double_ != NULL);
537 return primitive_double_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700538 case 'F':
Carl Shapiro565f5072011-07-10 13:39:43 -0700539 CHECK(primitive_float_ != NULL);
540 return primitive_float_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700541 case 'I':
Carl Shapiro565f5072011-07-10 13:39:43 -0700542 CHECK(primitive_int_ != NULL);
543 return primitive_int_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700544 case 'J':
Carl Shapiro565f5072011-07-10 13:39:43 -0700545 CHECK(primitive_long_ != NULL);
546 return primitive_long_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700547 case 'S':
Carl Shapiro565f5072011-07-10 13:39:43 -0700548 CHECK(primitive_short_ != NULL);
549 return primitive_short_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700550 case 'Z':
Carl Shapiro565f5072011-07-10 13:39:43 -0700551 CHECK(primitive_boolean_ != NULL);
552 return primitive_boolean_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700553 case 'V':
Carl Shapiro565f5072011-07-10 13:39:43 -0700554 CHECK(primitive_void_ != NULL);
555 return primitive_void_;
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700556 case 'L':
557 case '[':
558 LOG(ERROR) << "Not a primitive type " << static_cast<int>(type);
Carl Shapiro565f5072011-07-10 13:39:43 -0700559 default:
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700560 LOG(ERROR) << "Unknown primitive type " << static_cast<int>(type);
Carl Shapiro565f5072011-07-10 13:39:43 -0700561 };
562 return NULL; // Not reachable.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700563}
564
565bool ClassLinker::InsertClass(Class* klass) {
566 // TODO: acquire classes_lock_
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700567 const StringPiece& key = klass->GetDescriptor();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700568 bool success = classes_.insert(std::make_pair(key, klass)).second;
569 // TODO: release classes_lock_
570 return success;
571}
572
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700573Class* ClassLinker::LookupClass(const StringPiece& descriptor, Object* class_loader) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700574 // TODO: acquire classes_lock_
575 Table::iterator it = classes_.find(descriptor);
576 // TODO: release classes_lock_
577 if (it == classes_.end()) {
578 return NULL;
579 } else {
580 return (*it).second;
581 }
582}
583
584bool ClassLinker::InitializeClass(Class* klass) {
585 CHECK(klass->GetStatus() == Class::kStatusResolved ||
586 klass->GetStatus() == Class::kStatusError);
587
Carl Shapirob5573532011-07-12 18:22:59 -0700588 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700589
590 {
591 ObjectLock lock(klass);
592
593 if (klass->GetStatus() < Class::kStatusVerified) {
594 if (klass->IsErroneous()) {
595 LG << "re-initializing failed class"; // TODO: throw
596 return false;
597 }
598
599 CHECK(klass->GetStatus() == Class::kStatusResolved);
600
601 klass->status_ = Class::kStatusVerifying;
602 if (!DexVerify::VerifyClass(klass)) {
603 LG << "Verification failed"; // TODO: ThrowVerifyError
604 Object* exception = self->GetException();
Carl Shapiro69759ea2011-07-21 18:13:35 -0700605 size_t field_offset = OFFSETOF_MEMBER(Class, verify_error_class_);
606 klass->SetFieldObject(field_offset, exception->GetClass());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700607 klass->SetStatus(Class::kStatusError);
608 return false;
609 }
610
611 klass->SetStatus(Class::kStatusVerified);
612 }
613
614 if (klass->status_ == Class::kStatusInitialized) {
615 return true;
616 }
617
618 while (klass->status_ == Class::kStatusInitializing) {
619 // we caught somebody else in the act; was it us?
Carl Shapirob5573532011-07-12 18:22:59 -0700620 if (klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700621 LG << "recursive <clinit>";
622 return true;
623 }
624
625 CHECK(!self->IsExceptionPending());
626
627 lock.Wait(); // TODO: check for interruption
628
629 // When we wake up, repeat the test for init-in-progress. If
630 // there's an exception pending (only possible if
631 // "interruptShouldThrow" was set), bail out.
632 if (self->IsExceptionPending()) {
633 CHECK(false);
634 LG << "Exception in initialization."; // TODO: ExceptionInInitializerError
635 klass->SetStatus(Class::kStatusError);
636 return false;
637 }
638 if (klass->GetStatus() == Class::kStatusInitializing) {
639 continue;
640 }
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700641 DCHECK(klass->GetStatus() == Class::kStatusInitialized ||
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700642 klass->GetStatus() == Class::kStatusError);
643 if (klass->IsErroneous()) {
Brian Carlstrombe977852011-07-19 14:54:54 -0700644 // The caller wants an exception, but it was thrown in a
645 // different thread. Synthesize one here.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700646 LG << "<clinit> failed"; // TODO: throw UnsatisfiedLinkError
647 return false;
648 }
649 return true; // otherwise, initialized
650 }
651
652 // see if we failed previously
653 if (klass->IsErroneous()) {
654 // might be wise to unlock before throwing; depends on which class
655 // it is that we have locked
656
657 // TODO: throwEarlierClassFailure(klass);
658 return false;
659 }
660
661 if (!ValidateSuperClassDescriptors(klass)) {
662 klass->SetStatus(Class::kStatusError);
663 return false;
664 }
665
Brian Carlstroma331b3c2011-07-18 17:47:56 -0700666 DCHECK(klass->status_ < Class::kStatusInitializing);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700667
Carl Shapirob5573532011-07-12 18:22:59 -0700668 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700669 klass->status_ = Class::kStatusInitializing;
670 }
671
672 if (!InitializeSuperClass(klass)) {
673 return false;
674 }
675
676 InitializeStaticFields(klass);
677
678 Method* clinit = klass->FindDirectMethodLocally("<clinit>", "()V");
679 if (clinit != NULL) {
680 } else {
681 // JValue unused;
682 // TODO: dvmCallMethod(self, method, NULL, &unused);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700683 //CHECK(!"unimplemented");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700684 }
685
686 {
687 ObjectLock lock(klass);
688
689 if (self->IsExceptionPending()) {
690 klass->SetStatus(Class::kStatusError);
691 } else {
692 klass->SetStatus(Class::kStatusInitialized);
693 }
694 lock.NotifyAll();
695 }
696
697 return true;
698}
699
700bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
701 if (klass->IsInterface()) {
702 return true;
703 }
704 // begin with the methods local to the superclass
705 if (klass->HasSuperClass() &&
706 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
707 const Class* super = klass->GetSuperClass();
708 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
709 const Method* method = klass->GetVirtualMethod(i);
710 if (method != super->GetVirtualMethod(i) &&
711 !HasSameMethodDescriptorClasses(method, super, klass)) {
712 LG << "Classes resolve differently in superclass";
713 return false;
714 }
715 }
716 }
717 for (size_t i = 0; i < klass->iftable_count_; ++i) {
718 const InterfaceEntry* iftable = &klass->iftable_[i];
719 Class* interface = iftable->GetClass();
720 if (klass->GetClassLoader() != interface->GetClassLoader()) {
721 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
722 uint32_t vtable_index = iftable->method_index_array_[j];
723 const Method* method = klass->GetVirtualMethod(vtable_index);
724 if (!HasSameMethodDescriptorClasses(method, interface,
725 method->GetClass())) {
726 LG << "Classes resolve differently in interface"; // TODO: LinkageError
727 return false;
728 }
729 }
730 }
731 }
732 return true;
733}
734
735bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700736 const Class* klass1,
737 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700738 const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
739 const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
740 RawDexFile::ParameterIterator *it;
741 for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
742 const char* descriptor = it->GetDescriptor();
743 if (descriptor == NULL) {
744 break;
745 }
746 if (descriptor[0] == 'L' || descriptor[0] == '[') {
747 // Found a non-primitive type.
748 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
749 return false;
750 }
751 }
752 }
753 // Check the return type
754 const char* descriptor = raw->GetReturnTypeDescriptor(proto_id);
755 if (descriptor[0] == 'L' || descriptor[0] == '[') {
756 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
757 return false;
758 }
759 }
760 return true;
761}
762
763// Returns true if classes referenced by the descriptor are the
764// same classes in klass1 as they are in klass2.
765bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700766 const Class* klass1,
767 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700768 CHECK(descriptor != NULL);
769 CHECK(klass1 != NULL);
770 CHECK(klass2 != NULL);
771#if 0
772 Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader());
773 // TODO: found1 == NULL
774 Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader());
775 // TODO: found2 == NULL
776 // TODO: lookup found1 in initiating loader list
777 if (found1 == NULL || found2 == NULL) {
Carl Shapirob5573532011-07-12 18:22:59 -0700778 Thread::Current()->ClearException();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700779 if (found1 == found2) {
780 return true;
781 } else {
782 return false;
783 }
784 }
785#endif
786 return true;
787}
788
789bool ClassLinker::InitializeSuperClass(Class* klass) {
790 CHECK(klass != NULL);
791 // TODO: assert klass lock is acquired
792 if (!klass->IsInterface() && klass->HasSuperClass()) {
793 Class* super_class = klass->GetSuperClass();
794 if (super_class->GetStatus() != Class::kStatusInitialized) {
795 CHECK(!super_class->IsInterface());
796 klass->MonitorExit();
797 bool super_initialized = InitializeClass(super_class);
798 klass->MonitorEnter();
799 // TODO: check for a pending exception
800 if (!super_initialized) {
801 klass->SetStatus(Class::kStatusError);
802 klass->NotifyAll();
803 return false;
804 }
805 }
806 }
807 return true;
808}
809
810void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700811 size_t num_static_fields = klass->NumStaticFields();
812 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700813 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700814 }
815 DexFile* dex_file = klass->GetDexFile();
816 if (dex_file == NULL) {
817 return;
818 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700819 const StringPiece& descriptor = klass->GetDescriptor();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700820 const RawDexFile* raw = dex_file->GetRaw();
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700821 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
822 CHECK(class_def != NULL);
823 const byte* addr = raw->GetEncodedArray(*class_def);
824 size_t array_size = DecodeUnsignedLeb128(&addr);
825 for (size_t i = 0; i < array_size; ++i) {
826 StaticField* field = klass->GetStaticField(i);
827 JValue value;
828 RawDexFile::ValueType type = raw->ReadEncodedValue(&addr, &value);
829 switch (type) {
830 case RawDexFile::kByte:
831 field->SetByte(value.b);
832 break;
833 case RawDexFile::kShort:
834 field->SetShort(value.s);
835 break;
836 case RawDexFile::kChar:
837 field->SetChar(value.c);
838 break;
839 case RawDexFile::kInt:
840 field->SetInt(value.i);
841 break;
842 case RawDexFile::kLong:
843 field->SetLong(value.j);
844 break;
845 case RawDexFile::kFloat:
846 field->SetFloat(value.f);
847 break;
848 case RawDexFile::kDouble:
849 field->SetDouble(value.d);
850 break;
851 case RawDexFile::kString: {
852 uint32_t string_idx = value.i;
853 String* resolved = ResolveString(klass, string_idx);
854 field->SetObject(resolved);
855 break;
856 }
857 case RawDexFile::kBoolean:
858 field->SetBoolean(value.z);
859 break;
860 case RawDexFile::kNull:
861 field->SetObject(value.l);
862 break;
863 default:
Carl Shapiro606258b2011-07-09 16:09:09 -0700864 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700865 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700866 }
867}
868
869bool ClassLinker::LinkClass(Class* klass) {
870 CHECK(klass->status_ == Class::kStatusIdx ||
871 klass->status_ == Class::kStatusLoaded);
872 if (klass->status_ == Class::kStatusIdx) {
873 if (!LinkInterfaces(klass)) {
874 return false;
875 }
876 }
877 if (!LinkSuperClass(klass)) {
878 return false;
879 }
880 if (!LinkMethods(klass)) {
881 return false;
882 }
883 if (!LinkInstanceFields(klass)) {
884 return false;
885 }
886 CreateReferenceOffsets(klass);
887 CHECK_EQ(klass->status_, Class::kStatusLoaded);
888 klass->status_ = Class::kStatusResolved;
889 return true;
890}
891
892bool ClassLinker::LinkInterfaces(Class* klass) {
893 scoped_array<uint32_t> interfaces_idx;
894 // TODO: store interfaces_idx in the Class object
895 // TODO: move this outside of link interfaces
896 if (klass->interface_count_ > 0) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700897 size_t length = klass->interface_count_ * sizeof(klass->interfaces_[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700898 interfaces_idx.reset(new uint32_t[klass->interface_count_]);
Carl Shapiro565f5072011-07-10 13:39:43 -0700899 memcpy(interfaces_idx.get(), klass->interfaces_, length);
900 memset(klass->interfaces_, 0xFF, length);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700901 }
902 // Mark the class as loaded.
903 klass->status_ = Class::kStatusLoaded;
904 if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
905 Class* super_class = ResolveClass(klass, klass->super_class_idx_);
906 if (super_class == NULL) {
907 LG << "Failed to resolve superclass";
908 return false;
909 }
910 klass->super_class_ = super_class; // TODO: write barrier
911 }
912 if (klass->interface_count_ > 0) {
913 for (size_t i = 0; i < klass->interface_count_; ++i) {
914 uint32_t idx = interfaces_idx[i];
915 klass->interfaces_[i] = ResolveClass(klass, idx);
916 if (klass->interfaces_[i] == NULL) {
917 LG << "Failed to resolve interface";
918 return false;
919 }
920 // Verify
921 if (!klass->CanAccess(klass->interfaces_[i])) {
922 LG << "Inaccessible interface";
923 return false;
924 }
925 }
926 }
927 return true;
928}
929
930bool ClassLinker::LinkSuperClass(Class* klass) {
931 CHECK(!klass->IsPrimitive());
932 const Class* super = klass->GetSuperClass();
933 if (klass->GetDescriptor() == "Ljava/lang/Object;") {
934 if (super != NULL) {
935 LG << "Superclass must not be defined"; // TODO: ClassFormatError
936 return false;
937 }
938 // TODO: clear finalize attribute
939 return true;
940 }
941 if (super == NULL) {
942 LG << "No superclass defined"; // TODO: LinkageError
943 return false;
944 }
945 // Verify
946 if (super->IsFinal()) {
947 LG << "Superclass is declared final"; // TODO: IncompatibleClassChangeError
948 return false;
949 }
950 if (super->IsInterface()) {
951 LG << "Superclass is an interface"; // TODO: IncompatibleClassChangeError
952 return false;
953 }
954 if (!klass->CanAccess(super)) {
955 LG << "Superclass is inaccessible"; // TODO: IllegalAccessError
956 return false;
957 }
958 return true;
959}
960
961// Populate the class vtable and itable.
962bool ClassLinker::LinkMethods(Class* klass) {
963 if (klass->IsInterface()) {
964 // No vtable.
965 size_t count = klass->NumVirtualMethods();
966 if (!IsUint(16, count)) {
967 LG << "Too many methods on interface"; // TODO: VirtualMachineError
968 return false;
969 }
Carl Shapiro565f5072011-07-10 13:39:43 -0700970 for (size_t i = 0; i < count; ++i) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700971 klass->GetVirtualMethod(i)->method_index_ = i;
972 }
973 } else {
974 // Link virtual method tables
975 LinkVirtualMethods(klass);
976
977 // Link interface method tables
978 LinkInterfaceMethods(klass);
979
980 // Insert stubs.
981 LinkAbstractMethods(klass);
982 }
983 return true;
984}
985
986bool ClassLinker::LinkVirtualMethods(Class* klass) {
987 uint32_t max_count = klass->NumVirtualMethods();
988 if (klass->GetSuperClass() != NULL) {
989 max_count += klass->GetSuperClass()->NumVirtualMethods();
990 } else {
991 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
992 }
993 // TODO: do not assign to the vtable field until it is fully constructed.
994 // TODO: make this a vector<Method*> instead?
995 klass->vtable_ = new Method*[max_count];
996 if (klass->HasSuperClass()) {
997 memcpy(klass->vtable_,
998 klass->GetSuperClass()->vtable_,
999 klass->GetSuperClass()->vtable_count_ * sizeof(Method*));
1000 size_t actual_count = klass->GetSuperClass()->vtable_count_;
1001 // See if any of our virtual methods override the superclass.
1002 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1003 Method* local_method = klass->GetVirtualMethod(i);
1004 size_t j = 0;
1005 for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
1006 const Method* super_method = klass->vtable_[j];
1007 if (local_method->HasSameNameAndPrototype(super_method)) {
1008 // Verify
1009 if (super_method->IsFinal()) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001010 LG << "Method overrides final method"; // TODO: VirtualMachineError
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001011 return false;
1012 }
1013 klass->vtable_[j] = local_method;
1014 local_method->method_index_ = j;
1015 break;
1016 }
1017 }
1018 if (j == klass->GetSuperClass()->vtable_count_) {
1019 // Not overriding, append.
1020 klass->vtable_[actual_count] = local_method;
1021 local_method->method_index_ = actual_count;
1022 actual_count += 1;
1023 }
1024 }
1025 if (!IsUint(16, actual_count)) {
1026 LG << "Too many methods defined on class"; // TODO: VirtualMachineError
1027 return false;
1028 }
1029 CHECK_LE(actual_count, max_count);
1030 if (actual_count < max_count) {
1031 Method** new_vtable = new Method*[actual_count];
1032 memcpy(new_vtable, klass->vtable_, actual_count * sizeof(Method*));
Carl Shapiro565f5072011-07-10 13:39:43 -07001033 delete[] klass->vtable_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001034 klass->vtable_ = new_vtable;
1035 LG << "shrunk vtable: "
1036 << "was " << max_count << ", "
1037 << "now " << actual_count;
1038 }
1039 klass->vtable_count_ = actual_count;
1040 } else {
1041 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
1042 if (!IsUint(16, klass->NumVirtualMethods())) {
1043 LG << "Too many methods"; // TODO: VirtualMachineError
1044 return false;
1045 }
1046 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1047 klass->vtable_[i] = klass->GetVirtualMethod(i);
1048 klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
1049 }
1050 klass->vtable_count_ = klass->NumVirtualMethods();
1051 }
1052 return true;
1053}
1054
1055bool ClassLinker::LinkInterfaceMethods(Class* klass) {
1056 int pool_offset = 0;
1057 int pool_size = 0;
1058 int miranda_count = 0;
1059 int miranda_alloc = 0;
1060 size_t super_ifcount;
1061 if (klass->HasSuperClass()) {
1062 super_ifcount = klass->GetSuperClass()->iftable_count_;
1063 } else {
1064 super_ifcount = 0;
1065 }
1066 size_t ifCount = super_ifcount;
1067 ifCount += klass->interface_count_;
1068 for (size_t i = 0; i < klass->interface_count_; i++) {
1069 ifCount += klass->interfaces_[i]->iftable_count_;
1070 }
1071 if (ifCount == 0) {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001072 DCHECK(klass->iftable_count_ == 0);
1073 DCHECK(klass->iftable_ == NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001074 return true;
1075 }
1076 klass->iftable_ = new InterfaceEntry[ifCount * sizeof(InterfaceEntry)];
1077 memset(klass->iftable_, 0x00, sizeof(InterfaceEntry) * ifCount);
1078 if (super_ifcount != 0) {
1079 memcpy(klass->iftable_, klass->GetSuperClass()->iftable_,
1080 sizeof(InterfaceEntry) * super_ifcount);
1081 }
1082 // Flatten the interface inheritance hierarchy.
1083 size_t idx = super_ifcount;
1084 for (size_t i = 0; i < klass->interface_count_; i++) {
1085 Class* interf = klass->interfaces_[i];
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001086 DCHECK(interf != NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001087 if (!interf->IsInterface()) {
1088 LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
1089 return false;
1090 }
1091 klass->iftable_[idx++].SetClass(interf);
1092 for (size_t j = 0; j < interf->iftable_count_; j++) {
1093 klass->iftable_[idx++].SetClass(interf->iftable_[j].GetClass());
1094 }
1095 }
1096 CHECK_EQ(idx, ifCount);
1097 klass->iftable_count_ = ifCount;
1098 if (klass->IsInterface() || super_ifcount == ifCount) {
1099 return true;
1100 }
1101 for (size_t i = super_ifcount; i < ifCount; i++) {
1102 pool_size += klass->iftable_[i].GetClass()->NumVirtualMethods();
1103 }
1104 if (pool_size == 0) {
1105 return true;
1106 }
1107 klass->ifvi_pool_count_ = pool_size;
1108 klass->ifvi_pool_ = new uint32_t[pool_size];
1109 std::vector<Method*> miranda_list;
1110 for (size_t i = super_ifcount; i < ifCount; ++i) {
1111 klass->iftable_[i].method_index_array_ = klass->ifvi_pool_ + pool_offset;
1112 Class* interface = klass->iftable_[i].GetClass();
1113 pool_offset += interface->NumVirtualMethods(); // end here
1114 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
1115 Method* interface_method = interface->GetVirtualMethod(j);
1116 int k; // must be signed
1117 for (k = klass->vtable_count_ - 1; k >= 0; --k) {
1118 if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) {
Carl Shapiro565f5072011-07-10 13:39:43 -07001119 if (!klass->vtable_[k]->IsPublic()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001120 LG << "Implementation not public";
1121 return false;
1122 }
1123 klass->iftable_[i].method_index_array_[j] = k;
1124 break;
1125 }
1126 }
1127 if (k < 0) {
1128 if (miranda_count == miranda_alloc) {
1129 miranda_alloc += 8;
1130 if (miranda_list.empty()) {
1131 miranda_list.resize(miranda_alloc);
1132 } else {
1133 miranda_list.resize(miranda_alloc);
1134 }
1135 }
1136 int mir;
1137 for (mir = 0; mir < miranda_count; mir++) {
1138 if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) {
1139 break;
1140 }
1141 }
1142 // point the interface table at a phantom slot index
1143 klass->iftable_[i].method_index_array_[j] = klass->vtable_count_ + mir;
1144 if (mir == miranda_count) {
1145 miranda_list[miranda_count++] = interface_method;
1146 }
1147 }
1148 }
1149 }
1150 if (miranda_count != 0) {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001151 int oldMethodCount = klass->NumVirtualMethods();
1152 int newMethodCount = oldMethodCount + miranda_count;
1153 Method** newVirtualMethods = new Method*[newMethodCount];
1154 if (klass->virtual_methods_ != NULL) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001155 memcpy(newVirtualMethods,
1156 klass->virtual_methods_,
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001157 klass->NumVirtualMethods() * sizeof(Method*));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001158 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001159 klass->virtual_methods_ = newVirtualMethods;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001160 klass->num_virtual_methods_ = newMethodCount;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001161
1162 CHECK(klass->vtable_ != NULL);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001163 int oldVtableCount = klass->vtable_count_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001164 klass->vtable_count_ += miranda_count;
1165
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001166 for (int i = 0; i < miranda_count; i++) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001167 Method* meth = AllocMethod();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001168 memcpy(meth, miranda_list[i], sizeof(Method));
1169 meth->klass_ = klass;
1170 meth->access_flags_ |= kAccMiranda;
1171 meth->method_index_ = 0xFFFF & (oldVtableCount + i);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001172 klass->virtual_methods_[oldMethodCount+i] = meth;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001173 klass->vtable_[oldVtableCount + i] = meth;
1174 }
1175 }
1176 return true;
1177}
1178
1179void ClassLinker::LinkAbstractMethods(Class* klass) {
1180 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1181 Method* method = klass->GetVirtualMethod(i);
1182 if (method->IsAbstract()) {
1183 method->insns_ = reinterpret_cast<uint16_t*>(0xFFFFFFFF); // TODO: AbstractMethodError
1184 }
1185 }
1186}
1187
1188bool ClassLinker::LinkInstanceFields(Class* klass) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001189 int field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001190 if (klass->GetSuperClass() != NULL) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001191 field_offset = klass->GetSuperClass()->object_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001192 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -07001193 field_offset = OFFSETOF_MEMBER(DataObject, fields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001194 }
1195 // Move references to the front.
Carl Shapiro69759ea2011-07-21 18:13:35 -07001196 klass->num_reference_instance_fields_ = 0;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001197 size_t i = 0;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001198 for ( ; i < klass->NumInstanceFields(); i++) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001199 InstanceField* pField = klass->GetInstanceField(i);
1200 char c = pField->GetType();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001201 if (c != '[' && c != 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001202 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1203 InstanceField* refField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001204 char rc = refField->GetType();
1205 if (rc == '[' || rc == 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001206 klass->SetInstanceField(i, refField);
1207 klass->SetInstanceField(j, pField);
1208 pField = refField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001209 c = rc;
Carl Shapiro69759ea2011-07-21 18:13:35 -07001210 klass->num_reference_instance_fields_++;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001211 break;
1212 }
1213 }
1214 } else {
Carl Shapiro69759ea2011-07-21 18:13:35 -07001215 klass->num_reference_instance_fields_++;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001216 }
1217 if (c != '[' && c != 'L') {
1218 break;
1219 }
Brian Carlstroma0808032011-07-18 00:39:23 -07001220 pField->SetOffset(field_offset);
1221 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001222 }
1223
1224 // Now we want to pack all of the double-wide fields together. If
1225 // we're not aligned, though, we want to shuffle one 32-bit field
1226 // into place. If we can't find one, we'll have to pad it.
Brian Carlstroma0808032011-07-18 00:39:23 -07001227 if (i != klass->NumInstanceFields() && (field_offset & 0x04) != 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001228 InstanceField* pField = klass->GetInstanceField(i);
1229 char c = pField->GetType();
1230
1231 if (c != 'J' && c != 'D') {
1232 // The field that comes next is 32-bit, so just advance past it.
Brian Carlstrombe977852011-07-19 14:54:54 -07001233 DCHECK(c != '[');
1234 DCHECK(c != 'L');
Brian Carlstroma0808032011-07-18 00:39:23 -07001235 pField->SetOffset(field_offset);
1236 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001237 i++;
1238 } else {
1239 // Next field is 64-bit, so search for a 32-bit field we can
1240 // swap into it.
1241 bool found = false;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001242 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1243 InstanceField* singleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001244 char rc = singleField->GetType();
1245 if (rc != 'J' && rc != 'D') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001246 klass->SetInstanceField(i, singleField);
1247 klass->SetInstanceField(j, pField);
1248 pField = singleField;
Brian Carlstroma0808032011-07-18 00:39:23 -07001249 pField->SetOffset(field_offset);
1250 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001251 found = true;
1252 i++;
1253 break;
1254 }
1255 }
1256 if (!found) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001257 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001258 }
1259 }
1260 }
1261
1262 // Alignment is good, shuffle any double-wide fields forward, and
1263 // finish assigning field offsets to all fields.
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001264 DCHECK(i == klass->NumInstanceFields() || (field_offset & 0x04) == 0);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001265 for ( ; i < klass->NumInstanceFields(); i++) {
1266 InstanceField* pField = klass->GetInstanceField(i);
1267 char c = pField->GetType();
1268 if (c != 'D' && c != 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001269 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1270 InstanceField* doubleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001271 char rc = doubleField->GetType();
1272 if (rc == 'D' || rc == 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001273 klass->SetInstanceField(i, doubleField);
1274 klass->SetInstanceField(j, pField);
1275 pField = doubleField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001276 c = rc;
1277 break;
1278 }
1279 }
1280 } else {
1281 // This is a double-wide field, leave it be.
1282 }
1283
Brian Carlstroma0808032011-07-18 00:39:23 -07001284 pField->SetOffset(field_offset);
1285 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001286 if (c == 'J' || c == 'D')
Brian Carlstroma0808032011-07-18 00:39:23 -07001287 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001288 }
1289
1290#ifndef NDEBUG
Brian Carlstrombe977852011-07-19 14:54:54 -07001291 // Make sure that all reference fields appear before
1292 // non-reference fields, and all double-wide fields are aligned.
1293 bool seen_non_ref = false;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001294 for (i = 0; i < klass->NumInstanceFields(); i++) {
Brian Carlstrombe977852011-07-19 14:54:54 -07001295 InstanceField *pField = klass->GetInstanceField(i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001296 char c = pField->GetType();
1297
1298 if (c == 'D' || c == 'J') {
Brian Carlstrombe977852011-07-19 14:54:54 -07001299 DCHECK_EQ(0U, pField->GetOffset() & 0x07);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001300 }
1301
1302 if (c != '[' && c != 'L') {
Brian Carlstrombe977852011-07-19 14:54:54 -07001303 if (!seen_non_ref) {
1304 seen_non_ref = true;
1305 DCHECK_EQ(klass->num_reference_ifields_, i);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001306 }
Brian Carlstrombe977852011-07-19 14:54:54 -07001307 } else {
1308 DCHECK(!seen_non_ref);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001309 }
1310 }
Brian Carlstrombe977852011-07-19 14:54:54 -07001311 if (!seen_non_ref) {
1312 DCHECK(klass->NumInstanceFields(), klass->num_reference_ifields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001313 }
1314#endif
1315
Brian Carlstroma0808032011-07-18 00:39:23 -07001316 klass->object_size_ = field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001317 return true;
1318}
1319
1320// Set the bitmap of reference offsets, refOffsets, from the ifields
1321// list.
1322void ClassLinker::CreateReferenceOffsets(Class* klass) {
1323 uint32_t reference_offsets = 0;
1324 if (klass->HasSuperClass()) {
1325 reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
1326 }
1327 // If our superclass overflowed, we don't stand a chance.
1328 if (reference_offsets != CLASS_WALK_SUPER) {
1329 // All of the fields that contain object references are guaranteed
1330 // to be at the beginning of the ifields list.
1331 for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
1332 // Note that, per the comment on struct InstField, f->byteOffset
1333 // is the offset from the beginning of obj, not the offset into
1334 // obj->instanceData.
1335 const InstanceField* field = klass->GetInstanceField(i);
1336 size_t byte_offset = field->GetOffset();
1337 CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001338 CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001339 if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
1340 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001341 CHECK_NE(new_bit, 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001342 reference_offsets |= new_bit;
1343 } else {
1344 reference_offsets = CLASS_WALK_SUPER;
1345 break;
1346 }
1347 }
1348 klass->SetReferenceOffsets(reference_offsets);
1349 }
1350}
1351
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001352Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001353 DexFile* dex_file = referrer->GetDexFile();
1354 Class* resolved = dex_file->GetResolvedClass(class_idx);
1355 if (resolved != NULL) {
1356 return resolved;
1357 }
1358 const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx);
1359 if (descriptor[0] != '\0' && descriptor[1] == '\0') {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001360 resolved = FindPrimitiveClass(descriptor[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001361 } else {
Brian Carlstrom6cc18452011-07-18 15:10:33 -07001362 resolved = FindClass(descriptor, referrer->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001363 }
1364 if (resolved != NULL) {
1365 Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
1366 if (referrer->GetDexFile() != check->GetDexFile()) {
1367 if (check->GetClassLoader() != NULL) {
1368 LG << "Class resolved by unexpected DEX"; // TODO: IllegalAccessError
1369 return NULL;
1370 }
1371 }
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001372 dex_file->SetResolvedClass(resolved, class_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001373 } else {
Brian Carlstroma331b3c2011-07-18 17:47:56 -07001374 DCHECK(Thread::Current()->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001375 }
1376 return resolved;
1377}
1378
1379Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
1380 /*MethodType*/ int method_type) {
1381 CHECK(false);
1382 return NULL;
1383}
1384
Carl Shapiro69759ea2011-07-21 18:13:35 -07001385String* ClassLinker::ResolveString(const Class* referring,
1386 uint32_t string_idx) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001387 const RawDexFile* raw = referring->GetDexFile()->GetRaw();
1388 const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
1389 const char* string_data = raw->GetStringData(string_id);
Carl Shapiro69759ea2011-07-21 18:13:35 -07001390 String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_,
1391 char_array_class_,
1392 string_data);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001393 // TODO: intern the new string
1394 referring->GetDexFile()->SetResolvedString(new_string, string_idx);
1395 return new_string;
1396}
1397
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001398} // namespace art