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