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