blob: 15c2e407e14e563477eb0f9df7d8b437cd8d54d7 [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 Carlstrom934486c2011-07-12 23:42:50 -070030 // Allocate and partially initialize the Object and Class classes.
31 // Initialization will be completed when the definitions are loaded.
32 java_lang_Object_ = Heap::AllocClass(NULL);
33 java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
34 java_lang_Class_ = Heap::AllocClass(NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -070035 java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
36
37 // Allocate and initialize the primitive type classes.
38 primitive_byte_ = CreatePrimitiveClass(kTypeByte, "B");
39 primitive_char_ = CreatePrimitiveClass(kTypeChar, "C");
40 primitive_double_ = CreatePrimitiveClass(kTypeDouble, "D");
41 primitive_float_ = CreatePrimitiveClass(kTypeFloat, "F");
42 primitive_int_ = CreatePrimitiveClass(kTypeInt, "I");
43 primitive_long_ = CreatePrimitiveClass(kTypeLong, "J");
44 primitive_short_ = CreatePrimitiveClass(kTypeShort, "S");
45 primitive_boolean_ = CreatePrimitiveClass(kTypeBoolean, "Z");
46 primitive_void_ = CreatePrimitiveClass(kTypeVoid, "V");
47}
48
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070049Class* ClassLinker::FindClass(const char* descriptor,
50 Object* class_loader,
51 DexFile* dex_file) {
Carl Shapirob5573532011-07-12 18:22:59 -070052 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070053 CHECK(!self->IsExceptionPending());
54 // Find the class in the loaded classes table.
55 Class* klass = LookupClass(descriptor, class_loader);
56 if (klass == NULL) {
57 // Class is not yet loaded.
58 if (dex_file == NULL) {
59 // No .dex file specified, search the class path.
60 dex_file = FindInClassPath(descriptor);
61 if (dex_file == NULL) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070062 LG << "Class " << descriptor << " really not found";
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070063 return NULL;
64 }
65 }
66 // Load the class from the dex file.
Brian Carlstrom934486c2011-07-12 23:42:50 -070067 if (!strcmp(descriptor, "Ljava/lang/Object;")) {
68 klass = java_lang_Object_;
69 klass->dex_file_ = dex_file;
70 } else if (!strcmp(descriptor, "Ljava/lang/Class;")) {
Carl Shapiro565f5072011-07-10 13:39:43 -070071 klass = java_lang_Class_;
Brian Carlstrom934486c2011-07-12 23:42:50 -070072 klass->dex_file_ = dex_file;
Carl Shapiro565f5072011-07-10 13:39:43 -070073 } else {
Brian Carlstrom934486c2011-07-12 23:42:50 -070074 klass = Heap::AllocClass(dex_file);
Carl Shapiro565f5072011-07-10 13:39:43 -070075 }
Brian Carlstrom934486c2011-07-12 23:42:50 -070076 bool is_loaded = LoadClass(descriptor, klass);
Carl Shapiro565f5072011-07-10 13:39:43 -070077 if (!is_loaded) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070078 // TODO: this occurs only when a dex file is provided.
79 LG << "Class not found"; // TODO: NoClassDefFoundError
80 return NULL;
81 }
82 // Check for a pending exception during load
83 if (self->IsExceptionPending()) {
84 // TODO: free native allocations in klass
85 return NULL;
86 }
87 {
88 ObjectLock lock(klass);
Carl Shapirob5573532011-07-12 18:22:59 -070089 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070090 // Add the newly loaded class to the loaded classes table.
91 bool success = InsertClass(klass);
92 if (!success) {
93 // We may fail to insert if we raced with another thread.
94 klass->clinit_thread_id_ = 0;
95 // TODO: free native allocations in klass
96 klass = LookupClass(descriptor, class_loader);
97 CHECK(klass != NULL);
98 } else {
99 // Link the class.
100 if (!LinkClass(klass)) {
101 // Linking failed.
102 // TODO: CHECK(self->IsExceptionPending());
103 lock.NotifyAll();
104 return NULL;
105 }
106 }
107 }
108 }
109 // Link the class if it has not already been linked.
110 if (!klass->IsLinked() && !klass->IsErroneous()) {
111 ObjectLock lock(klass);
112 // Check for circular dependencies between classes.
Carl Shapirob5573532011-07-12 18:22:59 -0700113 if (!klass->IsLinked() && klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700114 LG << "Recursive link"; // TODO: ClassCircularityError
115 return NULL;
116 }
117 // Wait for the pending initialization to complete.
118 while (!klass->IsLinked() && !klass->IsErroneous()) {
119 lock.Wait();
120 }
121 }
122 if (klass->IsErroneous()) {
123 LG << "EarlierClassFailure"; // TODO: EarlierClassFailure
124 return NULL;
125 }
126 // Return the loaded class. No exceptions should be pending.
127 CHECK(!self->IsExceptionPending());
128 return klass;
129}
130
Brian Carlstrom934486c2011-07-12 23:42:50 -0700131bool ClassLinker::LoadClass(const char* descriptor, Class* klass) {
132 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
133 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
134 if (class_def == NULL) {
135 return false;
136 } else {
137 return LoadClass(*class_def, klass);
138 }
139}
140
141bool ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
142 CHECK(klass != NULL);
143 CHECK(klass->dex_file_ != NULL);
144 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
145 const byte* class_data = raw->GetClassData(class_def);
146 RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
147
148 const char* descriptor = raw->GetClassDescriptor(class_def);
149 CHECK(descriptor != NULL);
150
151 klass->klass_ = java_lang_Class_;
152 klass->descriptor_.set(descriptor);
153 klass->descriptor_alloc_ = NULL;
154 klass->access_flags_ = class_def.access_flags_;
155 klass->class_loader_ = NULL; // TODO
156 klass->primitive_type_ = Class::kPrimNot;
157 klass->status_ = Class::kStatusIdx;
158
159 klass->super_class_ = NULL;
160 klass->super_class_idx_ = class_def.superclass_idx_;
161
162 klass->num_sfields_ = header.static_fields_size_;
163 klass->num_ifields_ = header.instance_fields_size_;
164 klass->num_direct_methods_ = header.direct_methods_size_;
165 klass->num_virtual_methods_ = header.virtual_methods_size_;
166
167 klass->source_file_ = raw->dexGetSourceFile(class_def);
168
169 // Load class interfaces.
170 LoadInterfaces(class_def, klass);
171
172 // Load static fields.
173 if (klass->num_sfields_ != 0) {
174 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700175 klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700176 uint32_t last_idx = 0;
177 for (size_t i = 0; i < klass->num_sfields_; ++i) {
178 RawDexFile::Field raw_field;
179 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700180 StaticField* sfield = Heap::AllocStaticField();
181 klass->sfields_[i] = sfield;
182 LoadField(klass, raw_field, sfield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700183 }
184 }
185
186 // Load instance fields.
187 if (klass->NumInstanceFields() != 0) {
188 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700189 klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700190 uint32_t last_idx = 0;
191 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
192 RawDexFile::Field raw_field;
193 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700194 InstanceField* ifield = Heap::AllocInstanceField();
195 klass->ifields_[i] = ifield;
196 LoadField(klass, raw_field, ifield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700197 }
198 }
199
200 // Load direct methods.
201 if (klass->NumDirectMethods() != 0) {
202 // TODO: append direct methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700203 klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700204 uint32_t last_idx = 0;
205 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
206 RawDexFile::Method raw_method;
207 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700208 Method* meth = Heap::AllocMethod();
209 klass->direct_methods_[i] = meth;
210 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700211 // TODO: register maps
212 }
213 }
214
215 // Load virtual methods.
216 if (klass->NumVirtualMethods() != 0) {
217 // TODO: append virtual methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700218 klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700219 uint32_t last_idx = 0;
220 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
221 RawDexFile::Method raw_method;
222 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700223 Method* meth = Heap::AllocMethod();
224 klass->virtual_methods_[i] = meth;
225 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700226 // TODO: register maps
227 }
228 }
229
230 return klass;
231}
232
233void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
234 Class* klass) {
235 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
236 const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
237 if (list != NULL) {
238 klass->interface_count_ = list->Size();
239 // TODO: allocate the interfaces array on the object heap.
240 klass->interfaces_ = new Class*[list->Size()]();
241 for (size_t i = 0; i < list->Size(); ++i) {
242 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
243 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
244 }
245 }
246}
247
248void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
249 Field* dst) {
250 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
251 const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
252 dst->klass_ = klass;
253 dst->name_ = raw->dexStringById(field_id.name_idx_);
254 dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
255 dst->access_flags_ = src.access_flags_;
256}
257
258void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
259 Method* dst) {
260 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
261 const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
262 dst->klass_ = klass;
263 dst->name_.set(raw->dexStringById(method_id.name_idx_));
264 dst->proto_idx_ = method_id.proto_idx_;
265 dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
266 dst->access_flags_ = src.access_flags_;
267
268 // TODO: check for finalize method
269
270 const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
271 if (code_item != NULL) {
272 dst->num_registers_ = code_item->registers_size_;
273 dst->num_ins_ = code_item->ins_size_;
274 dst->num_outs_ = code_item->outs_size_;
275 dst->insns_ = code_item->insns_;
276 } else {
277 uint16_t num_args = dst->NumArgRegisters();
278 if (!dst->IsStatic()) {
279 ++num_args;
280 }
281 dst->num_registers_ = dst->num_ins_ + num_args;
282 // TODO: native methods
283 }
284}
285
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700286DexFile* ClassLinker::FindInClassPath(const char* descriptor) {
287 for (size_t i = 0; i != class_path_.size(); ++i) {
288 DexFile* dex_file = class_path_[i];
289 if (dex_file->HasClass(descriptor)) {
290 return dex_file;
291 }
292 }
293 return NULL;
294}
295
296void ClassLinker::AppendToClassPath(DexFile* dex_file) {
297 class_path_.push_back(dex_file);
298}
299
Carl Shapiro565f5072011-07-10 13:39:43 -0700300Class* ClassLinker::CreatePrimitiveClass(JType type, const char* descriptor) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700301 Class* klass = Heap::AllocClass(NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -0700302 CHECK(klass != NULL);
303 klass->super_class_ = java_lang_Class_;
304 klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
305 klass->descriptor_ = descriptor;
306 klass->status_ = Class::kStatusInitialized;
307 return klass;
308}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700309
Carl Shapiro565f5072011-07-10 13:39:43 -0700310Class* ClassLinker::FindPrimitiveClass(JType type) {
311 switch (type) {
312 case kTypeByte:
313 CHECK(primitive_byte_ != NULL);
314 return primitive_byte_;
315 case kTypeChar:
316 CHECK(primitive_char_ != NULL);
317 return primitive_char_;
318 case kTypeDouble:
319 CHECK(primitive_double_ != NULL);
320 return primitive_double_;
321 case kTypeFloat:
322 CHECK(primitive_float_ != NULL);
323 return primitive_float_;
324 case kTypeInt:
325 CHECK(primitive_int_ != NULL);
326 return primitive_int_;
327 case kTypeLong:
328 CHECK(primitive_long_ != NULL);
329 return primitive_long_;
330 case kTypeShort:
331 CHECK(primitive_short_ != NULL);
332 return primitive_short_;
333 case kTypeBoolean:
334 CHECK(primitive_boolean_ != NULL);
335 return primitive_boolean_;
336 case kTypeVoid:
337 CHECK(primitive_void_ != NULL);
338 return primitive_void_;
339 default:
340 LOG(FATAL) << "Unknown primitive type " << static_cast<int>(type);
341 };
342 return NULL; // Not reachable.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700343}
344
345bool ClassLinker::InsertClass(Class* klass) {
346 // TODO: acquire classes_lock_
347 const char* key = klass->GetDescriptor().data();
348 bool success = classes_.insert(std::make_pair(key, klass)).second;
349 // TODO: release classes_lock_
350 return success;
351}
352
353Class* ClassLinker::LookupClass(const char* descriptor, Object* class_loader) {
354 // TODO: acquire classes_lock_
355 Table::iterator it = classes_.find(descriptor);
356 // TODO: release classes_lock_
357 if (it == classes_.end()) {
358 return NULL;
359 } else {
360 return (*it).second;
361 }
362}
363
364bool ClassLinker::InitializeClass(Class* klass) {
365 CHECK(klass->GetStatus() == Class::kStatusResolved ||
366 klass->GetStatus() == Class::kStatusError);
367
Carl Shapirob5573532011-07-12 18:22:59 -0700368 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700369
370 {
371 ObjectLock lock(klass);
372
373 if (klass->GetStatus() < Class::kStatusVerified) {
374 if (klass->IsErroneous()) {
375 LG << "re-initializing failed class"; // TODO: throw
376 return false;
377 }
378
379 CHECK(klass->GetStatus() == Class::kStatusResolved);
380
381 klass->status_ = Class::kStatusVerifying;
382 if (!DexVerify::VerifyClass(klass)) {
383 LG << "Verification failed"; // TODO: ThrowVerifyError
384 Object* exception = self->GetException();
385 klass->SetObjectAt(OFFSETOF_MEMBER(Class, verify_error_class_),
386 exception->GetClass());
387 klass->SetStatus(Class::kStatusError);
388 return false;
389 }
390
391 klass->SetStatus(Class::kStatusVerified);
392 }
393
394 if (klass->status_ == Class::kStatusInitialized) {
395 return true;
396 }
397
398 while (klass->status_ == Class::kStatusInitializing) {
399 // we caught somebody else in the act; was it us?
Carl Shapirob5573532011-07-12 18:22:59 -0700400 if (klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700401 LG << "recursive <clinit>";
402 return true;
403 }
404
405 CHECK(!self->IsExceptionPending());
406
407 lock.Wait(); // TODO: check for interruption
408
409 // When we wake up, repeat the test for init-in-progress. If
410 // there's an exception pending (only possible if
411 // "interruptShouldThrow" was set), bail out.
412 if (self->IsExceptionPending()) {
413 CHECK(false);
414 LG << "Exception in initialization."; // TODO: ExceptionInInitializerError
415 klass->SetStatus(Class::kStatusError);
416 return false;
417 }
418 if (klass->GetStatus() == Class::kStatusInitializing) {
419 continue;
420 }
421 assert(klass->GetStatus() == Class::kStatusInitialized ||
422 klass->GetStatus() == Class::kStatusError);
423 if (klass->IsErroneous()) {
424 /*
425 * The caller wants an exception, but it was thrown in a
426 * different thread. Synthesize one here.
427 */
428 LG << "<clinit> failed"; // TODO: throw UnsatisfiedLinkError
429 return false;
430 }
431 return true; // otherwise, initialized
432 }
433
434 // see if we failed previously
435 if (klass->IsErroneous()) {
436 // might be wise to unlock before throwing; depends on which class
437 // it is that we have locked
438
439 // TODO: throwEarlierClassFailure(klass);
440 return false;
441 }
442
443 if (!ValidateSuperClassDescriptors(klass)) {
444 klass->SetStatus(Class::kStatusError);
445 return false;
446 }
447
448 assert(klass->status < CLASS_INITIALIZING);
449
Carl Shapirob5573532011-07-12 18:22:59 -0700450 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700451 klass->status_ = Class::kStatusInitializing;
452 }
453
454 if (!InitializeSuperClass(klass)) {
455 return false;
456 }
457
458 InitializeStaticFields(klass);
459
460 Method* clinit = klass->FindDirectMethodLocally("<clinit>", "()V");
461 if (clinit != NULL) {
462 } else {
463 // JValue unused;
464 // TODO: dvmCallMethod(self, method, NULL, &unused);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700465 //CHECK(!"unimplemented");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700466 }
467
468 {
469 ObjectLock lock(klass);
470
471 if (self->IsExceptionPending()) {
472 klass->SetStatus(Class::kStatusError);
473 } else {
474 klass->SetStatus(Class::kStatusInitialized);
475 }
476 lock.NotifyAll();
477 }
478
479 return true;
480}
481
482bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
483 if (klass->IsInterface()) {
484 return true;
485 }
486 // begin with the methods local to the superclass
487 if (klass->HasSuperClass() &&
488 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
489 const Class* super = klass->GetSuperClass();
490 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
491 const Method* method = klass->GetVirtualMethod(i);
492 if (method != super->GetVirtualMethod(i) &&
493 !HasSameMethodDescriptorClasses(method, super, klass)) {
494 LG << "Classes resolve differently in superclass";
495 return false;
496 }
497 }
498 }
499 for (size_t i = 0; i < klass->iftable_count_; ++i) {
500 const InterfaceEntry* iftable = &klass->iftable_[i];
501 Class* interface = iftable->GetClass();
502 if (klass->GetClassLoader() != interface->GetClassLoader()) {
503 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
504 uint32_t vtable_index = iftable->method_index_array_[j];
505 const Method* method = klass->GetVirtualMethod(vtable_index);
506 if (!HasSameMethodDescriptorClasses(method, interface,
507 method->GetClass())) {
508 LG << "Classes resolve differently in interface"; // TODO: LinkageError
509 return false;
510 }
511 }
512 }
513 }
514 return true;
515}
516
517bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700518 const Class* klass1,
519 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700520 const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
521 const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
522 RawDexFile::ParameterIterator *it;
523 for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
524 const char* descriptor = it->GetDescriptor();
525 if (descriptor == NULL) {
526 break;
527 }
528 if (descriptor[0] == 'L' || descriptor[0] == '[') {
529 // Found a non-primitive type.
530 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
531 return false;
532 }
533 }
534 }
535 // Check the return type
536 const char* descriptor = raw->GetReturnTypeDescriptor(proto_id);
537 if (descriptor[0] == 'L' || descriptor[0] == '[') {
538 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
539 return false;
540 }
541 }
542 return true;
543}
544
545// Returns true if classes referenced by the descriptor are the
546// same classes in klass1 as they are in klass2.
547bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700548 const Class* klass1,
549 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700550 CHECK(descriptor != NULL);
551 CHECK(klass1 != NULL);
552 CHECK(klass2 != NULL);
553#if 0
554 Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader());
555 // TODO: found1 == NULL
556 Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader());
557 // TODO: found2 == NULL
558 // TODO: lookup found1 in initiating loader list
559 if (found1 == NULL || found2 == NULL) {
Carl Shapirob5573532011-07-12 18:22:59 -0700560 Thread::Current()->ClearException();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700561 if (found1 == found2) {
562 return true;
563 } else {
564 return false;
565 }
566 }
567#endif
568 return true;
569}
570
571bool ClassLinker::InitializeSuperClass(Class* klass) {
572 CHECK(klass != NULL);
573 // TODO: assert klass lock is acquired
574 if (!klass->IsInterface() && klass->HasSuperClass()) {
575 Class* super_class = klass->GetSuperClass();
576 if (super_class->GetStatus() != Class::kStatusInitialized) {
577 CHECK(!super_class->IsInterface());
578 klass->MonitorExit();
579 bool super_initialized = InitializeClass(super_class);
580 klass->MonitorEnter();
581 // TODO: check for a pending exception
582 if (!super_initialized) {
583 klass->SetStatus(Class::kStatusError);
584 klass->NotifyAll();
585 return false;
586 }
587 }
588 }
589 return true;
590}
591
592void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700593 size_t num_static_fields = klass->NumStaticFields();
594 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700595 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700596 }
597 DexFile* dex_file = klass->GetDexFile();
598 if (dex_file == NULL) {
599 return;
600 }
601 const char* descriptor = klass->GetDescriptor().data();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700602 const RawDexFile* raw = dex_file->GetRaw();
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700603 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
604 CHECK(class_def != NULL);
605 const byte* addr = raw->GetEncodedArray(*class_def);
606 size_t array_size = DecodeUnsignedLeb128(&addr);
607 for (size_t i = 0; i < array_size; ++i) {
608 StaticField* field = klass->GetStaticField(i);
609 JValue value;
610 RawDexFile::ValueType type = raw->ReadEncodedValue(&addr, &value);
611 switch (type) {
612 case RawDexFile::kByte:
613 field->SetByte(value.b);
614 break;
615 case RawDexFile::kShort:
616 field->SetShort(value.s);
617 break;
618 case RawDexFile::kChar:
619 field->SetChar(value.c);
620 break;
621 case RawDexFile::kInt:
622 field->SetInt(value.i);
623 break;
624 case RawDexFile::kLong:
625 field->SetLong(value.j);
626 break;
627 case RawDexFile::kFloat:
628 field->SetFloat(value.f);
629 break;
630 case RawDexFile::kDouble:
631 field->SetDouble(value.d);
632 break;
633 case RawDexFile::kString: {
634 uint32_t string_idx = value.i;
635 String* resolved = ResolveString(klass, string_idx);
636 field->SetObject(resolved);
637 break;
638 }
639 case RawDexFile::kBoolean:
640 field->SetBoolean(value.z);
641 break;
642 case RawDexFile::kNull:
643 field->SetObject(value.l);
644 break;
645 default:
Carl Shapiro606258b2011-07-09 16:09:09 -0700646 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700647 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700648 }
649}
650
651bool ClassLinker::LinkClass(Class* klass) {
652 CHECK(klass->status_ == Class::kStatusIdx ||
653 klass->status_ == Class::kStatusLoaded);
654 if (klass->status_ == Class::kStatusIdx) {
655 if (!LinkInterfaces(klass)) {
656 return false;
657 }
658 }
659 if (!LinkSuperClass(klass)) {
660 return false;
661 }
662 if (!LinkMethods(klass)) {
663 return false;
664 }
665 if (!LinkInstanceFields(klass)) {
666 return false;
667 }
668 CreateReferenceOffsets(klass);
669 CHECK_EQ(klass->status_, Class::kStatusLoaded);
670 klass->status_ = Class::kStatusResolved;
671 return true;
672}
673
674bool ClassLinker::LinkInterfaces(Class* klass) {
675 scoped_array<uint32_t> interfaces_idx;
676 // TODO: store interfaces_idx in the Class object
677 // TODO: move this outside of link interfaces
678 if (klass->interface_count_ > 0) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700679 size_t length = klass->interface_count_ * sizeof(klass->interfaces_[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700680 interfaces_idx.reset(new uint32_t[klass->interface_count_]);
Carl Shapiro565f5072011-07-10 13:39:43 -0700681 memcpy(interfaces_idx.get(), klass->interfaces_, length);
682 memset(klass->interfaces_, 0xFF, length);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700683 }
684 // Mark the class as loaded.
685 klass->status_ = Class::kStatusLoaded;
686 if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
687 Class* super_class = ResolveClass(klass, klass->super_class_idx_);
688 if (super_class == NULL) {
689 LG << "Failed to resolve superclass";
690 return false;
691 }
692 klass->super_class_ = super_class; // TODO: write barrier
693 }
694 if (klass->interface_count_ > 0) {
695 for (size_t i = 0; i < klass->interface_count_; ++i) {
696 uint32_t idx = interfaces_idx[i];
697 klass->interfaces_[i] = ResolveClass(klass, idx);
698 if (klass->interfaces_[i] == NULL) {
699 LG << "Failed to resolve interface";
700 return false;
701 }
702 // Verify
703 if (!klass->CanAccess(klass->interfaces_[i])) {
704 LG << "Inaccessible interface";
705 return false;
706 }
707 }
708 }
709 return true;
710}
711
712bool ClassLinker::LinkSuperClass(Class* klass) {
713 CHECK(!klass->IsPrimitive());
714 const Class* super = klass->GetSuperClass();
715 if (klass->GetDescriptor() == "Ljava/lang/Object;") {
716 if (super != NULL) {
717 LG << "Superclass must not be defined"; // TODO: ClassFormatError
718 return false;
719 }
720 // TODO: clear finalize attribute
721 return true;
722 }
723 if (super == NULL) {
724 LG << "No superclass defined"; // TODO: LinkageError
725 return false;
726 }
727 // Verify
728 if (super->IsFinal()) {
729 LG << "Superclass is declared final"; // TODO: IncompatibleClassChangeError
730 return false;
731 }
732 if (super->IsInterface()) {
733 LG << "Superclass is an interface"; // TODO: IncompatibleClassChangeError
734 return false;
735 }
736 if (!klass->CanAccess(super)) {
737 LG << "Superclass is inaccessible"; // TODO: IllegalAccessError
738 return false;
739 }
740 return true;
741}
742
743// Populate the class vtable and itable.
744bool ClassLinker::LinkMethods(Class* klass) {
745 if (klass->IsInterface()) {
746 // No vtable.
747 size_t count = klass->NumVirtualMethods();
748 if (!IsUint(16, count)) {
749 LG << "Too many methods on interface"; // TODO: VirtualMachineError
750 return false;
751 }
Carl Shapiro565f5072011-07-10 13:39:43 -0700752 for (size_t i = 0; i < count; ++i) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700753 klass->GetVirtualMethod(i)->method_index_ = i;
754 }
755 } else {
756 // Link virtual method tables
757 LinkVirtualMethods(klass);
758
759 // Link interface method tables
760 LinkInterfaceMethods(klass);
761
762 // Insert stubs.
763 LinkAbstractMethods(klass);
764 }
765 return true;
766}
767
768bool ClassLinker::LinkVirtualMethods(Class* klass) {
769 uint32_t max_count = klass->NumVirtualMethods();
770 if (klass->GetSuperClass() != NULL) {
771 max_count += klass->GetSuperClass()->NumVirtualMethods();
772 } else {
773 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
774 }
775 // TODO: do not assign to the vtable field until it is fully constructed.
776 // TODO: make this a vector<Method*> instead?
777 klass->vtable_ = new Method*[max_count];
778 if (klass->HasSuperClass()) {
779 memcpy(klass->vtable_,
780 klass->GetSuperClass()->vtable_,
781 klass->GetSuperClass()->vtable_count_ * sizeof(Method*));
782 size_t actual_count = klass->GetSuperClass()->vtable_count_;
783 // See if any of our virtual methods override the superclass.
784 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
785 Method* local_method = klass->GetVirtualMethod(i);
786 size_t j = 0;
787 for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
788 const Method* super_method = klass->vtable_[j];
789 if (local_method->HasSameNameAndPrototype(super_method)) {
790 // Verify
791 if (super_method->IsFinal()) {
792 LG << "Method overrides final method"; // TODO: VirtualMachineError
793 return false;
794 }
795 klass->vtable_[j] = local_method;
796 local_method->method_index_ = j;
797 break;
798 }
799 }
800 if (j == klass->GetSuperClass()->vtable_count_) {
801 // Not overriding, append.
802 klass->vtable_[actual_count] = local_method;
803 local_method->method_index_ = actual_count;
804 actual_count += 1;
805 }
806 }
807 if (!IsUint(16, actual_count)) {
808 LG << "Too many methods defined on class"; // TODO: VirtualMachineError
809 return false;
810 }
811 CHECK_LE(actual_count, max_count);
812 if (actual_count < max_count) {
813 Method** new_vtable = new Method*[actual_count];
814 memcpy(new_vtable, klass->vtable_, actual_count * sizeof(Method*));
Carl Shapiro565f5072011-07-10 13:39:43 -0700815 delete[] klass->vtable_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700816 klass->vtable_ = new_vtable;
817 LG << "shrunk vtable: "
818 << "was " << max_count << ", "
819 << "now " << actual_count;
820 }
821 klass->vtable_count_ = actual_count;
822 } else {
823 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
824 if (!IsUint(16, klass->NumVirtualMethods())) {
825 LG << "Too many methods"; // TODO: VirtualMachineError
826 return false;
827 }
828 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
829 klass->vtable_[i] = klass->GetVirtualMethod(i);
830 klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
831 }
832 klass->vtable_count_ = klass->NumVirtualMethods();
833 }
834 return true;
835}
836
837bool ClassLinker::LinkInterfaceMethods(Class* klass) {
838 int pool_offset = 0;
839 int pool_size = 0;
840 int miranda_count = 0;
841 int miranda_alloc = 0;
842 size_t super_ifcount;
843 if (klass->HasSuperClass()) {
844 super_ifcount = klass->GetSuperClass()->iftable_count_;
845 } else {
846 super_ifcount = 0;
847 }
848 size_t ifCount = super_ifcount;
849 ifCount += klass->interface_count_;
850 for (size_t i = 0; i < klass->interface_count_; i++) {
851 ifCount += klass->interfaces_[i]->iftable_count_;
852 }
853 if (ifCount == 0) {
854 assert(klass->iftable_count_ == 0);
855 assert(klass->iftable == NULL);
856 return true;
857 }
858 klass->iftable_ = new InterfaceEntry[ifCount * sizeof(InterfaceEntry)];
859 memset(klass->iftable_, 0x00, sizeof(InterfaceEntry) * ifCount);
860 if (super_ifcount != 0) {
861 memcpy(klass->iftable_, klass->GetSuperClass()->iftable_,
862 sizeof(InterfaceEntry) * super_ifcount);
863 }
864 // Flatten the interface inheritance hierarchy.
865 size_t idx = super_ifcount;
866 for (size_t i = 0; i < klass->interface_count_; i++) {
867 Class* interf = klass->interfaces_[i];
868 assert(interf != NULL);
869 if (!interf->IsInterface()) {
870 LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
871 return false;
872 }
873 klass->iftable_[idx++].SetClass(interf);
874 for (size_t j = 0; j < interf->iftable_count_; j++) {
875 klass->iftable_[idx++].SetClass(interf->iftable_[j].GetClass());
876 }
877 }
878 CHECK_EQ(idx, ifCount);
879 klass->iftable_count_ = ifCount;
880 if (klass->IsInterface() || super_ifcount == ifCount) {
881 return true;
882 }
883 for (size_t i = super_ifcount; i < ifCount; i++) {
884 pool_size += klass->iftable_[i].GetClass()->NumVirtualMethods();
885 }
886 if (pool_size == 0) {
887 return true;
888 }
889 klass->ifvi_pool_count_ = pool_size;
890 klass->ifvi_pool_ = new uint32_t[pool_size];
891 std::vector<Method*> miranda_list;
892 for (size_t i = super_ifcount; i < ifCount; ++i) {
893 klass->iftable_[i].method_index_array_ = klass->ifvi_pool_ + pool_offset;
894 Class* interface = klass->iftable_[i].GetClass();
895 pool_offset += interface->NumVirtualMethods(); // end here
896 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
897 Method* interface_method = interface->GetVirtualMethod(j);
898 int k; // must be signed
899 for (k = klass->vtable_count_ - 1; k >= 0; --k) {
900 if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700901 if (!klass->vtable_[k]->IsPublic()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700902 LG << "Implementation not public";
903 return false;
904 }
905 klass->iftable_[i].method_index_array_[j] = k;
906 break;
907 }
908 }
909 if (k < 0) {
910 if (miranda_count == miranda_alloc) {
911 miranda_alloc += 8;
912 if (miranda_list.empty()) {
913 miranda_list.resize(miranda_alloc);
914 } else {
915 miranda_list.resize(miranda_alloc);
916 }
917 }
918 int mir;
919 for (mir = 0; mir < miranda_count; mir++) {
920 if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) {
921 break;
922 }
923 }
924 // point the interface table at a phantom slot index
925 klass->iftable_[i].method_index_array_[j] = klass->vtable_count_ + mir;
926 if (mir == miranda_count) {
927 miranda_list[miranda_count++] = interface_method;
928 }
929 }
930 }
931 }
932 if (miranda_count != 0) {
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700933 int oldMethodCount = klass->NumVirtualMethods();
934 int newMethodCount = oldMethodCount + miranda_count;
935 Method** newVirtualMethods = new Method*[newMethodCount];
936 if (klass->virtual_methods_ != NULL) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700937 memcpy(newVirtualMethods,
938 klass->virtual_methods_,
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700939 klass->NumVirtualMethods() * sizeof(Method*));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700940 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700941 klass->virtual_methods_ = newVirtualMethods;
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700942 klass->num_virtual_methods_ = newMethodCount;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700943
944 CHECK(klass->vtable_ != NULL);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700945 int oldVtableCount = klass->vtable_count_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700946 klass->vtable_count_ += miranda_count;
947
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700948 for (int i = 0; i < miranda_count; i++) {
949 Method* meth = Heap::AllocMethod();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700950 memcpy(meth, miranda_list[i], sizeof(Method));
951 meth->klass_ = klass;
952 meth->access_flags_ |= kAccMiranda;
953 meth->method_index_ = 0xFFFF & (oldVtableCount + i);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700954 klass->virtual_methods_[oldMethodCount+i] = meth;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700955 klass->vtable_[oldVtableCount + i] = meth;
956 }
957 }
958 return true;
959}
960
961void ClassLinker::LinkAbstractMethods(Class* klass) {
962 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
963 Method* method = klass->GetVirtualMethod(i);
964 if (method->IsAbstract()) {
965 method->insns_ = reinterpret_cast<uint16_t*>(0xFFFFFFFF); // TODO: AbstractMethodError
966 }
967 }
968}
969
970bool ClassLinker::LinkInstanceFields(Class* klass) {
971 int fieldOffset;
972 if (klass->GetSuperClass() != NULL) {
973 fieldOffset = klass->GetSuperClass()->object_size_;
974 } else {
975 fieldOffset = OFFSETOF_MEMBER(DataObject, fields_);
976 }
977 // Move references to the front.
978 klass->num_reference_ifields_ = 0;
979 size_t i = 0;
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700980 for ( ; i < klass->NumInstanceFields(); i++) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700981 InstanceField* pField = klass->GetInstanceField(i);
982 char c = pField->GetType();
983
984 if (c != '[' && c != 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700985 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
986 InstanceField* refField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700987 char rc = refField->GetType();
988 if (rc == '[' || rc == 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700989 klass->SetInstanceField(i, refField);
990 klass->SetInstanceField(j, pField);
991 pField = refField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700992 c = rc;
993 klass->num_reference_ifields_++;
994 break;
995 }
996 }
997 } else {
998 klass->num_reference_ifields_++;
999 }
1000 if (c != '[' && c != 'L') {
1001 break;
1002 }
1003 pField->SetOffset(fieldOffset);
1004 fieldOffset += sizeof(uint32_t);
1005 }
1006
1007 // Now we want to pack all of the double-wide fields together. If
1008 // we're not aligned, though, we want to shuffle one 32-bit field
1009 // into place. If we can't find one, we'll have to pad it.
1010 if (i != klass->NumInstanceFields() && (fieldOffset & 0x04) != 0) {
1011 InstanceField* pField = klass->GetInstanceField(i);
1012 char c = pField->GetType();
1013
1014 if (c != 'J' && c != 'D') {
1015 // The field that comes next is 32-bit, so just advance past it.
1016 assert(c != '[' && c != 'L');
1017 pField->SetOffset(fieldOffset);
1018 fieldOffset += sizeof(uint32_t);
1019 i++;
1020 } else {
1021 // Next field is 64-bit, so search for a 32-bit field we can
1022 // swap into it.
1023 bool found = false;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001024 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1025 InstanceField* singleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001026 char rc = singleField->GetType();
1027 if (rc != 'J' && rc != 'D') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001028 klass->SetInstanceField(i, singleField);
1029 klass->SetInstanceField(j, pField);
1030 pField = singleField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001031 pField->SetOffset(fieldOffset);
1032 fieldOffset += sizeof(uint32_t);
1033 found = true;
1034 i++;
1035 break;
1036 }
1037 }
1038 if (!found) {
1039 fieldOffset += sizeof(uint32_t);
1040 }
1041 }
1042 }
1043
1044 // Alignment is good, shuffle any double-wide fields forward, and
1045 // finish assigning field offsets to all fields.
1046 assert(i == klass->NumInstanceFields() || (fieldOffset & 0x04) == 0);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001047 for ( ; i < klass->NumInstanceFields(); i++) {
1048 InstanceField* pField = klass->GetInstanceField(i);
1049 char c = pField->GetType();
1050 if (c != 'D' && c != 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001051 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1052 InstanceField* doubleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001053 char rc = doubleField->GetType();
1054 if (rc == 'D' || rc == 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001055 klass->SetInstanceField(i, doubleField);
1056 klass->SetInstanceField(j, pField);
1057 pField = doubleField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001058 c = rc;
1059 break;
1060 }
1061 }
1062 } else {
1063 // This is a double-wide field, leave it be.
1064 }
1065
1066 pField->SetOffset(fieldOffset);
1067 fieldOffset += sizeof(uint32_t);
1068 if (c == 'J' || c == 'D')
1069 fieldOffset += sizeof(uint32_t);
1070 }
1071
1072#ifndef NDEBUG
1073 /* Make sure that all reference fields appear before
1074 * non-reference fields, and all double-wide fields are aligned.
1075 */
1076 j = 0; // seen non-ref
1077 for (i = 0; i < klass->NumInstanceFields(); i++) {
1078 InstanceField *pField = &klass->ifields[i];
1079 char c = pField->GetType();
1080
1081 if (c == 'D' || c == 'J') {
1082 assert((pField->offset_ & 0x07) == 0);
1083 }
1084
1085 if (c != '[' && c != 'L') {
1086 if (!j) {
1087 assert(i == klass->num_reference_ifields_);
1088 j = 1;
1089 }
1090 } else if (j) {
1091 assert(false);
1092 }
1093 }
1094 if (!j) {
1095 assert(klass->num_reference_ifields_ == klass->NumInstanceFields());
1096 }
1097#endif
1098
1099 klass->object_size_ = fieldOffset;
1100 return true;
1101}
1102
1103// Set the bitmap of reference offsets, refOffsets, from the ifields
1104// list.
1105void ClassLinker::CreateReferenceOffsets(Class* klass) {
1106 uint32_t reference_offsets = 0;
1107 if (klass->HasSuperClass()) {
1108 reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
1109 }
1110 // If our superclass overflowed, we don't stand a chance.
1111 if (reference_offsets != CLASS_WALK_SUPER) {
1112 // All of the fields that contain object references are guaranteed
1113 // to be at the beginning of the ifields list.
1114 for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
1115 // Note that, per the comment on struct InstField, f->byteOffset
1116 // is the offset from the beginning of obj, not the offset into
1117 // obj->instanceData.
1118 const InstanceField* field = klass->GetInstanceField(i);
1119 size_t byte_offset = field->GetOffset();
1120 CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001121 CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001122 if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
1123 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001124 CHECK_NE(new_bit, 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001125 reference_offsets |= new_bit;
1126 } else {
1127 reference_offsets = CLASS_WALK_SUPER;
1128 break;
1129 }
1130 }
1131 klass->SetReferenceOffsets(reference_offsets);
1132 }
1133}
1134
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001135Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001136 DexFile* dex_file = referrer->GetDexFile();
1137 Class* resolved = dex_file->GetResolvedClass(class_idx);
1138 if (resolved != NULL) {
1139 return resolved;
1140 }
1141 const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx);
1142 if (descriptor[0] != '\0' && descriptor[1] == '\0') {
Carl Shapiro565f5072011-07-10 13:39:43 -07001143 JType type = static_cast<JType>(descriptor[0]);
1144 resolved = FindPrimitiveClass(type);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001145 } else {
1146 resolved = FindClass(descriptor, referrer->GetClassLoader(), NULL);
1147 }
1148 if (resolved != NULL) {
1149 Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
1150 if (referrer->GetDexFile() != check->GetDexFile()) {
1151 if (check->GetClassLoader() != NULL) {
1152 LG << "Class resolved by unexpected DEX"; // TODO: IllegalAccessError
1153 return NULL;
1154 }
1155 }
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001156 dex_file->SetResolvedClass(resolved, class_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001157 } else {
Carl Shapirob5573532011-07-12 18:22:59 -07001158 CHECK(Thread::Current()->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001159 }
1160 return resolved;
1161}
1162
1163Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
1164 /*MethodType*/ int method_type) {
1165 CHECK(false);
1166 return NULL;
1167}
1168
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001169String* ClassLinker::ResolveString(const Class* referring, uint32_t string_idx) {
1170 const RawDexFile* raw = referring->GetDexFile()->GetRaw();
1171 const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
1172 const char* string_data = raw->GetStringData(string_id);
1173 String* new_string = Heap::AllocStringFromModifiedUtf8(string_data);
1174 // TODO: intern the new string
1175 referring->GetDexFile()->SetResolvedString(new_string, string_idx);
1176 return new_string;
1177}
1178
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001179} // namespace art