blob: 332900bd8a9a91ea211df800238545a3f0bd496e [file] [log] [blame]
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2// Author: cshapiro@google.com (Carl Shapiro)
3
4#include "src/class_linker.h"
5
6#include <vector>
7#include <utility>
8
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07009#include "src/casts.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070010#include "src/dex_verifier.h"
Carl Shapiro5fafe2b2011-07-09 15:34:41 -070011#include "src/heap.h"
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070012#include "src/logging.h"
13#include "src/monitor.h"
14#include "src/object.h"
15#include "src/raw_dex_file.h"
16#include "src/scoped_ptr.h"
17#include "src/thread.h"
18#include "src/utils.h"
19
20namespace art {
21
Carl Shapiro61e019d2011-07-14 16:53:09 -070022ClassLinker* ClassLinker::Create() {
23 scoped_ptr<ClassLinker> class_linker(new ClassLinker);
24 class_linker->Init();
25 // TODO: check for failure during initialization
26 return class_linker.release();
27}
28
Carl Shapiro565f5072011-07-10 13:39:43 -070029void ClassLinker::Init() {
Brian Carlstroma0808032011-07-18 00:39:23 -070030 // Allocate and partially initialize the Class, Object, Field, Method classes.
Brian Carlstrom934486c2011-07-12 23:42:50 -070031 // Initialization will be completed when the definitions are loaded.
Brian Carlstroma0808032011-07-18 00:39:23 -070032 java_lang_Class_ = reinterpret_cast<Class*>(Heap::AllocRaw(sizeof(Class), NULL));
Carl Shapiro565f5072011-07-10 13:39:43 -070033 java_lang_Class_->descriptor_ = "Ljava/lang/Class;";
Brian Carlstroma0808032011-07-18 00:39:23 -070034 java_lang_Class_->object_size_ = sizeof(Class);
35 java_lang_Class_->klass_ = java_lang_Class_;
36
37 java_lang_Object_ = AllocClass(NULL);
38 java_lang_Object_->descriptor_ = "Ljava/lang/Object;";
39
40 java_lang_Class_->super_class_ = java_lang_Object_;
41
42 java_lang_ref_Field_ = AllocClass(NULL);
43 java_lang_ref_Field_->descriptor_ = "Ljava/lang/ref/Field;";
44
45 java_lang_ref_Method_ = AllocClass(NULL);
46 java_lang_ref_Method_->descriptor_ = "Ljava/lang/Method;";
Carl Shapiro565f5072011-07-10 13:39:43 -070047
48 // Allocate and initialize the primitive type classes.
49 primitive_byte_ = CreatePrimitiveClass(kTypeByte, "B");
50 primitive_char_ = CreatePrimitiveClass(kTypeChar, "C");
51 primitive_double_ = CreatePrimitiveClass(kTypeDouble, "D");
52 primitive_float_ = CreatePrimitiveClass(kTypeFloat, "F");
53 primitive_int_ = CreatePrimitiveClass(kTypeInt, "I");
54 primitive_long_ = CreatePrimitiveClass(kTypeLong, "J");
55 primitive_short_ = CreatePrimitiveClass(kTypeShort, "S");
56 primitive_boolean_ = CreatePrimitiveClass(kTypeBoolean, "Z");
57 primitive_void_ = CreatePrimitiveClass(kTypeVoid, "V");
Brian Carlstroma0808032011-07-18 00:39:23 -070058
59 char_array_class_ = AllocClass(NULL);
60 char_array_class_->descriptor_ = "[C";
61 char_array_class_->status_ = Class::kStatusInitialized;
62 char_array_class_->component_type_ = primitive_char_;
63 char_array_class_->array_rank_ = 1;
64 char_array_class_->primitive_type_ = Class::kPrimNot;
65 char_array_class_->super_class_ = java_lang_Object_;
66}
67
68Class* ClassLinker::AllocClass(DexFile* dex_file) {
69 Class* klass = reinterpret_cast<Class*>(Heap::AllocObject(java_lang_Class_));
70 klass->dex_file_ = dex_file;
71 return klass;
72}
73
74StaticField* ClassLinker::AllocStaticField() {
75 return reinterpret_cast<StaticField*>(Heap::AllocRaw(sizeof(StaticField), java_lang_ref_Field_));
76}
77
78InstanceField* ClassLinker::AllocInstanceField() {
79 return reinterpret_cast<InstanceField*>(Heap::AllocRaw(sizeof(InstanceField), java_lang_ref_Field_));
80}
81
82Method* ClassLinker::AllocMethod() {
83 return reinterpret_cast<Method*>(Heap::AllocRaw(sizeof(Method), java_lang_ref_Method_));
Carl Shapiro565f5072011-07-10 13:39:43 -070084}
85
Brian Carlstrom6cc18452011-07-18 15:10:33 -070086Class* ClassLinker::FindClass(const StringPiece& descriptor,
87 Object* class_loader) {
Carl Shapirob5573532011-07-12 18:22:59 -070088 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -070089 CHECK(!self->IsExceptionPending());
90 // Find the class in the loaded classes table.
91 Class* klass = LookupClass(descriptor, class_loader);
92 if (klass == NULL) {
93 // Class is not yet loaded.
Brian Carlstroma0808032011-07-18 00:39:23 -070094 const RawDexFile::ClassDef* class_def;
Brian Carlstrom6cc18452011-07-18 15:10:33 -070095 // No .dex file specified, search the class path.
96 ClassPathEntry pair = FindInClassPath(descriptor);
97 if (pair.first == NULL) {
98 LG << "Class " << descriptor << " really not found";
99 return NULL;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700100 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700101 DexFile* dex_file = pair.first;
102 class_def = pair.second;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700103 // Load the class from the dex file.
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700104 if (descriptor == "Ljava/lang/Object;") {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700105 klass = java_lang_Object_;
106 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700107 klass->object_size_ = sizeof(Object);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700108 char_array_class_->super_class_idx_ = class_def->class_idx_;
109 } else if (descriptor == "Ljava/lang/Class;") {
Carl Shapiro565f5072011-07-10 13:39:43 -0700110 klass = java_lang_Class_;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700111 klass->dex_file_ = dex_file;
Brian Carlstroma0808032011-07-18 00:39:23 -0700112 klass->object_size_ = sizeof(Class);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700113 } else if (descriptor == "Ljava/lang/ref/Field;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700114 klass = java_lang_ref_Field_;
115 klass->dex_file_ = dex_file;
116 klass->object_size_ = sizeof(Field);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700117 } else if (descriptor == "Ljava/lang/ref/Method;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700118 klass = java_lang_ref_Method_;
119 klass->dex_file_ = dex_file;
120 klass->object_size_ = sizeof(Method);
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700121 } else if (descriptor == "Ljava/lang/String;") {
Brian Carlstroma0808032011-07-18 00:39:23 -0700122 klass = java_lang_String_;
123 klass->dex_file_ = dex_file;
124 klass->object_size_ = sizeof(String);
Carl Shapiro565f5072011-07-10 13:39:43 -0700125 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -0700126 klass = AllocClass(dex_file);
Carl Shapiro565f5072011-07-10 13:39:43 -0700127 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700128 bool is_loaded = LoadClass(*class_def, klass);
Carl Shapiro565f5072011-07-10 13:39:43 -0700129 if (!is_loaded) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700130 // TODO: this occurs only when a dex file is provided.
131 LG << "Class not found"; // TODO: NoClassDefFoundError
132 return NULL;
133 }
134 // Check for a pending exception during load
135 if (self->IsExceptionPending()) {
136 // TODO: free native allocations in klass
137 return NULL;
138 }
139 {
140 ObjectLock lock(klass);
Carl Shapirob5573532011-07-12 18:22:59 -0700141 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700142 // Add the newly loaded class to the loaded classes table.
143 bool success = InsertClass(klass);
144 if (!success) {
145 // We may fail to insert if we raced with another thread.
146 klass->clinit_thread_id_ = 0;
147 // TODO: free native allocations in klass
148 klass = LookupClass(descriptor, class_loader);
149 CHECK(klass != NULL);
150 } else {
151 // Link the class.
152 if (!LinkClass(klass)) {
153 // Linking failed.
154 // TODO: CHECK(self->IsExceptionPending());
155 lock.NotifyAll();
156 return NULL;
157 }
158 }
159 }
160 }
161 // Link the class if it has not already been linked.
162 if (!klass->IsLinked() && !klass->IsErroneous()) {
163 ObjectLock lock(klass);
164 // Check for circular dependencies between classes.
Carl Shapirob5573532011-07-12 18:22:59 -0700165 if (!klass->IsLinked() && klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700166 LG << "Recursive link"; // TODO: ClassCircularityError
167 return NULL;
168 }
169 // Wait for the pending initialization to complete.
170 while (!klass->IsLinked() && !klass->IsErroneous()) {
171 lock.Wait();
172 }
173 }
174 if (klass->IsErroneous()) {
175 LG << "EarlierClassFailure"; // TODO: EarlierClassFailure
176 return NULL;
177 }
178 // Return the loaded class. No exceptions should be pending.
179 CHECK(!self->IsExceptionPending());
180 return klass;
181}
182
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700183bool ClassLinker::LoadClass(const StringPiece& descriptor, Class* klass) {
Brian Carlstrom934486c2011-07-12 23:42:50 -0700184 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
185 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
186 if (class_def == NULL) {
187 return false;
188 } else {
189 return LoadClass(*class_def, klass);
190 }
191}
192
193bool ClassLinker::LoadClass(const RawDexFile::ClassDef& class_def, Class* klass) {
194 CHECK(klass != NULL);
195 CHECK(klass->dex_file_ != NULL);
196 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
197 const byte* class_data = raw->GetClassData(class_def);
198 RawDexFile::ClassDataHeader header = raw->ReadClassDataHeader(&class_data);
199
200 const char* descriptor = raw->GetClassDescriptor(class_def);
201 CHECK(descriptor != NULL);
202
203 klass->klass_ = java_lang_Class_;
204 klass->descriptor_.set(descriptor);
205 klass->descriptor_alloc_ = NULL;
206 klass->access_flags_ = class_def.access_flags_;
207 klass->class_loader_ = NULL; // TODO
208 klass->primitive_type_ = Class::kPrimNot;
209 klass->status_ = Class::kStatusIdx;
210
211 klass->super_class_ = NULL;
212 klass->super_class_idx_ = class_def.superclass_idx_;
213
214 klass->num_sfields_ = header.static_fields_size_;
215 klass->num_ifields_ = header.instance_fields_size_;
216 klass->num_direct_methods_ = header.direct_methods_size_;
217 klass->num_virtual_methods_ = header.virtual_methods_size_;
218
219 klass->source_file_ = raw->dexGetSourceFile(class_def);
220
221 // Load class interfaces.
222 LoadInterfaces(class_def, klass);
223
224 // Load static fields.
225 if (klass->num_sfields_ != 0) {
226 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700227 klass->sfields_ = new StaticField*[klass->NumStaticFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700228 uint32_t last_idx = 0;
229 for (size_t i = 0; i < klass->num_sfields_; ++i) {
230 RawDexFile::Field raw_field;
231 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700232 StaticField* sfield = AllocStaticField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700233 klass->sfields_[i] = sfield;
234 LoadField(klass, raw_field, sfield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700235 }
236 }
237
238 // Load instance fields.
239 if (klass->NumInstanceFields() != 0) {
240 // TODO: allocate on the object heap.
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700241 klass->ifields_ = new InstanceField*[klass->NumInstanceFields()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700242 uint32_t last_idx = 0;
243 for (size_t i = 0; i < klass->NumInstanceFields(); ++i) {
244 RawDexFile::Field raw_field;
245 raw->dexReadClassDataField(&class_data, &raw_field, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700246 InstanceField* ifield = AllocInstanceField();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700247 klass->ifields_[i] = ifield;
248 LoadField(klass, raw_field, ifield);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700249 }
250 }
251
252 // Load direct methods.
253 if (klass->NumDirectMethods() != 0) {
254 // TODO: append direct methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700255 klass->direct_methods_ = new Method*[klass->NumDirectMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700256 uint32_t last_idx = 0;
257 for (size_t i = 0; i < klass->NumDirectMethods(); ++i) {
258 RawDexFile::Method raw_method;
259 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700260 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700261 klass->direct_methods_[i] = meth;
262 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700263 // TODO: register maps
264 }
265 }
266
267 // Load virtual methods.
268 if (klass->NumVirtualMethods() != 0) {
269 // TODO: append virtual methods to class object
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700270 klass->virtual_methods_ = new Method*[klass->NumVirtualMethods()]();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700271 uint32_t last_idx = 0;
272 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
273 RawDexFile::Method raw_method;
274 raw->dexReadClassDataMethod(&class_data, &raw_method, &last_idx);
Brian Carlstroma0808032011-07-18 00:39:23 -0700275 Method* meth = AllocMethod();
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700276 klass->virtual_methods_[i] = meth;
277 LoadMethod(klass, raw_method, meth);
Brian Carlstrom934486c2011-07-12 23:42:50 -0700278 // TODO: register maps
279 }
280 }
Brian Carlstroma0808032011-07-18 00:39:23 -0700281 return true;
Brian Carlstrom934486c2011-07-12 23:42:50 -0700282}
283
284void ClassLinker::LoadInterfaces(const RawDexFile::ClassDef& class_def,
285 Class* klass) {
286 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
287 const RawDexFile::TypeList* list = raw->GetInterfacesList(class_def);
288 if (list != NULL) {
289 klass->interface_count_ = list->Size();
290 // TODO: allocate the interfaces array on the object heap.
291 klass->interfaces_ = new Class*[list->Size()]();
292 for (size_t i = 0; i < list->Size(); ++i) {
293 const RawDexFile::TypeItem& type_item = list->GetTypeItem(i);
294 klass->interfaces_[i] = reinterpret_cast<Class*>(type_item.type_idx_);
295 }
296 }
297}
298
299void ClassLinker::LoadField(Class* klass, const RawDexFile::Field& src,
300 Field* dst) {
301 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
302 const RawDexFile::FieldId& field_id = raw->GetFieldId(src.field_idx_);
303 dst->klass_ = klass;
304 dst->name_ = raw->dexStringById(field_id.name_idx_);
305 dst->signature_ = raw->dexStringByTypeIdx(field_id.type_idx_);
306 dst->access_flags_ = src.access_flags_;
307}
308
309void ClassLinker::LoadMethod(Class* klass, const RawDexFile::Method& src,
310 Method* dst) {
311 const RawDexFile* raw = klass->GetDexFile()->GetRaw();
312 const RawDexFile::MethodId& method_id = raw->GetMethodId(src.method_idx_);
313 dst->klass_ = klass;
314 dst->name_.set(raw->dexStringById(method_id.name_idx_));
315 dst->proto_idx_ = method_id.proto_idx_;
316 dst->shorty_.set(raw->GetShorty(method_id.proto_idx_));
317 dst->access_flags_ = src.access_flags_;
318
319 // TODO: check for finalize method
320
321 const RawDexFile::CodeItem* code_item = raw->GetCodeItem(src);
322 if (code_item != NULL) {
323 dst->num_registers_ = code_item->registers_size_;
324 dst->num_ins_ = code_item->ins_size_;
325 dst->num_outs_ = code_item->outs_size_;
326 dst->insns_ = code_item->insns_;
327 } else {
328 uint16_t num_args = dst->NumArgRegisters();
329 if (!dst->IsStatic()) {
330 ++num_args;
331 }
332 dst->num_registers_ = dst->num_ins_ + num_args;
333 // TODO: native methods
334 }
335}
336
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700337ClassLinker::ClassPathEntry ClassLinker::FindInClassPath(const StringPiece& descriptor) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700338 for (size_t i = 0; i != class_path_.size(); ++i) {
339 DexFile* dex_file = class_path_[i];
Brian Carlstroma0808032011-07-18 00:39:23 -0700340 const RawDexFile::ClassDef* class_def = dex_file->GetRaw()->FindClassDef(descriptor);
341 if (class_def != NULL) {
342 return ClassPathEntry(dex_file, class_def);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700343 }
344 }
Brian Carlstroma0808032011-07-18 00:39:23 -0700345 return ClassPathEntry(NULL, NULL);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700346}
347
348void ClassLinker::AppendToClassPath(DexFile* dex_file) {
349 class_path_.push_back(dex_file);
350}
351
Carl Shapiro565f5072011-07-10 13:39:43 -0700352Class* ClassLinker::CreatePrimitiveClass(JType type, const char* descriptor) {
Brian Carlstroma0808032011-07-18 00:39:23 -0700353 Class* klass = AllocClass(NULL);
Carl Shapiro565f5072011-07-10 13:39:43 -0700354 CHECK(klass != NULL);
Brian Carlstroma0808032011-07-18 00:39:23 -0700355 klass->super_class_ = NULL;
Carl Shapiro565f5072011-07-10 13:39:43 -0700356 klass->access_flags_ = kAccPublic | kAccFinal | kAccAbstract;
357 klass->descriptor_ = descriptor;
358 klass->status_ = Class::kStatusInitialized;
359 return klass;
360}
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700361
Carl Shapiro565f5072011-07-10 13:39:43 -0700362Class* ClassLinker::FindPrimitiveClass(JType type) {
363 switch (type) {
364 case kTypeByte:
365 CHECK(primitive_byte_ != NULL);
366 return primitive_byte_;
367 case kTypeChar:
368 CHECK(primitive_char_ != NULL);
369 return primitive_char_;
370 case kTypeDouble:
371 CHECK(primitive_double_ != NULL);
372 return primitive_double_;
373 case kTypeFloat:
374 CHECK(primitive_float_ != NULL);
375 return primitive_float_;
376 case kTypeInt:
377 CHECK(primitive_int_ != NULL);
378 return primitive_int_;
379 case kTypeLong:
380 CHECK(primitive_long_ != NULL);
381 return primitive_long_;
382 case kTypeShort:
383 CHECK(primitive_short_ != NULL);
384 return primitive_short_;
385 case kTypeBoolean:
386 CHECK(primitive_boolean_ != NULL);
387 return primitive_boolean_;
388 case kTypeVoid:
389 CHECK(primitive_void_ != NULL);
390 return primitive_void_;
391 default:
392 LOG(FATAL) << "Unknown primitive type " << static_cast<int>(type);
393 };
394 return NULL; // Not reachable.
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700395}
396
397bool ClassLinker::InsertClass(Class* klass) {
398 // TODO: acquire classes_lock_
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700399 const StringPiece& key = klass->GetDescriptor();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700400 bool success = classes_.insert(std::make_pair(key, klass)).second;
401 // TODO: release classes_lock_
402 return success;
403}
404
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700405Class* ClassLinker::LookupClass(const StringPiece& descriptor, Object* class_loader) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700406 // TODO: acquire classes_lock_
407 Table::iterator it = classes_.find(descriptor);
408 // TODO: release classes_lock_
409 if (it == classes_.end()) {
410 return NULL;
411 } else {
412 return (*it).second;
413 }
414}
415
416bool ClassLinker::InitializeClass(Class* klass) {
417 CHECK(klass->GetStatus() == Class::kStatusResolved ||
418 klass->GetStatus() == Class::kStatusError);
419
Carl Shapirob5573532011-07-12 18:22:59 -0700420 Thread* self = Thread::Current();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700421
422 {
423 ObjectLock lock(klass);
424
425 if (klass->GetStatus() < Class::kStatusVerified) {
426 if (klass->IsErroneous()) {
427 LG << "re-initializing failed class"; // TODO: throw
428 return false;
429 }
430
431 CHECK(klass->GetStatus() == Class::kStatusResolved);
432
433 klass->status_ = Class::kStatusVerifying;
434 if (!DexVerify::VerifyClass(klass)) {
435 LG << "Verification failed"; // TODO: ThrowVerifyError
436 Object* exception = self->GetException();
437 klass->SetObjectAt(OFFSETOF_MEMBER(Class, verify_error_class_),
438 exception->GetClass());
439 klass->SetStatus(Class::kStatusError);
440 return false;
441 }
442
443 klass->SetStatus(Class::kStatusVerified);
444 }
445
446 if (klass->status_ == Class::kStatusInitialized) {
447 return true;
448 }
449
450 while (klass->status_ == Class::kStatusInitializing) {
451 // we caught somebody else in the act; was it us?
Carl Shapirob5573532011-07-12 18:22:59 -0700452 if (klass->clinit_thread_id_ == self->GetId()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700453 LG << "recursive <clinit>";
454 return true;
455 }
456
457 CHECK(!self->IsExceptionPending());
458
459 lock.Wait(); // TODO: check for interruption
460
461 // When we wake up, repeat the test for init-in-progress. If
462 // there's an exception pending (only possible if
463 // "interruptShouldThrow" was set), bail out.
464 if (self->IsExceptionPending()) {
465 CHECK(false);
466 LG << "Exception in initialization."; // TODO: ExceptionInInitializerError
467 klass->SetStatus(Class::kStatusError);
468 return false;
469 }
470 if (klass->GetStatus() == Class::kStatusInitializing) {
471 continue;
472 }
473 assert(klass->GetStatus() == Class::kStatusInitialized ||
474 klass->GetStatus() == Class::kStatusError);
475 if (klass->IsErroneous()) {
476 /*
477 * The caller wants an exception, but it was thrown in a
478 * different thread. Synthesize one here.
479 */
480 LG << "<clinit> failed"; // TODO: throw UnsatisfiedLinkError
481 return false;
482 }
483 return true; // otherwise, initialized
484 }
485
486 // see if we failed previously
487 if (klass->IsErroneous()) {
488 // might be wise to unlock before throwing; depends on which class
489 // it is that we have locked
490
491 // TODO: throwEarlierClassFailure(klass);
492 return false;
493 }
494
495 if (!ValidateSuperClassDescriptors(klass)) {
496 klass->SetStatus(Class::kStatusError);
497 return false;
498 }
499
500 assert(klass->status < CLASS_INITIALIZING);
501
Carl Shapirob5573532011-07-12 18:22:59 -0700502 klass->clinit_thread_id_ = self->GetId();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700503 klass->status_ = Class::kStatusInitializing;
504 }
505
506 if (!InitializeSuperClass(klass)) {
507 return false;
508 }
509
510 InitializeStaticFields(klass);
511
512 Method* clinit = klass->FindDirectMethodLocally("<clinit>", "()V");
513 if (clinit != NULL) {
514 } else {
515 // JValue unused;
516 // TODO: dvmCallMethod(self, method, NULL, &unused);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700517 //CHECK(!"unimplemented");
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700518 }
519
520 {
521 ObjectLock lock(klass);
522
523 if (self->IsExceptionPending()) {
524 klass->SetStatus(Class::kStatusError);
525 } else {
526 klass->SetStatus(Class::kStatusInitialized);
527 }
528 lock.NotifyAll();
529 }
530
531 return true;
532}
533
534bool ClassLinker::ValidateSuperClassDescriptors(const Class* klass) {
535 if (klass->IsInterface()) {
536 return true;
537 }
538 // begin with the methods local to the superclass
539 if (klass->HasSuperClass() &&
540 klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
541 const Class* super = klass->GetSuperClass();
542 for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
543 const Method* method = klass->GetVirtualMethod(i);
544 if (method != super->GetVirtualMethod(i) &&
545 !HasSameMethodDescriptorClasses(method, super, klass)) {
546 LG << "Classes resolve differently in superclass";
547 return false;
548 }
549 }
550 }
551 for (size_t i = 0; i < klass->iftable_count_; ++i) {
552 const InterfaceEntry* iftable = &klass->iftable_[i];
553 Class* interface = iftable->GetClass();
554 if (klass->GetClassLoader() != interface->GetClassLoader()) {
555 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
556 uint32_t vtable_index = iftable->method_index_array_[j];
557 const Method* method = klass->GetVirtualMethod(vtable_index);
558 if (!HasSameMethodDescriptorClasses(method, interface,
559 method->GetClass())) {
560 LG << "Classes resolve differently in interface"; // TODO: LinkageError
561 return false;
562 }
563 }
564 }
565 }
566 return true;
567}
568
569bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700570 const Class* klass1,
571 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700572 const RawDexFile* raw = method->GetClass()->GetDexFile()->GetRaw();
573 const RawDexFile::ProtoId& proto_id = raw->GetProtoId(method->proto_idx_);
574 RawDexFile::ParameterIterator *it;
575 for (it = raw->GetParameterIterator(proto_id); it->HasNext(); it->Next()) {
576 const char* descriptor = it->GetDescriptor();
577 if (descriptor == NULL) {
578 break;
579 }
580 if (descriptor[0] == 'L' || descriptor[0] == '[') {
581 // Found a non-primitive type.
582 if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
583 return false;
584 }
585 }
586 }
587 // Check the return type
588 const char* descriptor = raw->GetReturnTypeDescriptor(proto_id);
589 if (descriptor[0] == 'L' || descriptor[0] == '[') {
590 if (HasSameDescriptorClasses(descriptor, klass1, klass2)) {
591 return false;
592 }
593 }
594 return true;
595}
596
597// Returns true if classes referenced by the descriptor are the
598// same classes in klass1 as they are in klass2.
599bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
Brian Carlstrom934486c2011-07-12 23:42:50 -0700600 const Class* klass1,
601 const Class* klass2) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700602 CHECK(descriptor != NULL);
603 CHECK(klass1 != NULL);
604 CHECK(klass2 != NULL);
605#if 0
606 Class* found1 = FindClassNoInit(descriptor, klass1->GetClassLoader());
607 // TODO: found1 == NULL
608 Class* found2 = FindClassNoInit(descriptor, klass2->GetClassLoader());
609 // TODO: found2 == NULL
610 // TODO: lookup found1 in initiating loader list
611 if (found1 == NULL || found2 == NULL) {
Carl Shapirob5573532011-07-12 18:22:59 -0700612 Thread::Current()->ClearException();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700613 if (found1 == found2) {
614 return true;
615 } else {
616 return false;
617 }
618 }
619#endif
620 return true;
621}
622
623bool ClassLinker::InitializeSuperClass(Class* klass) {
624 CHECK(klass != NULL);
625 // TODO: assert klass lock is acquired
626 if (!klass->IsInterface() && klass->HasSuperClass()) {
627 Class* super_class = klass->GetSuperClass();
628 if (super_class->GetStatus() != Class::kStatusInitialized) {
629 CHECK(!super_class->IsInterface());
630 klass->MonitorExit();
631 bool super_initialized = InitializeClass(super_class);
632 klass->MonitorEnter();
633 // TODO: check for a pending exception
634 if (!super_initialized) {
635 klass->SetStatus(Class::kStatusError);
636 klass->NotifyAll();
637 return false;
638 }
639 }
640 }
641 return true;
642}
643
644void ClassLinker::InitializeStaticFields(Class* klass) {
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700645 size_t num_static_fields = klass->NumStaticFields();
646 if (num_static_fields == 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700647 return;
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700648 }
649 DexFile* dex_file = klass->GetDexFile();
650 if (dex_file == NULL) {
651 return;
652 }
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700653 const StringPiece& descriptor = klass->GetDescriptor();
Brian Carlstrom934486c2011-07-12 23:42:50 -0700654 const RawDexFile* raw = dex_file->GetRaw();
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700655 const RawDexFile::ClassDef* class_def = raw->FindClassDef(descriptor);
656 CHECK(class_def != NULL);
657 const byte* addr = raw->GetEncodedArray(*class_def);
658 size_t array_size = DecodeUnsignedLeb128(&addr);
659 for (size_t i = 0; i < array_size; ++i) {
660 StaticField* field = klass->GetStaticField(i);
661 JValue value;
662 RawDexFile::ValueType type = raw->ReadEncodedValue(&addr, &value);
663 switch (type) {
664 case RawDexFile::kByte:
665 field->SetByte(value.b);
666 break;
667 case RawDexFile::kShort:
668 field->SetShort(value.s);
669 break;
670 case RawDexFile::kChar:
671 field->SetChar(value.c);
672 break;
673 case RawDexFile::kInt:
674 field->SetInt(value.i);
675 break;
676 case RawDexFile::kLong:
677 field->SetLong(value.j);
678 break;
679 case RawDexFile::kFloat:
680 field->SetFloat(value.f);
681 break;
682 case RawDexFile::kDouble:
683 field->SetDouble(value.d);
684 break;
685 case RawDexFile::kString: {
686 uint32_t string_idx = value.i;
687 String* resolved = ResolveString(klass, string_idx);
688 field->SetObject(resolved);
689 break;
690 }
691 case RawDexFile::kBoolean:
692 field->SetBoolean(value.z);
693 break;
694 case RawDexFile::kNull:
695 field->SetObject(value.l);
696 break;
697 default:
Carl Shapiro606258b2011-07-09 16:09:09 -0700698 LOG(FATAL) << "Unknown type " << static_cast<int>(type);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -0700699 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700700 }
701}
702
703bool ClassLinker::LinkClass(Class* klass) {
704 CHECK(klass->status_ == Class::kStatusIdx ||
705 klass->status_ == Class::kStatusLoaded);
706 if (klass->status_ == Class::kStatusIdx) {
707 if (!LinkInterfaces(klass)) {
708 return false;
709 }
710 }
711 if (!LinkSuperClass(klass)) {
712 return false;
713 }
714 if (!LinkMethods(klass)) {
715 return false;
716 }
717 if (!LinkInstanceFields(klass)) {
718 return false;
719 }
720 CreateReferenceOffsets(klass);
721 CHECK_EQ(klass->status_, Class::kStatusLoaded);
722 klass->status_ = Class::kStatusResolved;
723 return true;
724}
725
726bool ClassLinker::LinkInterfaces(Class* klass) {
727 scoped_array<uint32_t> interfaces_idx;
728 // TODO: store interfaces_idx in the Class object
729 // TODO: move this outside of link interfaces
730 if (klass->interface_count_ > 0) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700731 size_t length = klass->interface_count_ * sizeof(klass->interfaces_[0]);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700732 interfaces_idx.reset(new uint32_t[klass->interface_count_]);
Carl Shapiro565f5072011-07-10 13:39:43 -0700733 memcpy(interfaces_idx.get(), klass->interfaces_, length);
734 memset(klass->interfaces_, 0xFF, length);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700735 }
736 // Mark the class as loaded.
737 klass->status_ = Class::kStatusLoaded;
738 if (klass->super_class_idx_ != RawDexFile::kDexNoIndex) {
739 Class* super_class = ResolveClass(klass, klass->super_class_idx_);
740 if (super_class == NULL) {
741 LG << "Failed to resolve superclass";
742 return false;
743 }
744 klass->super_class_ = super_class; // TODO: write barrier
745 }
746 if (klass->interface_count_ > 0) {
747 for (size_t i = 0; i < klass->interface_count_; ++i) {
748 uint32_t idx = interfaces_idx[i];
749 klass->interfaces_[i] = ResolveClass(klass, idx);
750 if (klass->interfaces_[i] == NULL) {
751 LG << "Failed to resolve interface";
752 return false;
753 }
754 // Verify
755 if (!klass->CanAccess(klass->interfaces_[i])) {
756 LG << "Inaccessible interface";
757 return false;
758 }
759 }
760 }
761 return true;
762}
763
764bool ClassLinker::LinkSuperClass(Class* klass) {
765 CHECK(!klass->IsPrimitive());
766 const Class* super = klass->GetSuperClass();
767 if (klass->GetDescriptor() == "Ljava/lang/Object;") {
768 if (super != NULL) {
769 LG << "Superclass must not be defined"; // TODO: ClassFormatError
770 return false;
771 }
772 // TODO: clear finalize attribute
773 return true;
774 }
775 if (super == NULL) {
776 LG << "No superclass defined"; // TODO: LinkageError
777 return false;
778 }
779 // Verify
780 if (super->IsFinal()) {
781 LG << "Superclass is declared final"; // TODO: IncompatibleClassChangeError
782 return false;
783 }
784 if (super->IsInterface()) {
785 LG << "Superclass is an interface"; // TODO: IncompatibleClassChangeError
786 return false;
787 }
788 if (!klass->CanAccess(super)) {
789 LG << "Superclass is inaccessible"; // TODO: IllegalAccessError
790 return false;
791 }
792 return true;
793}
794
795// Populate the class vtable and itable.
796bool ClassLinker::LinkMethods(Class* klass) {
797 if (klass->IsInterface()) {
798 // No vtable.
799 size_t count = klass->NumVirtualMethods();
800 if (!IsUint(16, count)) {
801 LG << "Too many methods on interface"; // TODO: VirtualMachineError
802 return false;
803 }
Carl Shapiro565f5072011-07-10 13:39:43 -0700804 for (size_t i = 0; i < count; ++i) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700805 klass->GetVirtualMethod(i)->method_index_ = i;
806 }
807 } else {
808 // Link virtual method tables
809 LinkVirtualMethods(klass);
810
811 // Link interface method tables
812 LinkInterfaceMethods(klass);
813
814 // Insert stubs.
815 LinkAbstractMethods(klass);
816 }
817 return true;
818}
819
820bool ClassLinker::LinkVirtualMethods(Class* klass) {
821 uint32_t max_count = klass->NumVirtualMethods();
822 if (klass->GetSuperClass() != NULL) {
823 max_count += klass->GetSuperClass()->NumVirtualMethods();
824 } else {
825 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
826 }
827 // TODO: do not assign to the vtable field until it is fully constructed.
828 // TODO: make this a vector<Method*> instead?
829 klass->vtable_ = new Method*[max_count];
830 if (klass->HasSuperClass()) {
831 memcpy(klass->vtable_,
832 klass->GetSuperClass()->vtable_,
833 klass->GetSuperClass()->vtable_count_ * sizeof(Method*));
834 size_t actual_count = klass->GetSuperClass()->vtable_count_;
835 // See if any of our virtual methods override the superclass.
836 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
837 Method* local_method = klass->GetVirtualMethod(i);
838 size_t j = 0;
839 for (; j < klass->GetSuperClass()->vtable_count_; ++j) {
840 const Method* super_method = klass->vtable_[j];
841 if (local_method->HasSameNameAndPrototype(super_method)) {
842 // Verify
843 if (super_method->IsFinal()) {
844 LG << "Method overrides final method"; // TODO: VirtualMachineError
845 return false;
846 }
847 klass->vtable_[j] = local_method;
848 local_method->method_index_ = j;
849 break;
850 }
851 }
852 if (j == klass->GetSuperClass()->vtable_count_) {
853 // Not overriding, append.
854 klass->vtable_[actual_count] = local_method;
855 local_method->method_index_ = actual_count;
856 actual_count += 1;
857 }
858 }
859 if (!IsUint(16, actual_count)) {
860 LG << "Too many methods defined on class"; // TODO: VirtualMachineError
861 return false;
862 }
863 CHECK_LE(actual_count, max_count);
864 if (actual_count < max_count) {
865 Method** new_vtable = new Method*[actual_count];
866 memcpy(new_vtable, klass->vtable_, actual_count * sizeof(Method*));
Carl Shapiro565f5072011-07-10 13:39:43 -0700867 delete[] klass->vtable_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700868 klass->vtable_ = new_vtable;
869 LG << "shrunk vtable: "
870 << "was " << max_count << ", "
871 << "now " << actual_count;
872 }
873 klass->vtable_count_ = actual_count;
874 } else {
875 CHECK(klass->GetDescriptor() == "Ljava/lang/Object;");
876 if (!IsUint(16, klass->NumVirtualMethods())) {
877 LG << "Too many methods"; // TODO: VirtualMachineError
878 return false;
879 }
880 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
881 klass->vtable_[i] = klass->GetVirtualMethod(i);
882 klass->GetVirtualMethod(i)->method_index_ = i & 0xFFFF;
883 }
884 klass->vtable_count_ = klass->NumVirtualMethods();
885 }
886 return true;
887}
888
889bool ClassLinker::LinkInterfaceMethods(Class* klass) {
890 int pool_offset = 0;
891 int pool_size = 0;
892 int miranda_count = 0;
893 int miranda_alloc = 0;
894 size_t super_ifcount;
895 if (klass->HasSuperClass()) {
896 super_ifcount = klass->GetSuperClass()->iftable_count_;
897 } else {
898 super_ifcount = 0;
899 }
900 size_t ifCount = super_ifcount;
901 ifCount += klass->interface_count_;
902 for (size_t i = 0; i < klass->interface_count_; i++) {
903 ifCount += klass->interfaces_[i]->iftable_count_;
904 }
905 if (ifCount == 0) {
906 assert(klass->iftable_count_ == 0);
907 assert(klass->iftable == NULL);
908 return true;
909 }
910 klass->iftable_ = new InterfaceEntry[ifCount * sizeof(InterfaceEntry)];
911 memset(klass->iftable_, 0x00, sizeof(InterfaceEntry) * ifCount);
912 if (super_ifcount != 0) {
913 memcpy(klass->iftable_, klass->GetSuperClass()->iftable_,
914 sizeof(InterfaceEntry) * super_ifcount);
915 }
916 // Flatten the interface inheritance hierarchy.
917 size_t idx = super_ifcount;
918 for (size_t i = 0; i < klass->interface_count_; i++) {
919 Class* interf = klass->interfaces_[i];
920 assert(interf != NULL);
921 if (!interf->IsInterface()) {
922 LG << "Class implements non-interface class"; // TODO: IncompatibleClassChangeError
923 return false;
924 }
925 klass->iftable_[idx++].SetClass(interf);
926 for (size_t j = 0; j < interf->iftable_count_; j++) {
927 klass->iftable_[idx++].SetClass(interf->iftable_[j].GetClass());
928 }
929 }
930 CHECK_EQ(idx, ifCount);
931 klass->iftable_count_ = ifCount;
932 if (klass->IsInterface() || super_ifcount == ifCount) {
933 return true;
934 }
935 for (size_t i = super_ifcount; i < ifCount; i++) {
936 pool_size += klass->iftable_[i].GetClass()->NumVirtualMethods();
937 }
938 if (pool_size == 0) {
939 return true;
940 }
941 klass->ifvi_pool_count_ = pool_size;
942 klass->ifvi_pool_ = new uint32_t[pool_size];
943 std::vector<Method*> miranda_list;
944 for (size_t i = super_ifcount; i < ifCount; ++i) {
945 klass->iftable_[i].method_index_array_ = klass->ifvi_pool_ + pool_offset;
946 Class* interface = klass->iftable_[i].GetClass();
947 pool_offset += interface->NumVirtualMethods(); // end here
948 for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
949 Method* interface_method = interface->GetVirtualMethod(j);
950 int k; // must be signed
951 for (k = klass->vtable_count_ - 1; k >= 0; --k) {
952 if (interface_method->HasSameNameAndPrototype(klass->vtable_[k])) {
Carl Shapiro565f5072011-07-10 13:39:43 -0700953 if (!klass->vtable_[k]->IsPublic()) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700954 LG << "Implementation not public";
955 return false;
956 }
957 klass->iftable_[i].method_index_array_[j] = k;
958 break;
959 }
960 }
961 if (k < 0) {
962 if (miranda_count == miranda_alloc) {
963 miranda_alloc += 8;
964 if (miranda_list.empty()) {
965 miranda_list.resize(miranda_alloc);
966 } else {
967 miranda_list.resize(miranda_alloc);
968 }
969 }
970 int mir;
971 for (mir = 0; mir < miranda_count; mir++) {
972 if (miranda_list[mir]->HasSameNameAndPrototype(interface_method)) {
973 break;
974 }
975 }
976 // point the interface table at a phantom slot index
977 klass->iftable_[i].method_index_array_[j] = klass->vtable_count_ + mir;
978 if (mir == miranda_count) {
979 miranda_list[miranda_count++] = interface_method;
980 }
981 }
982 }
983 }
984 if (miranda_count != 0) {
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700985 int oldMethodCount = klass->NumVirtualMethods();
986 int newMethodCount = oldMethodCount + miranda_count;
987 Method** newVirtualMethods = new Method*[newMethodCount];
988 if (klass->virtual_methods_ != NULL) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700989 memcpy(newVirtualMethods,
990 klass->virtual_methods_,
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700991 klass->NumVirtualMethods() * sizeof(Method*));
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700992 }
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700993 klass->virtual_methods_ = newVirtualMethods;
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700994 klass->num_virtual_methods_ = newMethodCount;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700995
996 CHECK(klass->vtable_ != NULL);
Brian Carlstroma7f4f482011-07-17 17:01:34 -0700997 int oldVtableCount = klass->vtable_count_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700998 klass->vtable_count_ += miranda_count;
999
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001000 for (int i = 0; i < miranda_count; i++) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001001 Method* meth = AllocMethod();
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001002 memcpy(meth, miranda_list[i], sizeof(Method));
1003 meth->klass_ = klass;
1004 meth->access_flags_ |= kAccMiranda;
1005 meth->method_index_ = 0xFFFF & (oldVtableCount + i);
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001006 klass->virtual_methods_[oldMethodCount+i] = meth;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001007 klass->vtable_[oldVtableCount + i] = meth;
1008 }
1009 }
1010 return true;
1011}
1012
1013void ClassLinker::LinkAbstractMethods(Class* klass) {
1014 for (size_t i = 0; i < klass->NumVirtualMethods(); ++i) {
1015 Method* method = klass->GetVirtualMethod(i);
1016 if (method->IsAbstract()) {
1017 method->insns_ = reinterpret_cast<uint16_t*>(0xFFFFFFFF); // TODO: AbstractMethodError
1018 }
1019 }
1020}
1021
1022bool ClassLinker::LinkInstanceFields(Class* klass) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001023 int field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001024 if (klass->GetSuperClass() != NULL) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001025 field_offset = klass->GetSuperClass()->object_size_;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001026 } else {
Brian Carlstroma0808032011-07-18 00:39:23 -07001027 field_offset = OFFSETOF_MEMBER(DataObject, fields_);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001028 }
1029 // Move references to the front.
1030 klass->num_reference_ifields_ = 0;
1031 size_t i = 0;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001032 for ( ; i < klass->NumInstanceFields(); i++) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001033 InstanceField* pField = klass->GetInstanceField(i);
1034 char c = pField->GetType();
1035
1036 if (c != '[' && c != 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001037 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1038 InstanceField* refField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001039 char rc = refField->GetType();
1040 if (rc == '[' || rc == 'L') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001041 klass->SetInstanceField(i, refField);
1042 klass->SetInstanceField(j, pField);
1043 pField = refField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001044 c = rc;
1045 klass->num_reference_ifields_++;
1046 break;
1047 }
1048 }
1049 } else {
1050 klass->num_reference_ifields_++;
1051 }
1052 if (c != '[' && c != 'L') {
1053 break;
1054 }
Brian Carlstroma0808032011-07-18 00:39:23 -07001055 pField->SetOffset(field_offset);
1056 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001057 }
1058
1059 // Now we want to pack all of the double-wide fields together. If
1060 // we're not aligned, though, we want to shuffle one 32-bit field
1061 // into place. If we can't find one, we'll have to pad it.
Brian Carlstroma0808032011-07-18 00:39:23 -07001062 if (i != klass->NumInstanceFields() && (field_offset & 0x04) != 0) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001063 InstanceField* pField = klass->GetInstanceField(i);
1064 char c = pField->GetType();
1065
1066 if (c != 'J' && c != 'D') {
1067 // The field that comes next is 32-bit, so just advance past it.
1068 assert(c != '[' && c != 'L');
Brian Carlstroma0808032011-07-18 00:39:23 -07001069 pField->SetOffset(field_offset);
1070 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001071 i++;
1072 } else {
1073 // Next field is 64-bit, so search for a 32-bit field we can
1074 // swap into it.
1075 bool found = false;
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001076 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1077 InstanceField* singleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001078 char rc = singleField->GetType();
1079 if (rc != 'J' && rc != 'D') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001080 klass->SetInstanceField(i, singleField);
1081 klass->SetInstanceField(j, pField);
1082 pField = singleField;
Brian Carlstroma0808032011-07-18 00:39:23 -07001083 pField->SetOffset(field_offset);
1084 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001085 found = true;
1086 i++;
1087 break;
1088 }
1089 }
1090 if (!found) {
Brian Carlstroma0808032011-07-18 00:39:23 -07001091 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001092 }
1093 }
1094 }
1095
1096 // Alignment is good, shuffle any double-wide fields forward, and
1097 // finish assigning field offsets to all fields.
Brian Carlstroma0808032011-07-18 00:39:23 -07001098 assert(i == klass->NumInstanceFields() || (field_offset & 0x04) == 0);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001099 for ( ; i < klass->NumInstanceFields(); i++) {
1100 InstanceField* pField = klass->GetInstanceField(i);
1101 char c = pField->GetType();
1102 if (c != 'D' && c != 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001103 for (size_t j = klass->NumInstanceFields() - 1; j > i; j--) {
1104 InstanceField* doubleField = klass->GetInstanceField(j);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001105 char rc = doubleField->GetType();
1106 if (rc == 'D' || rc == 'J') {
Brian Carlstroma7f4f482011-07-17 17:01:34 -07001107 klass->SetInstanceField(i, doubleField);
1108 klass->SetInstanceField(j, pField);
1109 pField = doubleField;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001110 c = rc;
1111 break;
1112 }
1113 }
1114 } else {
1115 // This is a double-wide field, leave it be.
1116 }
1117
Brian Carlstroma0808032011-07-18 00:39:23 -07001118 pField->SetOffset(field_offset);
1119 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001120 if (c == 'J' || c == 'D')
Brian Carlstroma0808032011-07-18 00:39:23 -07001121 field_offset += sizeof(uint32_t);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001122 }
1123
1124#ifndef NDEBUG
1125 /* Make sure that all reference fields appear before
1126 * non-reference fields, and all double-wide fields are aligned.
1127 */
1128 j = 0; // seen non-ref
1129 for (i = 0; i < klass->NumInstanceFields(); i++) {
1130 InstanceField *pField = &klass->ifields[i];
1131 char c = pField->GetType();
1132
1133 if (c == 'D' || c == 'J') {
1134 assert((pField->offset_ & 0x07) == 0);
1135 }
1136
1137 if (c != '[' && c != 'L') {
1138 if (!j) {
1139 assert(i == klass->num_reference_ifields_);
1140 j = 1;
1141 }
1142 } else if (j) {
1143 assert(false);
1144 }
1145 }
1146 if (!j) {
1147 assert(klass->num_reference_ifields_ == klass->NumInstanceFields());
1148 }
1149#endif
1150
Brian Carlstroma0808032011-07-18 00:39:23 -07001151 klass->object_size_ = field_offset;
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001152 return true;
1153}
1154
1155// Set the bitmap of reference offsets, refOffsets, from the ifields
1156// list.
1157void ClassLinker::CreateReferenceOffsets(Class* klass) {
1158 uint32_t reference_offsets = 0;
1159 if (klass->HasSuperClass()) {
1160 reference_offsets = klass->GetSuperClass()->GetReferenceOffsets();
1161 }
1162 // If our superclass overflowed, we don't stand a chance.
1163 if (reference_offsets != CLASS_WALK_SUPER) {
1164 // All of the fields that contain object references are guaranteed
1165 // to be at the beginning of the ifields list.
1166 for (size_t i = 0; i < klass->NumReferenceInstanceFields(); ++i) {
1167 // Note that, per the comment on struct InstField, f->byteOffset
1168 // is the offset from the beginning of obj, not the offset into
1169 // obj->instanceData.
1170 const InstanceField* field = klass->GetInstanceField(i);
1171 size_t byte_offset = field->GetOffset();
1172 CHECK_GE(byte_offset, CLASS_SMALLEST_OFFSET);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001173 CHECK_EQ(byte_offset & (CLASS_OFFSET_ALIGNMENT - 1), 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001174 if (CLASS_CAN_ENCODE_OFFSET(byte_offset)) {
1175 uint32_t new_bit = CLASS_BIT_FROM_OFFSET(byte_offset);
Elliott Hughes1f359b02011-07-17 14:27:17 -07001176 CHECK_NE(new_bit, 0U);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001177 reference_offsets |= new_bit;
1178 } else {
1179 reference_offsets = CLASS_WALK_SUPER;
1180 break;
1181 }
1182 }
1183 klass->SetReferenceOffsets(reference_offsets);
1184 }
1185}
1186
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001187Class* ClassLinker::ResolveClass(const Class* referrer, uint32_t class_idx) {
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001188 DexFile* dex_file = referrer->GetDexFile();
1189 Class* resolved = dex_file->GetResolvedClass(class_idx);
1190 if (resolved != NULL) {
1191 return resolved;
1192 }
1193 const char* descriptor = dex_file->GetRaw()->dexStringByTypeIdx(class_idx);
1194 if (descriptor[0] != '\0' && descriptor[1] == '\0') {
Carl Shapiro565f5072011-07-10 13:39:43 -07001195 JType type = static_cast<JType>(descriptor[0]);
1196 resolved = FindPrimitiveClass(type);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001197 } else {
Brian Carlstrom6cc18452011-07-18 15:10:33 -07001198 resolved = FindClass(descriptor, referrer->GetClassLoader());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001199 }
1200 if (resolved != NULL) {
1201 Class* check = resolved->IsArray() ? resolved->component_type_ : resolved;
1202 if (referrer->GetDexFile() != check->GetDexFile()) {
1203 if (check->GetClassLoader() != NULL) {
1204 LG << "Class resolved by unexpected DEX"; // TODO: IllegalAccessError
1205 return NULL;
1206 }
1207 }
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001208 dex_file->SetResolvedClass(resolved, class_idx);
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001209 } else {
Carl Shapirob5573532011-07-12 18:22:59 -07001210 CHECK(Thread::Current()->IsExceptionPending());
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001211 }
1212 return resolved;
1213}
1214
1215Method* ResolveMethod(const Class* referrer, uint32_t method_idx,
1216 /*MethodType*/ int method_type) {
1217 CHECK(false);
1218 return NULL;
1219}
1220
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001221String* ClassLinker::ResolveString(const Class* referring, uint32_t string_idx) {
1222 const RawDexFile* raw = referring->GetDexFile()->GetRaw();
1223 const RawDexFile::StringId& string_id = raw->GetStringId(string_idx);
1224 const char* string_data = raw->GetStringData(string_id);
Brian Carlstroma0808032011-07-18 00:39:23 -07001225 String* new_string = Heap::AllocStringFromModifiedUtf8(java_lang_String_, char_array_class_, string_data);
Carl Shapiro5fafe2b2011-07-09 15:34:41 -07001226 // TODO: intern the new string
1227 referring->GetDexFile()->SetResolvedString(new_string, string_idx);
1228 return new_string;
1229}
1230
Carl Shapiro0e5d75d2011-07-06 18:28:37 -07001231} // namespace art