blob: e1e9bef96d43f29f3773bec333f54af49bd07a00 [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 Shapiro565f5072011-07-10 13:39:43 -070022void ClassLinker::Init() {
23 // Allocate and partially initialize the class Class. This object
24 // will complete its initialization when its definition is loaded.
25 java_lang_Class_ = Heap::AllocClass();
26 java_lang_Class_->super_class_ = java_lang_Class_;
27 java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
28
29 // Allocate and initialize the primitive type classes.
30 primitive_byte_ = CreatePrimitiveClass(kTypeByte, "B");
31 primitive_char_ = CreatePrimitiveClass(kTypeChar, "C");
32 primitive_double_ = CreatePrimitiveClass(kTypeDouble, "D");
33 primitive_float_ = CreatePrimitiveClass(kTypeFloat, "F");
34 primitive_int_ = CreatePrimitiveClass(kTypeInt, "I");
35 primitive_long_ = CreatePrimitiveClass(kTypeLong, "J");
36 primitive_short_ = CreatePrimitiveClass(kTypeShort, "S");
37 primitive_boolean_ = CreatePrimitiveClass(kTypeBoolean, "Z");
38 primitive_void_ = CreatePrimitiveClass(kTypeVoid, "V");
39}
40
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070041Class* ClassLinker::FindClass(const char* descriptor,
42 Object* class_loader,
43 DexFile* dex_file) {
44 Thread* self = Thread::Self();
45 CHECK(!self->IsExceptionPending());
46 // Find the class in the loaded classes table.
47 Class* klass = LookupClass(descriptor, class_loader);
48 if (klass == NULL) {
49 // Class is not yet loaded.
50 if (dex_file == NULL) {
51 // No .dex file specified, search the class path.
52 dex_file = FindInClassPath(descriptor);
53 if (dex_file == NULL) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070054 LG << "Class " << descriptor << " really not found";
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070055 return NULL;
56 }
57 }
58 // Load the class from the dex file.
Carl Shapiro565f5072011-07-10 13:39:43 -070059 if (!strcmp(descriptor, "Ljava/lang/Class;")) {
60 klass = java_lang_Class_;
61 } else {
62 klass = Heap::AllocClass();
63 }
64 bool is_loaded = dex_file->LoadClass(descriptor, klass);
65 if (!is_loaded) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070066 // TODO: this occurs only when a dex file is provided.
67 LG << "Class not found"; // TODO: NoClassDefFoundError
68 return NULL;
69 }
70 // Check for a pending exception during load
71 if (self->IsExceptionPending()) {
72 // TODO: free native allocations in klass
73 return NULL;
74 }
75 {
76 ObjectLock lock(klass);
77 klass->clinit_thread_id_ = self->GetThreadId();
78 // Add the newly loaded class to the loaded classes table.
79 bool success = InsertClass(klass);
80 if (!success) {
81 // We may fail to insert if we raced with another thread.
82 klass->clinit_thread_id_ = 0;
83 // TODO: free native allocations in klass
84 klass = LookupClass(descriptor, class_loader);
85 CHECK(klass != NULL);
86 } else {
87 // Link the class.
88 if (!LinkClass(klass)) {
89 // Linking failed.
90 // TODO: CHECK(self->IsExceptionPending());
91 lock.NotifyAll();
92 return NULL;
93 }
94 }
95 }
96 }
97 // Link the class if it has not already been linked.
98 if (!klass->IsLinked() && !klass->IsErroneous()) {
99 ObjectLock lock(klass);
100 // Check for circular dependencies between classes.
101 if (!klass->IsLinked() && klass->clinit_thread_id_ == self->GetThreadId()) {
102 LG << "Recursive link"; // TODO: ClassCircularityError
103 return NULL;
104 }
105 // Wait for the pending initialization to complete.
106 while (!klass->IsLinked() && !klass->IsErroneous()) {
107 lock.Wait();
108 }
109 }
110 if (klass->IsErroneous()) {
111 LG << "EarlierClassFailure"; // TODO: EarlierClassFailure
112 return NULL;
113 }
114 // Return the loaded class. No exceptions should be pending.
115 CHECK(!self->IsExceptionPending());
116 return klass;
117}
118
119DexFile* ClassLinker::FindInClassPath(const char* descriptor) {
120 for (size_t i = 0; i != class_path_.size(); ++i) {
121 DexFile* dex_file = class_path_[i];
122 if (dex_file->HasClass(descriptor)) {
123 return dex_file;
124 }
125 }
126 return NULL;
127}
128
129void ClassLinker::AppendToClassPath(DexFile* dex_file) {
130 class_path_.push_back(dex_file);
131}
132
Carl Shapiro565f5072011-07-10 13:39:43 -0700133Class* ClassLinker::CreatePrimitiveClass(JType type, const char* descriptor) {
134 Class* klass = Heap::AllocClass();
135 CHECK(klass != NULL);
136 klass->super_class_ = java_lang_Class_;
137 klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
138 klass->descriptor_ = descriptor;
139 klass->status_ = Class::kStatusInitialized;
140 return klass;
141}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700142
Carl Shapiro565f5072011-07-10 13:39:43 -0700143Class* ClassLinker::FindPrimitiveClass(JType type) {
144 switch (type) {
145 case kTypeByte:
146 CHECK(primitive_byte_ != NULL);
147 return primitive_byte_;
148 case kTypeChar:
149 CHECK(primitive_char_ != NULL);
150 return primitive_char_;
151 case kTypeDouble:
152 CHECK(primitive_double_ != NULL);
153 return primitive_double_;
154 case kTypeFloat:
155 CHECK(primitive_float_ != NULL);
156 return primitive_float_;
157 case kTypeInt:
158 CHECK(primitive_int_ != NULL);
159 return primitive_int_;
160 case kTypeLong:
161 CHECK(primitive_long_ != NULL);
162 return primitive_long_;
163 case kTypeShort:
164 CHECK(primitive_short_ != NULL);
165 return primitive_short_;
166 case kTypeBoolean:
167 CHECK(primitive_boolean_ != NULL);
168 return primitive_boolean_;
169 case kTypeVoid:
170 CHECK(primitive_void_ != NULL);
171 return primitive_void_;
172 default:
173 LOG(FATAL) << "Unknown primitive type " << static_cast<int>(type);
174 };
175 return NULL; // Not reachable.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700176}
177
178bool ClassLinker::InsertClass(Class* klass) {
179 // TODO: acquire classes_lock_
180 const char* key = klass->GetDescriptor().data();
181 bool success = classes_.insert(std::make_pair(key, klass)).second;
182 // TODO: release classes_lock_
183 return success;
184}
185
186Class* ClassLinker::LookupClass(const char* descriptor, Object* class_loader) {
187 // TODO: acquire classes_lock_
188 Table::iterator it = classes_.find(descriptor);
189 // TODO: release classes_lock_
190 if (it == classes_.end()) {
191 return NULL;
192 } else {
193 return (*it).second;
194 }
195}
196
197bool ClassLinker::InitializeClass(Class* klass) {
198 CHECK(klass->GetStatus() == Class::kStatusResolved ||
199 klass->GetStatus() == Class::kStatusError);
200
201 Thread* self = Thread::Self();
202
203 {
204 ObjectLock lock(klass);
205
206 if (klass->GetStatus() < Class::kStatusVerified) {
207 if (klass->IsErroneous()) {
208 LG << "re-initializing failed class"; // TODO: throw
209 return false;
210 }
211
212 CHECK(klass->GetStatus() == Class::kStatusResolved);
213
214 klass->status_ = Class::kStatusVerifying;
215 if (!DexVerify::VerifyClass(klass)) {
216 LG << "Verification failed"; // TODO: ThrowVerifyError
217 Object* exception = self->GetException();
218 klass->SetObjectAt(OFFSETOF_MEMBER(Class, verify_error_class_),
219 exception->GetClass());
220 klass->SetStatus(Class::kStatusError);
221 return false;
222 }
223
224 klass->SetStatus(Class::kStatusVerified);
225 }
226
227 if (klass->status_ == Class::kStatusInitialized) {
228 return true;
229 }
230
231 while (klass->status_ == Class::kStatusInitializing) {
232 // we caught somebody else in the act; was it us?
233 if (klass->clinit_thread_id_ == self->GetThreadId()) {
234 LG << "recursive <clinit>";
235 return true;
236 }
237
238 CHECK(!self->IsExceptionPending());
239
240 lock.Wait(); // TODO: check for interruption
241
242 // When we wake up, repeat the test for init-in-progress. If
243 // there's an exception pending (only possible if
244 // "interruptShouldThrow" was set), bail out.
245 if (self->IsExceptionPending()) {
246 CHECK(false);
247 LG << "Exception in initialization."; // TODO: ExceptionInInitializerError
248 klass->SetStatus(Class::kStatusError);
249 return false;
250 }
251 if (klass->GetStatus() == Class::kStatusInitializing) {
252 continue;
253 }
254 assert(klass->GetStatus() == Class::kStatusInitialized ||
255 klass->GetStatus() == Class::kStatusError);
256 if (klass->IsErroneous()) {
257 /*
258 * The caller wants an exception, but it was thrown in a
259 * different thread. Synthesize one here.
260 */
261 LG << "<clinit> failed"; // TODO: throw UnsatisfiedLinkError
262 return false;
263 }
264 return true; // otherwise, initialized
265 }
266
267 // see if we failed previously
268 if (klass->IsErroneous()) {
269 // might be wise to unlock before throwing; depends on which class
270 // it is that we have locked
271
272 // TODO: throwEarlierClassFailure(klass);
273 return false;
274 }
275
276 if (!ValidateSuperClassDescriptors(klass)) {
277 klass->SetStatus(Class::kStatusError);
278 return false;
279 }
280
281 assert(klass->status < CLASS_INITIALIZING);
282
283 klass->clinit_thread_id_ = self->GetThreadId();
284 klass->status_ = Class::kStatusInitializing;
285 }
286
287 if (!InitializeSuperClass(klass)) {
288 return false;
289 }
290
291 InitializeStaticFields(klass);
292
293 Method* clinit = klass->FindDirectMethodLocally("<clinit>", "()V");
294 if (clinit != NULL) {
295 } else {
296 // JValue unused;
297 // TODO: dvmCallMethod(self, method, NULL, &unused);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700298 //CHECK(!"unimplemented");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700299 }
300
301 {
302 ObjectLock lock(klass);
303
304 if (self->IsExceptionPending()) {
305 klass->SetStatus(Class::kStatusError);
306 } else {
307 klass->SetStatus(Class::kStatusInitialized);
308 }
309 lock.NotifyAll();
310 }
311
312 return true;
313}
314
315bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
316 if (klass->IsInterface()) {
317 return true;
318 }
319 // begin with the methods local to the superclass
320 if (klass->HasSuperClass() &&
321 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
322 const Class* super = klass->GetSuperClass();
323 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
324 const Method* method = klass->GetVirtualMethod(i);
325 if (method != super->GetVirtualMethod(i) &&
326 !HasSameMethodDescriptorClasses(method, super, klass)) {
327 LG << "Classes resolve differently in superclass";
328 return false;
329 }
330 }
331 }
332 for (size_t i = 0; i < klass->iftable_count_; ++i) {
333 const InterfaceEntry* iftable = &klass->iftable_[i];
334 Class* interface = iftable->GetClass();
335 if (klass->GetClassLoader() != interface->GetClassLoader()) {
336 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
337 uint32_t vtable_index = iftable->method_index_array_[j];
338 const Method* method = klass->GetVirtualMethod(vtable_index);
339 if (!HasSameMethodDescriptorClasses(method, interface,
340 method->GetClass())) {
341 LG << "Classes resolve differently in interface"; // TODO: LinkageError
342 return false;
343 }
344 }
345 }
346 }
347 return true;
348}
349
350bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
351 const Class* klass1,
352 const Class* klass2) {
353 const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
354 const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
355 RawDexFile::ParameterIterator *it;
356 for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
357 const char* descriptor = it->GetDescriptor();
358 if (descriptor == NULL) {
359 break;
360 }
361 if (descriptor[0] == 'L' || descriptor[0] == '[') {
362 // Found a non-primitive type.
363 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
364 return false;
365 }
366 }
367 }
368 // Check the return type
369 const char* descriptor = raw->GetReturnTypeDescriptor(proto_id);
370 if (descriptor[0] == 'L' || descriptor[0] == '[') {
371 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
372 return false;
373 }
374 }
375 return true;
376}
377
378// Returns true if classes referenced by the descriptor are the
379// same classes in klass1 as they are in klass2.
380bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
381 const Class* klass1,
382 const Class* klass2) {
383 CHECK(descriptor != NULL);
384 CHECK(klass1 != NULL);
385 CHECK(klass2 != NULL);
386#if 0
387 Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader());
388 // TODO: found1 == NULL
389 Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader());
390 // TODO: found2 == NULL
391 // TODO: lookup found1 in initiating loader list
392 if (found1 == NULL || found2 == NULL) {
393 Thread::Self()->ClearException();
394 if (found1 == found2) {
395 return true;
396 } else {
397 return false;
398 }
399 }
400#endif
401 return true;
402}
403
404bool ClassLinker::InitializeSuperClass(Class* klass) {
405 CHECK(klass != NULL);
406 // TODO: assert klass lock is acquired
407 if (!klass->IsInterface() && klass->HasSuperClass()) {
408 Class* super_class = klass->GetSuperClass();
409 if (super_class->GetStatus() != Class::kStatusInitialized) {
410 CHECK(!super_class->IsInterface());
411 klass->MonitorExit();
412 bool super_initialized = InitializeClass(super_class);
413 klass->MonitorEnter();
414 // TODO: check for a pending exception
415 if (!super_initialized) {
416 klass->SetStatus(Class::kStatusError);
417 klass->NotifyAll();
418 return false;
419 }
420 }
421 }
422 return true;
423}
424
425void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700426 size_t num_static_fields = klass->NumStaticFields();
427 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700428 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700429 }
430 DexFile* dex_file = klass->GetDexFile();
431 if (dex_file == NULL) {
432 return;
433 }
434 const char* descriptor = klass->GetDescriptor().data();
435 RawDexFile* raw = dex_file->GetRaw();
436 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
437 CHECK(class_def != NULL);
438 const byte* addr = raw->GetEncodedArray(*class_def);
439 size_t array_size = DecodeUnsignedLeb128(&addr);
440 for (size_t i = 0; i < array_size; ++i) {
441 StaticField* field = klass->GetStaticField(i);
442 JValue value;
443 RawDexFile::ValueType type = raw->ReadEncodedValue(&addr, &value);
444 switch (type) {
445 case RawDexFile::kByte:
446 field->SetByte(value.b);
447 break;
448 case RawDexFile::kShort:
449 field->SetShort(value.s);
450 break;
451 case RawDexFile::kChar:
452 field->SetChar(value.c);
453 break;
454 case RawDexFile::kInt:
455 field->SetInt(value.i);
456 break;
457 case RawDexFile::kLong:
458 field->SetLong(value.j);
459 break;
460 case RawDexFile::kFloat:
461 field->SetFloat(value.f);
462 break;
463 case RawDexFile::kDouble:
464 field->SetDouble(value.d);
465 break;
466 case RawDexFile::kString: {
467 uint32_t string_idx = value.i;
468 String* resolved = ResolveString(klass, string_idx);
469 field->SetObject(resolved);
470 break;
471 }
472 case RawDexFile::kBoolean:
473 field->SetBoolean(value.z);
474 break;
475 case RawDexFile::kNull:
476 field->SetObject(value.l);
477 break;
478 default:
Carl Shapiro606258b2011-07-09 16:09:09 -0700479 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700480 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700481 }
482}
483
484bool ClassLinker::LinkClass(Class* klass) {
485 CHECK(klass->status_ == Class::kStatusIdx ||
486 klass->status_ == Class::kStatusLoaded);
487 if (klass->status_ == Class::kStatusIdx) {
488 if (!LinkInterfaces(klass)) {
489 return false;
490 }
491 }
492 if (!LinkSuperClass(klass)) {
493 return false;
494 }
495 if (!LinkMethods(klass)) {
496 return false;
497 }
498 if (!LinkInstanceFields(klass)) {
499 return false;
500 }
501 CreateReferenceOffsets(klass);
502 CHECK_EQ(klass->status_, Class::kStatusLoaded);
503 klass->status_ = Class::kStatusResolved;
504 return true;
505}
506
507bool ClassLinker::LinkInterfaces(Class* klass) {
508 scoped_array<uint32_t> interfaces_idx;
509 // TODO: store interfaces_idx in the Class object
510 // TODO: move this outside of link interfaces
511 if (klass->interface_count_ > 0) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700512 size_t length = klass->interface_count_ * sizeof(klass->interfaces_[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700513 interfaces_idx.reset(new uint32_t[klass->interface_count_]);
Carl Shapiro565f5072011-07-10 13:39:43 -0700514 memcpy(interfaces_idx.get(), klass->interfaces_, length);
515 memset(klass->interfaces_, 0xFF, length);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700516 }
517 // Mark the class as loaded.
518 klass->status_ = Class::kStatusLoaded;
519 if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
520 Class* super_class = ResolveClass(klass, klass->super_class_idx_);
521 if (super_class == NULL) {
522 LG << "Failed to resolve superclass";
523 return false;
524 }
525 klass->super_class_ = super_class; // TODO: write barrier
526 }
527 if (klass->interface_count_ > 0) {
528 for (size_t i = 0; i < klass->interface_count_; ++i) {
529 uint32_t idx = interfaces_idx[i];
530 klass->interfaces_[i] = ResolveClass(klass, idx);
531 if (klass->interfaces_[i] == NULL) {
532 LG << "Failed to resolve interface";
533 return false;
534 }
535 // Verify
536 if (!klass->CanAccess(klass->interfaces_[i])) {
537 LG << "Inaccessible interface";
538 return false;
539 }
540 }
541 }
542 return true;
543}
544
545bool ClassLinker::LinkSuperClass(Class* klass) {
546 CHECK(!klass->IsPrimitive());
547 const Class* super = klass->GetSuperClass();
548 if (klass->GetDescriptor() == "Ljava/lang/Object;") {
549 if (super != NULL) {
550 LG << "Superclass must not be defined"; // TODO: ClassFormatError
551 return false;
552 }
553 // TODO: clear finalize attribute
554 return true;
555 }
556 if (super == NULL) {
557 LG << "No superclass defined"; // TODO: LinkageError
558 return false;
559 }
560 // Verify
561 if (super->IsFinal()) {
562 LG << "Superclass is declared final"; // TODO: IncompatibleClassChangeError
563 return false;
564 }
565 if (super->IsInterface()) {
566 LG << "Superclass is an interface"; // TODO: IncompatibleClassChangeError
567 return false;
568 }
569 if (!klass->CanAccess(super)) {
570 LG << "Superclass is inaccessible"; // TODO: IllegalAccessError
571 return false;
572 }
573 return true;
574}
575
576// Populate the class vtable and itable.
577bool ClassLinker::LinkMethods(Class* klass) {
578 if (klass->IsInterface()) {
579 // No vtable.
580 size_t count = klass->NumVirtualMethods();
581 if (!IsUint(16, count)) {
582 LG << "Too many methods on interface"; // TODO: VirtualMachineError
583 return false;
584 }
Carl Shapiro565f5072011-07-10 13:39:43 -0700585 for (size_t i = 0; i < count; ++i) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700586 klass->GetVirtualMethod(i)->method_index_ = i;
587 }
588 } else {
589 // Link virtual method tables
590 LinkVirtualMethods(klass);
591
592 // Link interface method tables
593 LinkInterfaceMethods(klass);
594
595 // Insert stubs.
596 LinkAbstractMethods(klass);
597 }
598 return true;
599}
600
601bool ClassLinker::LinkVirtualMethods(Class* klass) {
602 uint32_t max_count = klass->NumVirtualMethods();
603 if (klass->GetSuperClass() != NULL) {
604 max_count += klass->GetSuperClass()->NumVirtualMethods();
605 } else {
606 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
607 }
608 // TODO: do not assign to the vtable field until it is fully constructed.
609 // TODO: make this a vector<Method*> instead?
610 klass->vtable_ = new Method*[max_count];
611 if (klass->HasSuperClass()) {
612 memcpy(klass->vtable_,
613 klass->GetSuperClass()->vtable_,
614 klass->GetSuperClass()->vtable_count_ * sizeof(Method*));
615 size_t actual_count = klass->GetSuperClass()->vtable_count_;
616 // See if any of our virtual methods override the superclass.
617 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
618 Method* local_method = klass->GetVirtualMethod(i);
619 size_t j = 0;
620 for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
621 const Method* super_method = klass->vtable_[j];
622 if (local_method->HasSameNameAndPrototype(super_method)) {
623 // Verify
624 if (super_method->IsFinal()) {
625 LG << "Method overrides final method"; // TODO: VirtualMachineError
626 return false;
627 }
628 klass->vtable_[j] = local_method;
629 local_method->method_index_ = j;
630 break;
631 }
632 }
633 if (j == klass->GetSuperClass()->vtable_count_) {
634 // Not overriding, append.
635 klass->vtable_[actual_count] = local_method;
636 local_method->method_index_ = actual_count;
637 actual_count += 1;
638 }
639 }
640 if (!IsUint(16, actual_count)) {
641 LG << "Too many methods defined on class"; // TODO: VirtualMachineError
642 return false;
643 }
644 CHECK_LE(actual_count, max_count);
645 if (actual_count < max_count) {
646 Method** new_vtable = new Method*[actual_count];
647 memcpy(new_vtable, klass->vtable_, actual_count * sizeof(Method*));
Carl Shapiro565f5072011-07-10 13:39:43 -0700648 delete[] klass->vtable_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700649 klass->vtable_ = new_vtable;
650 LG << "shrunk vtable: "
651 << "was " << max_count << ", "
652 << "now " << actual_count;
653 }
654 klass->vtable_count_ = actual_count;
655 } else {
656 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
657 if (!IsUint(16, klass->NumVirtualMethods())) {
658 LG << "Too many methods"; // TODO: VirtualMachineError
659 return false;
660 }
661 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
662 klass->vtable_[i] = klass->GetVirtualMethod(i);
663 klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
664 }
665 klass->vtable_count_ = klass->NumVirtualMethods();
666 }
667 return true;
668}
669
670bool ClassLinker::LinkInterfaceMethods(Class* klass) {
671 int pool_offset = 0;
672 int pool_size = 0;
673 int miranda_count = 0;
674 int miranda_alloc = 0;
675 size_t super_ifcount;
676 if (klass->HasSuperClass()) {
677 super_ifcount = klass->GetSuperClass()->iftable_count_;
678 } else {
679 super_ifcount = 0;
680 }
681 size_t ifCount = super_ifcount;
682 ifCount += klass->interface_count_;
683 for (size_t i = 0; i < klass->interface_count_; i++) {
684 ifCount += klass->interfaces_[i]->iftable_count_;
685 }
686 if (ifCount == 0) {
687 assert(klass->iftable_count_ == 0);
688 assert(klass->iftable == NULL);
689 return true;
690 }
691 klass->iftable_ = new InterfaceEntry[ifCount * sizeof(InterfaceEntry)];
692 memset(klass->iftable_, 0x00, sizeof(InterfaceEntry) * ifCount);
693 if (super_ifcount != 0) {
694 memcpy(klass->iftable_, klass->GetSuperClass()->iftable_,
695 sizeof(InterfaceEntry) * super_ifcount);
696 }
697 // Flatten the interface inheritance hierarchy.
698 size_t idx = super_ifcount;
699 for (size_t i = 0; i < klass->interface_count_; i++) {
700 Class* interf = klass->interfaces_[i];
701 assert(interf != NULL);
702 if (!interf->IsInterface()) {
703 LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
704 return false;
705 }
706 klass->iftable_[idx++].SetClass(interf);
707 for (size_t j = 0; j < interf->iftable_count_; j++) {
708 klass->iftable_[idx++].SetClass(interf->iftable_[j].GetClass());
709 }
710 }
711 CHECK_EQ(idx, ifCount);
712 klass->iftable_count_ = ifCount;
713 if (klass->IsInterface() || super_ifcount == ifCount) {
714 return true;
715 }
716 for (size_t i = super_ifcount; i < ifCount; i++) {
717 pool_size += klass->iftable_[i].GetClass()->NumVirtualMethods();
718 }
719 if (pool_size == 0) {
720 return true;
721 }
722 klass->ifvi_pool_count_ = pool_size;
723 klass->ifvi_pool_ = new uint32_t[pool_size];
724 std::vector<Method*> miranda_list;
725 for (size_t i = super_ifcount; i < ifCount; ++i) {
726 klass->iftable_[i].method_index_array_ = klass->ifvi_pool_ + pool_offset;
727 Class* interface = klass->iftable_[i].GetClass();
728 pool_offset += interface->NumVirtualMethods(); // end here
729 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
730 Method* interface_method = interface->GetVirtualMethod(j);
731 int k; // must be signed
732 for (k = klass->vtable_count_ - 1; k >= 0; --k) {
733 if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700734 if (!klass->vtable_[k]->IsPublic()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700735 LG << "Implementation not public";
736 return false;
737 }
738 klass->iftable_[i].method_index_array_[j] = k;
739 break;
740 }
741 }
742 if (k < 0) {
743 if (miranda_count == miranda_alloc) {
744 miranda_alloc += 8;
745 if (miranda_list.empty()) {
746 miranda_list.resize(miranda_alloc);
747 } else {
748 miranda_list.resize(miranda_alloc);
749 }
750 }
751 int mir;
752 for (mir = 0; mir < miranda_count; mir++) {
753 if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) {
754 break;
755 }
756 }
757 // point the interface table at a phantom slot index
758 klass->iftable_[i].method_index_array_[j] = klass->vtable_count_ + mir;
759 if (mir == miranda_count) {
760 miranda_list[miranda_count++] = interface_method;
761 }
762 }
763 }
764 }
765 if (miranda_count != 0) {
766 Method* newVirtualMethods;
767 Method* meth;
768 int oldMethodCount, oldVtableCount;
769 if (klass->virtual_methods_ == NULL) {
770 newVirtualMethods = new Method[klass->NumVirtualMethods() + miranda_count];
771
772 } else {
773 newVirtualMethods = new Method[klass->NumVirtualMethods() + miranda_count];
774 memcpy(newVirtualMethods,
775 klass->virtual_methods_,
776 klass->NumVirtualMethods() * sizeof(Method));
777
778 }
779 if (newVirtualMethods != klass->virtual_methods_) {
780 Method* meth = newVirtualMethods;
781 for (size_t i = 0; i < klass->NumVirtualMethods(); i++, meth++) {
782 klass->vtable_[meth->method_index_] = meth;
783 }
784 }
785 oldMethodCount = klass->NumVirtualMethods();
786 klass->virtual_methods_ = newVirtualMethods;
787 klass->num_virtual_methods_ += miranda_count;
788
789 CHECK(klass->vtable_ != NULL);
790 oldVtableCount = klass->vtable_count_;
791 klass->vtable_count_ += miranda_count;
792
793 meth = klass->virtual_methods_ + oldMethodCount;
794 for (int i = 0; i < miranda_count; i++, meth++) {
795 memcpy(meth, miranda_list[i], sizeof(Method));
796 meth->klass_ = klass;
797 meth->access_flags_ |= kAccMiranda;
798 meth->method_index_ = 0xFFFF & (oldVtableCount + i);
799 klass->vtable_[oldVtableCount + i] = meth;
800 }
801 }
802 return true;
803}
804
805void ClassLinker::LinkAbstractMethods(Class* klass) {
806 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
807 Method* method = klass->GetVirtualMethod(i);
808 if (method->IsAbstract()) {
809 method->insns_ = reinterpret_cast<uint16_t*>(0xFFFFFFFF); // TODO: AbstractMethodError
810 }
811 }
812}
813
814bool ClassLinker::LinkInstanceFields(Class* klass) {
815 int fieldOffset;
816 if (klass->GetSuperClass() != NULL) {
817 fieldOffset = klass->GetSuperClass()->object_size_;
818 } else {
819 fieldOffset = OFFSETOF_MEMBER(DataObject, fields_);
820 }
821 // Move references to the front.
822 klass->num_reference_ifields_ = 0;
823 size_t i = 0;
824 size_t j = klass->NumInstanceFields() - 1;
825 for (size_t i = 0; i < klass->NumInstanceFields(); i++) {
826 InstanceField* pField = klass->GetInstanceField(i);
827 char c = pField->GetType();
828
829 if (c != '[' && c != 'L') {
830 while (j > i) {
831 InstanceField* refField = klass->GetInstanceField(j--);
832 char rc = refField->GetType();
833 if (rc == '[' || rc == 'L') {
834 pField->Swap(refField);
835 c = rc;
836 klass->num_reference_ifields_++;
837 break;
838 }
839 }
840 } else {
841 klass->num_reference_ifields_++;
842 }
843 if (c != '[' && c != 'L') {
844 break;
845 }
846 pField->SetOffset(fieldOffset);
847 fieldOffset += sizeof(uint32_t);
848 }
849
850 // Now we want to pack all of the double-wide fields together. If
851 // we're not aligned, though, we want to shuffle one 32-bit field
852 // into place. If we can't find one, we'll have to pad it.
853 if (i != klass->NumInstanceFields() && (fieldOffset & 0x04) != 0) {
854 InstanceField* pField = klass->GetInstanceField(i);
855 char c = pField->GetType();
856
857 if (c != 'J' && c != 'D') {
858 // The field that comes next is 32-bit, so just advance past it.
859 assert(c != '[' && c != 'L');
860 pField->SetOffset(fieldOffset);
861 fieldOffset += sizeof(uint32_t);
862 i++;
863 } else {
864 // Next field is 64-bit, so search for a 32-bit field we can
865 // swap into it.
866 bool found = false;
867 j = klass->NumInstanceFields() - 1;
868 while (j > i) {
869 InstanceField* singleField = klass->GetInstanceField(j--);
870 char rc = singleField->GetType();
871 if (rc != 'J' && rc != 'D') {
872 pField->Swap(singleField);
873 pField->SetOffset(fieldOffset);
874 fieldOffset += sizeof(uint32_t);
875 found = true;
876 i++;
877 break;
878 }
879 }
880 if (!found) {
881 fieldOffset += sizeof(uint32_t);
882 }
883 }
884 }
885
886 // Alignment is good, shuffle any double-wide fields forward, and
887 // finish assigning field offsets to all fields.
888 assert(i == klass->NumInstanceFields() || (fieldOffset & 0x04) == 0);
889 j = klass->NumInstanceFields() - 1;
890 for ( ; i < klass->NumInstanceFields(); i++) {
891 InstanceField* pField = klass->GetInstanceField(i);
892 char c = pField->GetType();
893 if (c != 'D' && c != 'J') {
894 while (j > i) {
895 InstanceField* doubleField = klass->GetInstanceField(j--);
896 char rc = doubleField->GetType();
897 if (rc == 'D' || rc == 'J') {
898 pField->Swap(doubleField);
899 c = rc;
900 break;
901 }
902 }
903 } else {
904 // This is a double-wide field, leave it be.
905 }
906
907 pField->SetOffset(fieldOffset);
908 fieldOffset += sizeof(uint32_t);
909 if (c == 'J' || c == 'D')
910 fieldOffset += sizeof(uint32_t);
911 }
912
913#ifndef NDEBUG
914 /* Make sure that all reference fields appear before
915 * non-reference fields, and all double-wide fields are aligned.
916 */
917 j = 0; // seen non-ref
918 for (i = 0; i < klass->NumInstanceFields(); i++) {
919 InstanceField *pField = &klass->ifields[i];
920 char c = pField->GetType();
921
922 if (c == 'D' || c == 'J') {
923 assert((pField->offset_ & 0x07) == 0);
924 }
925
926 if (c != '[' && c != 'L') {
927 if (!j) {
928 assert(i == klass->num_reference_ifields_);
929 j = 1;
930 }
931 } else if (j) {
932 assert(false);
933 }
934 }
935 if (!j) {
936 assert(klass->num_reference_ifields_ == klass->NumInstanceFields());
937 }
938#endif
939
940 klass->object_size_ = fieldOffset;
941 return true;
942}
943
944// Set the bitmap of reference offsets, refOffsets, from the ifields
945// list.
946void ClassLinker::CreateReferenceOffsets(Class* klass) {
947 uint32_t reference_offsets = 0;
948 if (klass->HasSuperClass()) {
949 reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
950 }
951 // If our superclass overflowed, we don't stand a chance.
952 if (reference_offsets != CLASS_WALK_SUPER) {
953 // All of the fields that contain object references are guaranteed
954 // to be at the beginning of the ifields list.
955 for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
956 // Note that, per the comment on struct InstField, f->byteOffset
957 // is the offset from the beginning of obj, not the offset into
958 // obj->instanceData.
959 const InstanceField* field = klass->GetInstanceField(i);
960 size_t byte_offset = field->GetOffset();
961 CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
962 CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0);
963 if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
964 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
965 CHECK_NE(new_bit, 0);
966 reference_offsets |= new_bit;
967 } else {
968 reference_offsets = CLASS_WALK_SUPER;
969 break;
970 }
971 }
972 klass->SetReferenceOffsets(reference_offsets);
973 }
974}
975
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700976Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700977 DexFile* dex_file = referrer->GetDexFile();
978 Class* resolved = dex_file->GetResolvedClass(class_idx);
979 if (resolved != NULL) {
980 return resolved;
981 }
982 const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx);
983 if (descriptor[0] != '\0' && descriptor[1] == '\0') {
Carl Shapiro565f5072011-07-10 13:39:43 -0700984 JType type = static_cast<JType>(descriptor[0]);
985 resolved = FindPrimitiveClass(type);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700986 } else {
987 resolved = FindClass(descriptor, referrer->GetClassLoader(), NULL);
988 }
989 if (resolved != NULL) {
990 Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
991 if (referrer->GetDexFile() != check->GetDexFile()) {
992 if (check->GetClassLoader() != NULL) {
993 LG << "Class resolved by unexpected DEX"; // TODO: IllegalAccessError
994 return NULL;
995 }
996 }
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700997 dex_file->SetResolvedClass(resolved, class_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700998 } else {
999 CHECK(Thread::Self()->IsExceptionPending());
1000 }
1001 return resolved;
1002}
1003
1004Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
1005 /*MethodType*/ int method_type) {
1006 CHECK(false);
1007 return NULL;
1008}
1009
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001010String* ClassLinker::ResolveString(const Class* referring, uint32_t string_idx) {
1011 const RawDexFile* raw = referring->GetDexFile()->GetRaw();
1012 const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
1013 const char* string_data = raw->GetStringData(string_id);
1014 String* new_string = Heap::AllocStringFromModifiedUtf8(string_data);
1015 // TODO: intern the new string
1016 referring->GetDexFile()->SetResolvedString(new_string, string_idx);
1017 return new_string;
1018}
1019
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001020} // namespace art